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! :
За Здравейте! , кодът ще стане
Здравейте! |
Следва последваща обработка на резултата за някои случаи в IE - изтриване на автоматично вмъкнато tbody в таблици и добавяне на автоматично изтрити интервали към интервали в началото на нашия код.
Това е всичко, ура, можем да получим нашия резултат от контейнера с помощта на стандартната функция childNodes и да го премахнем от safeFrag.
Нека итерираме получения набор от възли и да ги добавим към нашия собствен фрагмент, който ще влезе в кеша (ако може да се кешира, вижте по-горе) и ще ни го върне обратно в parseHTML, yohoo! Там полученият клониран фрагмент се обединява в нашия резултат (ако е получен от кеша) или самия него.
всичко ли е
Да всички. Обаче чистият метод, който анализирахме, всъщност е малко по-сложен (методът се използва на няколко места в jQuery вътрешно) и аз умишлено просто не взех под внимание неговата функционалност, която не се използва в нашия случай, за създаване на елементи от обикновен низ, но е предназначена за напълно различни цели. Например, в последната стъпка всички създадени елементи се проверяват за наличието на етикета, в нашия случай това няма значение. За какво? Ще разберем в следващия епизод.
Заключение
Мислехте, че всичко е просто? За съжаление не. Но успяхме! Между другото, докато пишех статия и ровех в изходния код,намерих и нещо ново :)
Напишете красив код и се забавлявайте, момчета и момичета.