Best way to create nested HTML elements with jQuery

If I need to create a pair of nested DOM elements, I know one way to do this is to write them as a long string and then put them into the document using the appropriate jQuery function. Something like:

elem.html( '<div class="wrapper"> <div class="inner"> <span>Some text<span> </div> <div class="inner"> <span>Other text<span> </div> </div>'); 

This path is obviously not the cleanest. A bite does not take too much time to become messy, and editing becomes a problem. I prefer this notation more:

 $('<div></div>', { class : 'inner' }) .appendTo( elem ); 

The problem is that I do not know how to effectively implement it when creating nested elements on the fly, as described above. Therefore, if there is a way to make the first example with the second notation, I will be glad to know about it.

Basically, the question is, what is the best way to create nested HTML elements on the fly without having to deal with dirty long lines?

Note. I know engine patterns. However, it is a matter of creating just a couple of HTML elements on the fly. For example, when building DOM dependencies for a plugin or similar cases.

+43
javascript jquery dom nested
Jun 23 2018-12-12T00:
source share
6 answers

write them as a long string and put them in a document using the appropriate jQuery function. Something like:

The problem with this approach is that you will need a multi-line string - Javascript does not support, so in fact you will get:

 elem.html( '<div class="wrapper">'+ '<div class="inner">'+ '<span>Some text<span>'+ '</div>'+ '<div class="inner">'+ '<span>Other text<span>'+ '</div>'+ '</div>'); 

Using the method you suggested above is about as clean as I could get it:

 elem.append( $('<div/>', {'class': 'wrapper'}).append( $('<div/>', {'class': 'inner'}).append( $('<span/>', {text: 'Some text'}) ) ) .append( $('<div/>', {'class': 'inner'}).append( $('<span/>', {text: 'Other text'}) ) ) ); 

Another advantage of this is that you can (if you wish) get direct links to each newly created element without re-querying the DOM.

I like to write polyglots , so to make my code re-accessible, I usually do something like this (since jQuery .html() doesn't support XML):

 // Define shorthand utility method $.extend({ el: function(el, props) { var $el = $(document.createElement(el)); $el.attr(props); return $el; } }); elem.append( $.el('div', {'class': 'wrapper'}).append( $.el('div', {'class': 'inner'}).append( $.el('span').text('Some text') ) ) .append( $.el('div', {'class': 'inner'}).append( $.el('span').text('Other text') ) ) ); 

This is not very different from method # 2, but it gives you more portable code and does not rely on innerHTML internally.

+46
Jun 23 2018-12-12T00:
source share

I like the following approach:

 $('<div>',{ 'class' : 'wrapper', 'html': $('<div>',{ 'class' : 'inner', 'html' : $('<span>').text('Some text') }).add($('<div>',{ 'class' : 'inner', 'html' : $('<span>').text('Other text') })) }).appendTo('body'); 

As an alternative, first create your own packaging and continue to add to it:

 var $wrapper = $('<div>',{ 'class':'wrapper' }).appendTo('body'); $('<div>',{ 'class':'inner', 'html':$('<span>').text('Some text') }).appendTo($wrapper); $('<div>',{ 'class':'inner', 'html':$('<span>').text('Other text') }).appendTo($wrapper); 
+17
Jun 23 2018-12-23T00:
source share

I found this solution while I was learning something else. This is part of the jQuery Introduction by the jQuery creator and uses end () .

 $("<li><a></a></li>") // li .find("a") // a .attr("href", "http://ejohn.org/") // a .html("John Resig") // a .end() // li .appendTo("ul"); 

Applying to your question would be ...

 $("<div><span></span></div>") // div .addClass("inner") // div .find("span") // span .html("whatever you want here.") // span .end() // div .appendTo( elem ); 
+14
Sep 11 '13 at 23:19
source share

I like this approach

  $("<div>", {class: "wrapper"}).append( $("<div>", {class: "inner"}).append( $("<span>").text( "Some text" ) ), $("<div>", {class: "inner"}).append( $("<span>").text( "Some text" ) ) ).appendTo("body") 
+6
Jun 23 '12 at 23:13
source share

There is a third way, in addition to long ugly lines or huge methods put together. You can use simple old variables to store individual elements:

 var $wrapper = $("<div/>", { class: "wrapper" }), $inner = $("<p/>", { class: "inner" }), $text = $("<span/>", { class: "text", text: "Some text" }); 

Then link everything together with append :

 $wrapper.append($inner.append($text)).appendTo("#whatever"); 

Result:

 <div class="wrapper"> <p class="inner"> <span class="text">Some text</span> </p> </div> 

In my opinion, this is by far the cleanest and most readable approach, and it also has the advantage of sharing data with code.

EDIT: One caveat is that there is no easy way to combine textContent with nested elements (e.g. <p>Hello, <b>world!</b></p> .) In this case, you probably need to use one other method such as a string literal.

+6
Jan 10 '14 at 3:24
source share

The long line is obviously the cleanest. You see that the code is correctly embedded without unnecessary noise, such as brackets, dollar signs, and what not. Of course, it would be useful to be able to write it as a multi-line string, but this is not possible now. It is important for me to get rid of all unnecessary characters. I do not know how the line becomes messy, and editing becomes a problem. If you have assigned many classes, you can put them on a separate line:

 '<div id="id-1"' + ' class="class-1 class-2 class-3 class-4 class-5 class-6">' + '</div>' 

or as follows:

 '<div id="id-1" class="' + 'class-1 class-2 class-3 class-4 class-5 class-6' + '">' + '</div>' 

Another option is probably to use haml on the client side, if possible. This way you will have even less unnecessary noise.

+1
Aug 26 '13 at 15:26
source share



All Articles