简体   繁体   中英

Using .append() with lists places text on a newline

I'm trying to create an unordered list in javascript. My code reads:

$(div).append("<ul>")
for (i in usersLst){
    $(div).append("<li>")
    $(div).append(usersLst[i][1])
    $(div).append("</li>")
}
$(div).append("</ul>")

Then the result is:

•
bob
•
alice
•
fred

However, if the code reads:

$(div).append("<ul>")
for (i in usersLst){
    $(div).append("<li>"+usersLst[i][1]+"</li>")
}
$(div).append("</ul>")

Then the result is:

 - bob
 - alice
 - fred

So with three separate appends it appears that a newline is being mysteriously inserted. What's going on?

Assume this code:

$('div')
    .append("<ul>")
    .append("<li>");
    .append('foo');
    .append("</li>")
    .append("</ul>")​​​

Lets have a look at the resulting structure (Chrome 21):

<div>
    <ul></ul>
    <li></li>
    foo
</div>

What happend? .append takes each argument and converts the strings to proper DOM elements. Thus the code is the same as doing:

$('div')
   .append(document.createElement('ul'))
   .append(document.createElement('li'));
   .append(document.createTextNode('foo'));

The two calls containing closing tags are ignored since they cannot be convert to valid HTML / DOM elements.

.append (and all other DOM manipulation methods) is working on DOM elements . It's just jQuery's way of calling .appendChild [MDN] .

HTML is just a specific format of representing structure. In there, each element is represented by a opening tag and an (optional) closing tag . The browser is parsing the HTML and creates the DOM in memory. The DOM (Document Object Model) is a well defined interface for interacting with hierarchical, structured data. Once you are working with the DOM, start and end tags don't exist anymore (that's HTML), only Nodes . I recommend to read about DOM on MDN .

jQuery allows you to pass HTML strings to .append because it is convient, but each string is immediately converted to corresponding DOM nodes and appended to other nodes. You cannot build an HTML string with multiple calls to .append .

This is a corrected version of your code:

// jQuery parses the HTML string and creates a UL element
var $ul = $('<ul />');
// equivalent to
// var $ul = document.createElement('ul'); <- NOTE: not HTML, it's a node name

for (var i in usersLst) {
    // jQuery parses the HTML, creates a LI element and appends it to the list
    $ul.append('<li>' + usersLst[i][1] + '</li>');
    // equivalent to
    // var li = document.createElement('li');
    // li.appendChild(document.createTextNode(usersLst[i][1]));
    // $ul.appendChild(li);
}

// append the populated UL element to an existing node:
$(div).append($ul);
// equivalent to
// existingElement.appendChild($ul);

They are both incorrect. You should create the entire string first, then append it to the DIV:

var ul = '<ul>';
for (i in usersLst){
    ul+='<li>' + usersLst[i][1] + '</li>';
}
ul+='</ul>';

$(div).append(ul)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM