Использование .after () для добавления закрывающих HTML и открытых тегов - PullRequest
4 голосов
/ 03 января 2012

Я пытаюсь разбить неупорядоченный список на два столбца, найдя половину списка и добавив </ul><ul> после этого </li>. Это может быть совершенно неправильный способ сделать это, но я так и думал. Мой JS выглядит так:

$('.container ul').each(function(){

    var total = $(this).children().length;
    var half = Math.ceil(total / 2) - 1;
    $(this).children(':eq('+half+')').after('</ul><ul>');

});

Проблема, с которой я столкнулся, и чего я не понимаю, заключается в том, что .after () меняет порядок тегов и выводов:

<ul>

<li><a href="#">link</a></li>

<li><a href="#">link</a></li>

<li><a href="#">link</a></li>

<ul></ul>

<li><a href="#">link</a></li>

<li><a href="#">link</a></li>

</ul>

Пожалуйста, дайте мне знать, если есть лучший способ сделать это, но я действительно хотел бы знать, почему .after () меняет порядок тегов. Спасибо

Ответы [ 2 ]

8 голосов
/ 03 января 2012

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

Имея это в виду, давайте посмотрим на фрагмент кода, который вы разместили ...

.after('</ul><ul>')

Вы представляете, как редактируете присутствующий HTML и добавляете закрывающий тег и открывающий тег. Это не так. Он строит фрагмент документа из этого кода, а затем добавляет его как родственный элемент элемента в исходном выделении. Поскольку </ul> не является допустимым началом строки HTML, оно отбрасывается. Все, что у вас осталось, это <ul>, который полностью анализируется как элемент (представьте HTML-документ, который прошел <div><ul></div>, и вы поймете идею). Таким образом, пустой элемент ul вставляется в список как родственный элемент выбранного вами элемента: он представлен как <ul></ul>, поскольку это способ сериализации элемента ul в HTML.

Чтобы делать то, что вы хотите, вам нужно использовать другой подход, который распознает, что такое DOM.

$('.container ul').each(function(){
    var total = $(this).children().length;
    var half = Math.ceil(total / 2) - 1;
    $(this).children(':gt('+half+')').detach().wrapAll('<ul></ul>').parent().insertAfter(this);
});

Здесь написано "забрать детей на полпути (:gt), detach их от нынешних ul, wrap их в новом ul выберите ul с помощью parent и insert после него после текущего ul (this). "


Рабочая jsFiddle

2 голосов
/ 03 января 2012

Вы не можете добавить половину тегов в DOM, вы можете добавить только полные элементы. Когда вы пытаетесь, браузер делает все возможное, чтобы исправить код, и в итоге вы получаете <ul></ul> вместо </ul><ul>. (Фактический результат может отличаться в разных браузерах, поскольку у них разные стратегии исправления неверного кода.)

Вместо этого добавьте еще один элемент ul после первого и переместите к нему половину элементов:

$('.container ul').each(function(){

  var total = $(this).children().length;
  var half = Math.ceil(total / 2) - 1;
  $(this).after('<ul/>').append($(this).children(':gt('+half+')'));

});
...