ÐбÑÑнÑе меÑÐ¾Ð´Ñ Ð²ÑÑавки ÑабоÑаÑÑ Ñ Ð¾Ð´Ð½Ð¸Ð¼ Ñзлом. Ðо еÑÑÑ Ð¸ ÑпоÑÐ¾Ð±Ñ Ð²ÑÑавлÑÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво Ñзлов одновÑеменно.
ÐпÑимизаÑÐ¸Ñ Ð²ÑÑавки в докÑменÑ
РаÑÑмоÑÑим задаÑÑ: ÑгенеÑиÑоваÑÑ ÑпиÑок UL/LI.
ÐÑÑÑ Ð´Ð²Ðµ возможнÑÑ Ð¿Ð¾ÑледоваÑелÑноÑÑи:
-
СнаÑала вÑÑавиÑÑ
ULв докÑменÑ, а поÑом добавиÑÑ Ðº немÑLI:var ul = document.createElement('ul'); document.body.appendChild(ul); // ÑнаÑала в докÑÐ¼ÐµÐ½Ñ for (...) ul.appendChild(li); // поÑом ÑÐ·Ð»Ñ -
ÐолноÑÑÑÑ ÑоздаÑÑ ÑпиÑок «вне DOM», а поÑом â вÑÑавиÑÑ Ð² докÑменÑ:
var ul = document.createElement('ul'); for(...) ul.appendChild(li); // ÑнаÑала вÑÑавиÑÑ ÑÐ·Ð»Ñ document.body.appendChild(ul); // заÑем в докÑменÑ
Ðак ни ÑÑÑанно, Ð¼ÐµÐ¶Ð´Ñ ÑÑими поÑледоваÑелÑноÑÑÑми еÑÑÑ ÑазниÑа. РболÑÑинÑÑве бÑаÑзеÑов, вÑоÑой ваÑÐ¸Ð°Ð½Ñ â бÑÑÑÑее.
ÐоÑÐµÐ¼Ñ Ð¶Ðµ? Ðногда говоÑÑÑ: «поÑÐ¾Ð¼Ñ ÑÑо бÑаÑÐ·ÐµÑ Ð¿ÐµÑеÑиÑовÑÐ²Ð°ÐµÑ ÐºÐ°Ð¶Ð´Ñй Ñаз пÑи добавлении ÑлеменÑа». ÐÑо не Ñак. Ðело вовÑе не в пеÑеÑиÑовке.
ÐÑаÑÐ·ÐµÑ Ð´Ð¾ÑÑаÑоÑно «ÑмÑн», ÑÑÐ¾Ð±Ñ Ð½Ð¸Ñего не пеÑеÑиÑовÑваÑÑ Ð¿Ð¾Ð½Ð°Ð¿ÑаÑнÑ. РболÑÑинÑÑве ÑлÑÑаев пÑоÑеÑÑÑ Ð¿ÐµÑеÑиÑовки и ÑопÑÑÑÑвÑÑÑие вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð±ÑдÑÑ Ð¾ÑÐ»Ð¾Ð¶ÐµÐ½Ñ Ð´Ð¾ оконÑÐ°Ð½Ð¸Ñ ÑабоÑÑ ÑкÑипÑа, и на ÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ Ñже ÑовеÑÑенно без ÑазниÑÑ, в какой поÑледоваÑелÑноÑÑи бÑли Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ ÑзлÑ.
Тем не менее, пÑи вÑÑавке Ñзла пÑоиÑÑ Ð¾Ð´ÑÑ ÑазнÑе внÑÑÑенние ÑобÑÑÐ¸Ñ Ð¸ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ ÑÑÑÑкÑÑÑ Ð´Ð°Ð½Ð½ÑÑ , ÑкÑÑÑÑе Ð¾Ñ Ð½Ð°ÑÐ¸Ñ Ð³Ð»Ð°Ð·.
ЧÑо именно пÑоиÑÑ Ð¾Ð´Ð¸Ñ â завиÑÐ¸Ñ Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑной, внÑÑÑенней бÑаÑзеÑной ÑеализаÑии DOM, но ÑÑо оÑÐ½Ð¸Ð¼Ð°ÐµÑ Ð²ÑемÑ. ÐонеÑно, бÑаÑзеÑÑ ÑазвиваÑÑÑÑ Ð¸ ÑÑаÑаÑÑÑÑ ÑвеÑÑи лиÑние дейÑÑÐ²Ð¸Ñ Ðº минимÑмÑ.
ÐенÑмаÑк
ЧÑÐ¾Ð±Ñ Ð»ÐµÐ³ÐºÐ¾ пÑовеÑиÑÑ ÑекÑÑее ÑоÑÑоÑние дел â Ð²Ð¾Ñ Ð´Ð²Ð° бенÑмаÑка.
Ðба они ÑоздаÑÑ ÑаблиÑÑ 20x20, наполнÑÑ TBODY ÑлеменÑами TR/TD.
ÐÑи ÑÑом пеÑвÑй вÑÑавлÑÐµÑ Ð²Ñе в докÑÐ¼ÐµÐ½Ñ ÑÑÑ Ð¶Ðµ, вÑоÑой â задеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð²ÑÑÐ°Ð²ÐºÑ TBODY в докÑÐ¼ÐµÐ½Ñ Ð´Ð¾ конÑа пÑоÑеÑÑа.
ÐликниÑе, ÑÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑÑÑиÑÑ.
Ðод Ð´Ð»Ñ ÑеÑÑов Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² Ñайле insert-bench.js.
Ðобавление множеÑÑва Ñзлов
ÐÑодолжим ÑабоÑаÑÑ Ñо вÑÑавкой Ñзлов.
РаÑÑмоÑÑим ÑлÑÑай, когда в докÑменÑе Ñже еÑÑÑ Ð±Ð¾Ð»ÑÑой ÑпиÑок UL. Ð ÑÑÑ Ð¿Ð¾Ð½Ð°Ð´Ð¾Ð±Ð¸Ð»Ð¾ÑÑ ÑÑоÑно добавиÑÑ ÐµÑÑ 20 ÑлеменÑов LI.
Ðак ÑÑо ÑделаÑÑ?
ÐÑли новÑе ÑлеменÑÑ Ð¿ÑиÑли в виде ÑÑÑоки, Ñо можно попÑобоваÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð¸Ñ Ñак:
ul.innerHTML += "<li>1</li><li>2</li>...";
Ðо опеÑаÑÐ¸Ñ ul.innerHTML += "..." можно по-дÑÑÐ³Ð¾Ð¼Ñ Ð¿ÐµÑепиÑаÑÑ ÐºÐ°Ðº ul.innerHTML = ul.innerHTML + "...". ÐнаÑе говоÑÑ, она не пÑибавлÑеÑ, а заменÑÐµÑ Ð²ÑÑ ÑодеÑжимое ÑпиÑка на дополненнÑÑ ÑÑÑокÑ. ÐÑо и неÑ
оÑоÑо Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи, но и бÑдÑÑ Ð¿Ð¾Ð±Ð¾ÑнÑе ÑÑÑекÑÑ. Ð ÑаÑÑноÑÑи, вÑе внеÑние ÑеÑÑÑÑÑ (каÑÑинки) внÑÑÑи пеÑезапиÑÑваемого innerHTML бÑдÑÑ Ð·Ð°Ð³ÑÑÐ¶ÐµÐ½Ñ Ð·Ð°Ð½Ð¾Ð²Ð¾. ÐÑли в какиÑ
-Ñо пеÑеменнÑÑ
бÑли ÑÑÑлки на ÑлеменÑÑ ÑпиÑка â они ÑÑанÑÑ Ð½ÐµÐ²ÐµÑнÑ, Ñак как ÑодеÑжимое полноÑÑÑÑ Ð·Ð°Ð¼ÐµÐ½ÑеÑÑÑ. РобÑем, Ñак лÑÑÑе не делаÑÑ.
РеÑли нÑжно вÑÑавиÑÑ Ð² ÑеÑÐµÐ´Ð¸Ð½Ñ ÑпиÑка? ÐдеÑÑ innerHTML вообÑе не поможеÑ.
Ðожно, конеÑно, вÑÑавиÑÑ ÑÑÑÐ¾ÐºÑ Ð²Ð¾ вÑеменнÑй DOM-ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸ пеÑенеÑÑи оÑÑÑда ÑлеменÑÑ, но еÑÑÑ Ð¸ гоÑаздо лÑÑÑий ваÑианÑ: меÑод insertAdjacentHTML!
insertAdjacent*
ÐеÑод insertAdjacentHTML позволÑÐµÑ Ð²ÑÑавлÑÑÑ Ð¿ÑоизволÑнÑй HTML в лÑбое меÑÑо докÑменÑа, в Ñом ÑиÑле и Ð¼ÐµÐ¶Ð´Ñ Ñзлами!
СинÑакÑиÑ:
elem.insertAdjacentHTML(where, html);
html-
СÑÑока HTML, коÑоÑÑÑ Ð½Ñжно вÑÑавиÑÑ
where-
ÐÑда по оÑноÑÐµÐ½Ð¸Ñ Ðº
elemвÑÑавлÑÑÑ ÑÑÑокÑ. ÐÑего ÑеÑÑÑе ваÑианÑа:beforeBeginâ пеÑедelem.afterBeginâ внÑÑÑÑelem, в Ñамое наÑало.beforeEndâ внÑÑÑÑelem, в конеÑ.afterEndâ поÑлеelem.
ÐапÑимеÑ, вÑÑавим пÑопÑÑеннÑе ÑлеменÑÑ ÑпиÑка пеÑед <li>5</li>:
<ul>
<li>1</li>
<li>2</li>
<li>5</li>
</ul>
<script>
var ul = document.body.children[0];
var li5 = ul.children[2];
li5.insertAdjacentHTML("beforeBegin", "<li>3</li><li>4</li>");
</script>
У ÑÑого меÑода еÑÑÑ Â«Ð±Ð»Ð¸Ð·Ð½ÐµÑÑ-бÑаÑÑÑ»:
- elem.insertAdjacentElement(where, newElem) â вÑÑавлÑÐµÑ Ð² пÑоизволÑное меÑÑо не ÑÑÑÐ¾ÐºÑ HTML, а ÑлеменÑ
newElem. - elem.insertAdjacentText(where, text) â ÑоздаÑÑ ÑекÑÑовÑй Ñзел из ÑÑÑоки
textи вÑÑавлÑÐµÑ ÐµÐ³Ð¾ в Ñказанное меÑÑо оÑноÑиÑелÑноelem.
СинÑакÑÐ¸Ñ ÑÑиÑ
меÑодов, за иÑклÑÑением поÑледнего паÑамеÑÑа, полноÑÑÑÑ ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ Ñ insertAdjacentHTML. ÐмеÑÑе они обÑазÑÑÑ Â«ÑнивеÑÑалÑнÑй ÑвейÑаÑÑкий нож» Ð´Ð»Ñ Ð²ÑÑавки Ñего Ñгодно кÑда Ñгодно.
DocumentFragment
ÐпÑимизаÑиÑ, о коÑоÑой здеÑÑ Ð¸Ð´ÑÑ ÑеÑÑ, важна в пеÑвÑÑ Ð¾ÑеÑÐµÐ´Ñ Ð´Ð»Ñ ÑÑаÑÑÑ Ð±ÑаÑзеÑов, вклÑÑÐ°Ñ IE9-. Ð ÑовÑеменнÑÑ Ð±ÑаÑзеÑÐ°Ñ ÑÑÑÐµÐºÑ Ð¾Ñ Ð½ÐµÑ, как пÑавило, неболÑÑой, а иногда Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ оÑÑиÑаÑелÑнÑм.
Ðо ÑÑого Ð¼Ñ Ð³Ð¾Ð²Ð¾Ñили о вÑÑавке ÑÑÑоки в DOM. Ð ÑÑо делаÑÑ Ð² ÑлÑÑае, когда надо в ÑÑÑеÑÑвÑÑÑий UL вÑÑавиÑÑ Ð¼Ð½Ð¾Ð³Ð¾ DOM-ÑлеменÑов?
Ðожно вÑÑавлÑÑÑ Ð¸Ñ
один за дÑÑгим, вÑзовом insertBefore/appendChild, но пÑи ÑÑом полÑÑиÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ опеÑаÑий Ñ Ð±Ð¾Ð»ÑÑим живÑм докÑменÑом.
ÐÑÑавиÑÑ Ð¿Ð°ÑÐºÑ Ñзлов единовÑеменно Ð¿Ð¾Ð¼Ð¾Ð¶ÐµÑ DocumentFragment. ÐÑо оÑобеннÑй кÑоÑÑ-бÑаÑзеÑнÑй DOM-обÑекÑ, коÑоÑÑй поÑ
ож на обÑÑнÑй DOM-Ñзел, но им не ÑвлÑеÑÑÑ.
СинÑакÑÐ¸Ñ Ð´Ð»Ñ ÐµÐ³Ð¾ ÑозданиÑ:
var fragment = document.createDocumentFragment();
Рнего можно добавлÑÑÑ Ð´ÑÑгие ÑзлÑ.
fragment.appendChild(node);
Ðго можно клониÑоваÑÑ:
fragment.cloneNode(true); // клониÑование Ñ Ð¿Ð¾Ð´ÑлеменÑами
У DocumentFragment Ð½ÐµÑ Ð¾Ð±ÑÑнÑÑ
ÑвойÑÑв DOM-Ñзлов, ÑакиÑ
как innerHTML, tagName и Ñ.п. ÐÑо не Ñзел.
Ðго «ФиÑка» заклÑÑаеÑÑÑ Ð² Ñом, ÑÑо когда DocumentFragment вÑÑавлÑеÑÑÑ Ð² DOM â Ñо он иÑÑезаеÑ, а вмеÑÑо него вÑÑавлÑÑÑÑÑ ÐµÐ³Ð¾ деÑи. ÐÑо ÑвойÑÑво ÑвлÑеÑÑÑ ÑникалÑной оÑобенноÑÑÑÑ DocumentFragment.
ÐапÑимеÑ, еÑли добавиÑÑ Ð² него много LI, и поÑом вÑзваÑÑ ul.appendChild(fragment), Ñо ÑÑÐ°Ð³Ð¼ÐµÐ½Ñ ÑаÑÑвоÑиÑÑÑ, и в DOM вÑÑавÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ LI, пÑиÑÑм в Ñом же поÑÑдке, в коÑоÑом бÑли во ÑÑагменÑе.
ÐÑевдокод:
// Ñ
оÑим вÑÑавиÑÑ Ð² ÑпиÑок UL много LI
// делаем вÑпомогаÑелÑнÑй DocumentFragment
var fragment = document.createDocumentFragment();
for (Ñикл по li) {
fragment.appendChild(list[i]); // вÑÑавиÑÑ ÐºÐ°Ð¶Ð´Ñй LI в DocumentFragment
}
ul.appendChild(fragment); // вмеÑÑо ÑÑагменÑа вÑÑавÑÑÑÑ ÑлеменÑÑ ÑпиÑка
Ð ÑовÑеменнÑÑ Ð±ÑаÑзеÑÐ°Ñ ÑÑÑÐµÐºÑ Ð¾Ñ Ñакой опÑимизаÑии Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑазлиÑнÑм, а на неболÑÑÐ¸Ñ Ð´Ð¾ÐºÑменÑÐ°Ñ Ð¸Ð½Ð¾Ð³Ð´Ð° и оÑÑиÑаÑелÑнÑм.
ÐонÑÑÑ ÑекÑÑее положение веÑей Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе, запÑÑÑив ÑледÑÑÑий неболÑÑой бенÑмаÑк.
append/prepend, before/after, replaceWith
СÑавниÑелÑно недавно в ÑÑандаÑÑе поÑвилиÑÑ Ð¼ÐµÑодÑ, коÑоÑÑе позволÑÑÑ Ð²ÑÑавиÑÑ ÑÑо Ñгодно и кÑда Ñгодно.
СинÑакÑиÑ:
node.append(...nodes)â вÑÑавлÑеÑnodesв конеÑnode,node.prepend(...nodes)â вÑÑавлÑеÑnodesв наÑалоnode,node.after(...nodes)â вÑÑавлÑеÑnodesпоÑле Ñзлаnode,node.before(...nodes)â вÑÑавлÑеÑnodesпеÑед Ñзломnode,node.replaceWith(...nodes)â вÑÑавлÑеÑnodesвмеÑÑоnode.
ÐÑи меÑÐ¾Ð´Ñ Ð½Ð¸Ñего не возвÑаÑаÑÑ.
Ðо вÑеÑ
ÑÑиÑ
меÑодаÑ
nodes â DOM-ÑÐ·Ð»Ñ Ð¸Ð»Ð¸ ÑÑÑоки, в лÑбом ÑоÑеÑании и колиÑеÑÑве. ÐÑиÑÑм ÑÑÑоки вÑÑавлÑÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ как ÑекÑÑовÑе ÑзлÑ, в оÑлиÑие Ð¾Ñ insertAdjacentHTML.
ÐÑÐ¸Ð¼ÐµÑ (Ñ Ð¿Ð¾Ð»Ð¸Ñилом):
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.polyfill.io/v1/polyfill.js?features=Element.prototype.append,Element.prototype.after"></script>
</head>
<body>
<script>
// добавим ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² ÐºÐ¾Ð½ÐµÑ <body>
var p = document.createElement('p');
document.body.append(p);
var em = document.createElement('em');
em.append('ÐиÑ!');
// вÑÑавиÑÑ Ð² паÑагÑÐ°Ñ ÑекÑÑовÑй и обÑÑнÑй ÑзлÑ
p.append("ÐÑивеÑ, ", em);
// добавиÑÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾Ñле <p>
p.after(document.createElement('hr'))
</script>
</body>
</html>
ÐÑого
-
ÐанипÑлÑÑии, менÑÑÑие ÑÑÑÑкÑÑÑÑ DOM (вÑÑавка, Ñдаление ÑлеменÑов), как пÑавило, бÑÑÑÑее Ñ Ð¾ÑделÑнÑм маленÑким Ñзлом, Ñем Ñ Ð±Ð¾Ð»ÑÑим DOM, коÑоÑÑй Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² докÑменÑе.
ÐонкÑеÑÐ½Ð°Ñ ÑазниÑа завиÑÐ¸Ñ Ð¾Ñ Ð²Ð½ÑÑÑенней ÑеализаÑии DOM в бÑаÑзеÑе.
-
СемейÑÑво меÑодов Ð´Ð»Ñ Ð²ÑÑавки HTML/ÑлеменÑа/ÑекÑÑа в пÑоизволÑное меÑÑо докÑменÑа:
elem.insertAdjacentHTML(where, html)elem.insertAdjacentElement(where, element)elem.insertAdjacentText(where, text)
-
DocumentFragmentпозволÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð¸ÑоваÑÑ ÐºÐ¾Ð»Ð¸ÑеÑÑво вÑÑавок в болÑÑой живой DOM. ÐÑа опÑимизаÑÐ¸Ñ Ð¾Ñобо ÑÑÑекÑивна в ÑÑаÑÑÑ Ð±ÑаÑзеÑÐ°Ñ , в новÑÑ ÑÑÑÐµÐºÑ Ð¾Ñ Ð½ÐµÑ Ð¼ÐµÐ½ÑÑе или наобоÑÐ¾Ñ Ð¾ÑÑиÑаÑелÑнÑй.ÐлеменÑÑ ÑнаÑала вÑÑавлÑÑÑÑÑ Ð² него, а поÑом â он вÑÑавлÑеÑÑÑ Ð² DOM. ÐÑи вÑÑавке
DocumentFragment«ÑаÑÑвоÑÑеÑÑÑ», и вмеÑÑо него вÑÑавлÑÑÑÑÑ ÑодеÑжаÑиеÑÑ Ð² нÑм ÑзлÑ.DocumentFragment, в оÑлиÑие оÑinsertAdjacent*, ÑабоÑÐ°ÐµÑ Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑией DOM-Ñзлов. -
СовÑеменнÑе меÑодÑ, ÑабоÑаÑÑ Ñ Ð»ÑбÑм колиÑеÑÑвом Ñзлов и ÑекÑÑа, желаÑелен полиÑил:
append/prependâ вÑÑавка в конеÑ/наÑало.before/afterâ вÑÑавка пеÑед/поÑле.replaceWithâ замена.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)