вторник, 24 декабря 2013 г.

Что мне стоит DOM построить

У любого javascript-программиста время от времени возникает потребность вставить фрагмент разметки на страницу. Для больших фрагментов используются шаблонизаторы. А что если необходимо много раз вставлять маленькие кусочки? В plain js легко и элегантно этого не сделать. Решение в лоб — использовать innerHTML. Но это ужасное решение! Меня просто воротит когда я вижу это в коде подобное:

el.innerHTML = "<div id='main'>"+hello+"world!</div>";




Другое решение предложила Mozilla — библиотеку html2dom для генерации html путём построения цепочечных вызовов из строки разметки. Это решение достаточно не плохое, однако не решает главную задачу — необходимость просто и понятно описать разметку.

В конце концов я решил написать собственную библиотеку которая решает все нужные задачи — быстрая и безопасная генерация DOM из шаблона с тёплым ламповым синтаксисом.



Библиотека носит название SNC — Simple Node Creator. Она не манипулирует строкой разметки (innerHTML в частности), а имеет свой весьма простой, понятный и во многом знакомый синтаксис. На вход она принимает строку — шаблон, на выходе вполне себе готовый DocumentFragment.


В основе библиотеки лежит лексический анализатор. Вначале весь шаблон разбивается на массив токенов. При этом для токена-разделителя будет сохраняться его символьный код. Это позволит во время перебора массива однозначно его идентифицировать — по типу. В конце мы проходим по этой последовательности токенов и собираем документ.


Синтаксис



Любое описание узла начинается с его имени. Именем должно служить название html тэга. Затем уже мы декораторами добавляем различные сущности к элементу.

.class — добавить класс.

#id — добавить идентификатор.

[...] — позволяет задавать вложенные узлы: div.parent[ span.child ]

; — разделитель узлов на одном уровне: ul.menu[ li#home; li#abount ]

:attr — пустой атрибут.

:attr@value или :attr=value — один из вариантов передачи значения атрибута. В этом случае на значение накладываются ограничения — он не должен содержать управляющих символов #.[]:%@. Если имя атрибута начинается с «on», то будет добавлен обработчик события, имя обработчика будет значение value, а тело из второго аргумента. Обработчик будет добавлен стандартными средствами, динамически. А если имя начинается с «jq», то будет навешено jQuery-событие. Имя обработчика можно задать двояко — :onclick@handler и :onclick@%handler — оба эти способа несут один и тот же смысл.

%variable — универсальный способ задания переменных, а также способ передать текстовые данные (html entities передаются корректно). Вы можете написать #%id и тогда имя атрибута будет взято из второго параметра — карты значений. Это простой объект, где каждому ключу соответствует имя в шаблоне. С недавнего времени он может быть и массивом, значения в этом случае берутся последовательно, по мере обработки шаблона. Такие переменные поддерживаются для всех основных элементов — идентификаторов, классов, атрибутов и их значений.

Существует ещё и третий параметр — он отвечает за то, чтобы не генерировалось исключение, если вы вдруг забыли указать значение переменной. Использовать его не рекомендую. В этом случае вместо пропущенных значений будет подставлено «undefined».


Использование



Вызывайте функцию SNC, которой передавайте необходимые параметры.

Несколько примеров шаблонов было показано выше. Вот ещё один большой пример:

SNC("div #parent [" +
"i.icon-open;" +
"span.child%txt" +
"] :data-status@%status" +
":onclick@handler" +
":jqcustomevent=jhandler", {
txt:"lorem ipsum",
status:1,
handler:function(e){ console.log("Standart event"); },
jhandler:function(){ console.log("Custom event"); }
});




Планы



Следующим пунктом развития будет добавление циклов. Синтаксис я подсмотрел у Emmet. Будет нечто вроде такого:

SNC("table [ {tr [ { td } * 2 ]} * 8 ]");




Также необходимо перевести readme на английский. Но тут я надеюсь на помощь сообщества.

Реп: github.com/ReklatsMasters/SNC


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.


Комментариев нет:

Отправить комментарий