Destul de ciudat, există o diferență între aceste secvențe. În cele mai multe browsere, a doua opțiune este mai rapidă.
De ce este asta? Uneori se spune: "deoarece browserul revine la fiecare adăugare a unui element." Nu e așa. Nu este vorba despre redesenare.
Browserul este suficient de inteligent, astfel încât nimic nu poate fi repetat inutil. În majoritatea cazurilor, calculele de revopsire și calcul vor fi întârziate până când scriptul se termină și la acea dată este complet fără o diferență în ce secvență nodurile au fost schimbate.
Cu toate acestea, atunci când inserăm un nod, există diverse evenimente interne și actualizări ale structurilor de date interne ascunse din ochii noștri.
Ce se întâmplă exact depinde de implementarea specifică a browserului DOM, dar este nevoie de timp. Desigur, browserele evoluează și încearcă să reducă la minimum acțiunile inutile.
Pentru a verifica cu ușurință situația actuală - aici sunt două repere.
Ambele creați un tabel de 20x20, umplând TBODY cu elemente TR / TD.
În acest caz, primul introduce totul în documentul imediat, al doilea - întârzie inserarea TBODY în document până la sfârșitul procesului.
Faceți clic pentru a începe.
Codul pentru teste este localizat în fișierul insert-bench.js.
Continuăm să lucrăm cu introducerea nodurilor.
Luați în considerare cazul când documentul are deja o listă mare de UL-uri. Apoi a fost necesar să adăugăm urgent încă 20 de elemente LI.
Cum se face acest lucru?
Dacă noile elemente vin în formă de șir, puteți încerca să le adăugați astfel:
Dar ul.innerHTML + = "." Operația poate fi rescrisă într-un alt mod ca ul.innerHTML = ul.innerHTML + ".". Cu alte cuvinte, nu adaugă, ci înlocuiește întregul conținut al listei cu o linie augmentată. Acest lucru nu este bun în termeni de performanță, dar vor exista efecte secundare. În particular, toate resursele externe (imagini) din interiorHTML reinscriptibil vor fi încărcate din nou. Dacă în unele variabile există linkuri către elementele listate - acestea vor deveni incorecte, deoarece conținutul este complet înlocuit. În general, este mai bine să nu faceți acest lucru.
Și dacă doriți să inserați în mijlocul listei? Aici innerHTML nu ajută deloc.
Desigur, puteți introduce un rând într-un element DOM temporar și transfera elemente de acolo, dar există o opțiune mult mai bună: metoda insertAdjacentHTML!
Metoda insertAdjacentHTML vă permite să inserați HTML arbitrar oriunde în document, inclusiv între noduri!
Este susținută de toate browserele, cu excepția versiunii Firefox mai puțin versiunea 8, bine, pot fi emulate.
html Șirul HTML de inserat
în cazul în care: În ceea ce privește Elem pentru a insera un șir. Există doar patru opțiuni:
De exemplu, introduceți înainte elementele lipsă din listă
Singurul dezavantaj al acestei metode este că nu funcționează în Firefox înainte de versiunea 8. Dar poate fi adăugat cu ușurință utilizând polifilul insertAdjacentHTML pentru Firefox.
Această metodă are "frați gemeni", care sunt susținute oriunde, cu excepția Firefox, dar în ea sunt adăugate de același polifil:
- elem.insertAdjacentElement (unde, newElem) - inserează într-un loc arbitrar nu un șir HTML, ci un element newElem.
- elem.insertAdjacentText (unde, text) - creează un nod de text din șirul de text și îl inserează în locația specificată relativ la elem.
Sintaxa acestor metode, cu excepția ultimului parametru, este exact aceeași cu cea a insertAdjacentHTML. Împreună formează un "cuțit elvețian universal" pentru a introduce ceva de oriunde.
Important pentru browserele mai vechi
Optimizarea, la care se face referire aici, este importantă în primul rând pentru browserele mai vechi, inclusiv IE9-. În browserele moderne, efectul acesteia, de regulă, este mic și, uneori, poate fi negativ.
Înainte de aceasta, am vorbit despre introducerea unei linii în DOM. Și ce ar trebui să fac dacă trebuie să introduc multe elemente DOM în UL-ul existent?
Puteți să le inserați unul câte unul apelând insertBefore / appendChild. dar acest lucru va duce la multe operațiuni cu un document viu mare.
Introducerea unui pachet de noduri la un moment dat va ajuta DocumentFragment. Acesta este un obiect special DOM-cross-browser, care este similar cu un nod normal DOM, dar nu este.
Sintaxa pentru crearea acestuia este:
DocumentFragment nu are proprietățile obișnuite ale nodurilor DOM, cum ar fi innerHTML. tagName și altele asemenea. Acesta nu este un nod.
"Caracteristica" ei este că atunci când DocumentFragment este inserat în DOM, acesta dispare și copiii lui sunt inserați în loc. Această proprietate este o caracteristică unică a DocumentFragment.
De exemplu, dacă adăugați o mulțime de LI. și apoi apelați ul.appendChild (fragment). atunci fragmentul se va dizolva, iar DOM va insera exact LI. și în aceeași ordine în care erau în fragment.
În browserele moderne, efectul unei astfel de optimizări poate fi diferit, iar în cazul documentelor mici, uneori negativ.
Puteți înțelege starea actuală a lucrurilor prin rularea următorului indicator de referință.
Mai recent, standardul a introdus metode care vă permit să introduceți orice și oriunde.
- node.append (. nodes) - inserează noduri în nodul final,
- node.prepend (noduri) - introduce nodurile în nodul de început,
- node.after (.node) - inserează noduri după nodul nodului,
- node.before (.node) - inserează noduri înaintea nodului nodului,
- node.replaceWith (. nodes) - introduce noduri în loc de nod.
Aceste metode nu returnează nimic.
În toate aceste metode, nodurile sunt noduri DOM sau șiruri de caractere, în orice combinație și număr. Și liniile sunt inserate exact ca noduri de text, spre deosebire de insertAdjacentHTML.
Exemplu (cu polifil):
Manipulările care modifică structura unui DOM (inserarea, ștergerea elementelor) sunt de obicei mai rapide cu un nod mic separat decât cu un DOM mare care se află în document.
Diferența exactă depinde de implementarea internă a DOM în browser.
O familie de metode pentru inserarea în document a unui element HTML / element / text într-un loc arbitrar:
- elem.insertAdjacentHTML (unde, html)
- elem.insertAdjacentElement (unde, nodul)
- elem.insertAdjacentText (unde, text)
Ultimele două metode nu sunt acceptate în Firefox, la momentul redactării, dar există o mică inserție polyphyle insertAdjacentFF.js. care le adaugă. Desigur, este necesar doar pentru Firefox.
DocumentFragment vă permite să minimizați numărul de inserturi într-un DOM live mare. Această optimizare este deosebit de eficientă în browserele mai vechi, iar în cazul celor noi efectul este mai mic sau viceversa negativ.
Elementele sunt introduse mai întâi în ele și apoi - sunt inserate în DOM. Când inserați un DocumentFragment, acesta se "dizolvă", iar nodurile din acesta sunt inserate în loc.
DocumentFragment. spre deosebire de insertAdjacent *. funcționează cu o colecție de noduri DOM.
Metode moderne, de lucru cu orice număr de noduri și text, este de dorit polifill:
- append / prepend - inserați pentru a termina / începe.
- înainte / după inserarea înainte / după.
- înlocuiți - înlocuire.
Scrieți codul pentru a insera textul html la sfârșitul listei ul folosind metoda insertAdjacentHTML. Un astfel de insert, spre deosebire de alocarea innerHTML + =. Nu suprascrieți conținutul curent.
Adăugați elemente în listă
Rândurile din tabel sunt multe: poate 20, 50, 100 ... Există și alte elemente în document.
Cum se face munca de sortare cât mai repede posibil? Și dacă există 10 000 de rânduri în tabel (și câteodată este)?
P.S. Poate DocumentFragment ajuta aici?
Pentru sortare, funcția de sortare a matricei ne va ajuta.
Ideea generală se află pe suprafață: face o serie de rânduri și o sortează. Subtilitatea se află în detalii.
În cele de mai jos, este încărcat un document care descrie și implementează diferiți algoritmi. Rețineți: diferența de performanță poate atinge de mai multe ori!
P.S. Pentru a crea DocumentFragment aici la ce. Puteți să o scoateți din documentul TBODY și să o rezolvați izolat de DOM (Algoritmul 4).
P.P.S. Dacă trebuie să faceți mai multe noduri, atunci innerHTML funcționează de obicei mai rapid decât ștergerea și inserarea elementelor prin intermediul apelurilor DOM. Adică masa este regenerată mai eficient.