jQuery отвътре

Продължаваме работата по първата статия и се опитваме да разберем какво прави jQuery за нас, когато създаваме DOM елементи, използвайки тази библиотека.

В миналия брой споменахме, че когато подадете html низ към jQuery вместо селектор, функцията parseHTML ще генерира подходящите елементи въз основа на него и ще ги върне в познатия jQuery обект. Сега ще разгледаме всичко това по-подробно и освен core.js ще се докоснем и до manipulation.js и attributes.js (за един поглед).

Да започнем просто

jQuery определя, че вместо селектор, html низ се предава от първия и последния знак (знаците по-малко от и по-голямо от, които отварят и затварят етикета) или, ако първата проверка е неуспешна, от специалния регулярен израз /^(?:[^# )[^>]*$#([\w\-]*)$)/ .

ПРЕДУПРЕЖДЕНИЕ: като се започне от версия 1.9, проверката ще се състои само от гледане на първия знак на низа, той трябва да е знак по-малко от. Поне така пишат в блога. В този случай низът "testlalala" вече няма да се възприема като html, който след това jQuery ще се опита да анализира, бъдете внимателни.

Първо, той ще провери дали прост единичен таг е предаден като низ без никакво съдържание, в който случай той ще бъде създаден просто чрез context.createElement( [tagName] ), изпълнението на всеки от тези низове ще доведе до същия резултат доста бързо:

В същия случай с един таг, ако сме предали обект вместо контекст, jQuery.attr ще бъде приложен към резултата, който ще се опита да добави атрибутите, посочени в този обект, към конструирания таг. Надявам се, че ще говорим за това в някоя от следващите части.

Нека да преминем към по-сложни

В други случаи jQuery ще произведе много повечевсяка работа, която ще симпатизираме на старите бавни браузъри предварително, кажете на core.js "хайде, довиждане!" и погледнете buildFragment от manipulation.js, там започва да се случва магията. Накратко, ще бъде създаден фрагмент, получените DOM елементи ще бъдат бавно поставени в него, които след това ще дойдат от него в резултата.

кеширане

На първо място, за посочения html код ще се установи дали е възможно и необходимо да се кешира резултатът от неговото формиране. Може да се кешира, ако е изграден в контекста на документ, оригиналният html е с дължина по-малка от 512 знака, не съдържа маркери script, object, embed, option или style и преминава няколко теста, специфични за браузъра (например в относително остарял Webkit, клонирането на фрагмент с възел, който има зададения атрибут checked, няма да работи, като запази стойността си). Резултатите, които могат да бъдат кеширани, първо се маркират в обекта fragments и когато се опитате да създадете нещо, използвайки същия html втори път, самият резултат ще отиде там.

Реален пример за създаване на въображаеми хеш зарове с трима въображаеми потребители:

Кодът е грозен и в никакъв случай не трябва да се пише така. Въпреки това, периодично виждам този код от разработчици и в резултат на популярността на javascript шаблонните машини, той става все повече и повече. Какво ще завърши в jQuery.fragments:

Три обхвата, три елемента в обекта jQuery.fragments. false като стойност - точно това, за което говорех, първият път влизат само в обекта, вторият път - вместо false, ще бъде там самият резултат. Множество записи - глупав въпрос, разбира се. Но тонове записи - празна загуба на памет и не е добре.

Можете да опитате да напишете нещо в най-тъжното търсене на Habré и ​​след това да погледнете боклука в конзолата вjQuery.фрагменти. В този случай боклукът, разбира се, не е критичен, но, разбирате ли, можете да го направите без него.

отвътре

И ето един малко по-различен код, по-красив, макар и малко по-бавен. Потребителят ще види същия резултат на екрана: (добавянето на куп DOM елементи към страницата в цикъл не е добре и е по-добре да пропуснете този въпрос чрез допълнителен фрагмент, благодаря за принудителната бележка, дори не обърнах внимание, за съжаление)

jQuery.fragments просто ще бъде празен в този случай, защото за обикновен таг ще бъде извикан document.createElement('span'), идентификаторът и заглавието ще бъдат окачени върху него и текстът ще бъде хвърлен вътре.

По никакъв начин не препоръчвам да се пише само такъв код, в резултат на което нищо не попада в кеша на jQuery.fragments, само ви призовавам да го използвате по предназначение - да съхранявате части от код, които наистина често ще се изпълняват. В случая с примера по-горе, тези span със сигурност ще имат някакъв клас, например "user", така че е доста разумно да създадете такива зарове чрез $('') и след това да закачите нещо върху тях. Намерете баланс.

Така че кешираният фрагмент ще се върне веднага. Ако няма резултат в кеша, ще бъде създаден лек DocumentFragment и вниманието ни ще бъде превключено към функцията clean, в която ще бъдат хвърлени прясно създадения фрагмент и нашия html код.

safeFragment

Всички временни действия със създаването на елементи се извършват в специален фрагмент на резервоара, safeFragment, който се създава по време на инициализацията. Освен това в IE той също е допълнително обработен, за да поддържа html5 тагове (вижте грешката, много интересно).

Създаване на елементи

Създава се празен елемент в safeFragment, в който jQuery записва нашия html код, използвайки стандартния innerHTML метод

Но първо jQuery се опитва да разбере дали трябва да рамкираме кода си по някакъв начин допълнително. Първият етикет, намерен в кода, се взема и търси в обекта на помощната програма wrapMap. Защо изобщо да рамкирате нещо? След това, че не можете просто да го вземете и да го поставите във вътрешния HTML на, например, Hello! :

За Здравейте! , кодът ще стане

Здравейте!
, а указателят към контейнера с необходимия ни резултат ще бъде изместен на дълбочина от 3 тагове, т.е. вместо , който беше създаден в safeFrag в самото начало.

Следва последваща обработка на резултата за някои случаи в IE - изтриване на автоматично вмъкнато tbody в таблици и добавяне на автоматично изтрити интервали към интервали в началото на нашия код.

Това е всичко, ура, можем да получим нашия резултат от контейнера с помощта на стандартната функция childNodes и да го премахнем от safeFrag.

Нека итерираме получения набор от възли и да ги добавим към нашия собствен фрагмент, който ще влезе в кеша (ако може да се кешира, вижте по-горе) и ще ни го върне обратно в parseHTML, yohoo! Там полученият клониран фрагмент се обединява в нашия резултат (ако е получен от кеша) или самия него.

всичко ли е

Да всички. Обаче чистият метод, който анализирахме, всъщност е малко по-сложен (методът се използва на няколко места в jQuery вътрешно) и аз умишлено просто не взех под внимание неговата функционалност, която не се използва в нашия случай, за създаване на елементи от обикновен низ, но е предназначена за напълно различни цели. Например, в последната стъпка всички създадени елементи се проверяват за наличието на етикета, в нашия случай това няма значение. За какво? Ще разберем в следващия епизод.

Заключение

Мислехте, че всичко е просто? За съжаление не. Но успяхме! Между другото, докато пишех статия и ровех в изходния код,намерих и нещо ново :)

Напишете красив код и се забавлявайте, момчета и момичета.