Using .after () to add html closing and opening tags

I am trying to split an unordered list into two columns, finding half the point of the list and adding </ul><ul> after that </li> . It might be the complete wrong way to do this, but I thought so. My js look like this:

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

The problem I ran into, and that I don't understand, is that .after () is reordering tags and outputs:

<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>

Please let me know if there is a better way to do this, but I really would like to know why .after () is reordering the tags. Thanks

+4
source share
2 answers

You cannot think of modifying the DOM as if you were editing the source HTML file. After the browser has parsed the HTML file, it still does not exist. The only thing that matters is the representation of the DOM.

With that in mind, let's look at the bit of code that you posted ...

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

You imagine editing this existing HTML and adding a closing tag and an opening tag. This is not true. It creates a piece of the document from this code, and then adds it as a sibling in the original selection. Since </ul> not a valid beginning of an HTML string, it is discarded. All you have left is a <ul> , which is parsed as an entire element (imagine an HTML document that passed <div><ul></div> and you get this idea). Thus, the empty ul element is inserted into the list as a child of the element you selected: it is presented as <ul></ul> , since this is a way to serialize the ul element in HTML.

To do what you want to do, you need to use a different approach that recognizes what the DOM is.

 $('.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); }); 

This says: "Get the children after half ( :gt ), detach them from the current ul , wrap them in the new ul , select ul with parent and insert after the current ul ( this )."


JsFiddle work

+7
source

You cannot add half the tags in the DOM, you can only add full elements. When you try, the browser is best to fix the code, and you will get <ul></ul> instead of </ul><ul> . (Actual results may vary between browsers because they have different strategies for fixing the wrong code.)

Instead, add another ul element after the first and move half the elements to it:

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

Source: https://habr.com/ru/post/1389001/


All Articles