Построить элемент DOM

Для веб-разработчиков различные библиотеки и фреймворки основные инструменты без которых создать проект довольно сложно. При разработке проекта такие инструменты экономят много времени и избавляют от лишнего труда (заново изобретать велосипед). В этой статье мы раскроем некоторые магические процессы, происходящие в jQuery.

Построить элемент DOM

На одной HTML странице с помощью JavaScript можно много чего сделать. Что бы увидеть скрипты в действии создайте страницу и в заголовок подключите библиотеку jQuery вот так:



<script src=
http://pixelcom.crimea.ua/"http://yandex.st/jquery/2.0.2/jquery.min.js"></script>


Самый распространенный код.



var text = $('<div>Привет мир!</div>');

 $('body').append(text);


В результате содержимое и сам элемент <div> добавляется в тело документа HTML. Этому простому процессу требуется всего лишь одна строка из библиотеки jQuery. Без jQuery код немного сложнее, но не намного:



var stringToDom = function(str) {
 var temp = document.createElement('div');

 temp.innerHTML = str;
 return temp.childNodes[0];
}
var text = stringToDom('<div>Привет мир!</div>');

document.querySelector('body').appendChild(text);


Здесь мы написали свой метод stringToDom который создаёт элемент <div> . Мы изменили его свойством innerHTML и вернули дочерний элемент в тело документа.

Этот код покажет нам разные результаты:



var tableRow = $('<tr><td>Привет мир!</td></tr>');
$('body').append(tableRow);

var tableRow = stringToDom('<tr><td>Привет мир!</td></tr>');
 document.querySelector('body').appendChild(tableRow);


Визуально, на странице нет никаких различий. Но, если проверить разметку HTML с помощью Firebug, мы получим интересный результат:



<tr>
    <td>Привет мир!</td>
</tr>



Похоже что метод stringToDom предназначен только для вывода текста, а не для показа разметки HTML тегов <tr> . Но, jQuery может отобразить теги HTML в браузере. Дело в том, что строка, содержит элементы HTML для браузера, где анализатор синтаксиса игнорирует теги HTML, которые не размещаются в нужном контексте, поэтому мы видим только текст. И еще, строки таблицы без столбцов не является допустимым для браузера.

Парсинг HTML

jQuery успешно решает задачи по созданию правильного контекста. Если в jQuery копнуть немного глубже мы увидим карту, похожую на эту:



var wrapMap = {
 option: [1, '<select multiple="multiple">', '</select>'],
 legend: [1, '<fieldset>', '</fieldset>'],
 area: [1, '<map>', '</map>'],
 param: [1, '<object>', '</object>'],
 thead: [1, '<table>', '</table>'],
 tr: [2, '<table><tbody>', '</tbody></table>'],
 col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
 td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
 _default: [1, '<div>', '</div>']
  };
  wrapMap.optgroup = wrapMap.option;
  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  wrapMap.th = wrapMap.td;


Каждый элемент, который требует специального обращения имеет множество назначенный. Идея состоит в том, чтобы построить правильный элемент DOM зависящий от уровня вложенности, чтобы извлечь то, что нам нужно. Например, для элемента <tr> нам необходимо создать таблицу с дочерним элементом <tbody> . Значит мы имеем два уровня вложенности.

Имея карту, мы должны выяснить, какой именно тег нам нужен. Следующий код получает tr из <tr><td>Привет мир!</td></tr>



var match = /&lt;\s*\w.*?&gt;/g.exec(str);
var tag = match[0].replace(/&lt;/g, '').replace(/&gt;/g, '');


Остальное чтобы найти необходимый контекст и вернуть элемент DOM .

Вот окончательный вариант функции stringToDom :



<script>var stringToDom = function(str) {
   var wrapMap = {
        option: [ 1, "<select multiple='multiple'>", "</select>" ],
        legend: [ 1, "<fieldset>", "</fieldset>" ],
        area: [ 1, "<map>", "</map>" ],
        param: [ 1, "<object>", "</object>" ],
        thead: [ 1, "<table>", "</table>" ],
        tr: [ 2, "<table><tbody>", "</tbody></table>" ],
        col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
        td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
        _default: [ 1, "<div>", "</div>"  ]
    };
    wrapMap.optgroup = wrapMap.option;
    wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    wrapMap.th = wrapMap.td;
    var element = document.createElement('div');
    var match = /<\s*\w.*?>/g.exec(str);
    if(match != null) {
        var tag = match[0].replace(/</g, '').replace(/>/g, '');
        var map = wrapMap[tag] || wrapMap._default, element;
        str = map[1] + str + map[2];
        element.innerHTML = str;
        // Спуск через оболочки для правильного Контента
        var j = map[0]+1;
        while(j--) {
            element = element.lastChild;
        }
    } else {
        // только для текста
        element.innerHTML = str;
        element = element.lastChild;
    }
    return element;
}
var text = stringToDom('<table><tbody><tr><td>Привет мир!</td></tr></tbody></table>');
document.querySelector('body').innerHTML = text.outerHTML.replace(/</g, '&lt;');</script>


Обратите внимание, что мы проверяем наличие тегов в строке match != null . Теги будут отображаться в браузере если они в DOM’е…

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML -теги и атрибуты: <a href= http://pixelcom.crimea.ua/"" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>