How to perform extensive DOM insertion with jQuery append() (in the correct order)?
When I use the jQuery append()
method, the resulting HTML output is not in the order I intend.
As you see in the test case below, any time I open a DIV
tag without closing it, it is closed nevertheless.
The same goes for the <ul>
tag - which was also closed before I expected - I wanted it to be closed after the second <li>
tag that is supposed to be nested below it.
What's the best way to build a large block of dynamic HTML in the order it is written?
$('#a').remove(); // remove #a from the dom and re-insert it dynamically
$("<div id='a'>").insertAfter('div#main');
$('#a').append(" <ul>");
$('#a').append(" <li>A</li>");
$('#a').append(" <li>B</li>");
$('#a').append(" </ul>");
$('#a').append(" <div id='X1'>");
$('#a').append(" <div id='b'>");
$('#a').append(" <div id='b1'></div>");
$('#a').append(" <div id='b2'></div>");
$('#a').append(" </div>");
$('#a').append(" <div id='c'&g开发者_如何转开发t;");
$('#a').append(" <p id='c1'></p>");
$('#a').append(" </div>");
$('#a').append(" </div>");
$('#a').append(" <div id='X2'>B</div>");
$('#a').append("</div>");
<div id="main>
<div id="a>
<ul></ul> // <ul> tag is closed!?
<li>A</li>
<li>B</li>
<div id='X1'></div> // div is closed!?
<div id='b'> // div is closed!?
<div id='b1'></div>
<div id='b2'></div>
<div id='c'></div> // div is closed!?
<p id='c1'></p>
<div id='X2'>B</div>
</div>
</div>
The important thing to remember here is that .append()
doesn't append HTML, it appends DOM elements generated by the HTML you pass in, so for example <ul>
will be a <ul></ul>
element like you're seeing.
To have it spaced out similar to what you have currently, you either need to append each line or use \
like this:
$("<div id='a'>\
<ul> \
<li>A</li> \
<li>B</li> \
</ul> \
<div id='X1'> \
<div id='b'> \
<div id='b1'></div> \
<div id='b2'></div> \
</div> \
<div id='c'> \
<p id='c1'></p> \
</div> \
</div> \
<div id='X2'>B</div> \
</div>").insertAfter('div#main');
You can test it out here.
Use a simple StringBuffer implementation, such as the one below. Once the html has been fully buffered offline, write it to the DOM all at once:
function StringBuffer() {
this.buffer = [];
}
StringBuffer.prototype.append = function append(string) {
this.buffer.push(string);
return this;
};
StringBuffer.prototype.toString = function toString() {
return this.buffer.join("");
};
var buf = new StringBuffer();
buf.append('<ul>');
buf.append('<li>A</li>');
buf.append('</ul>');
...etc...
$("#a").empty().html(buf.toString());
And see: http://developer.yahoo.com/performance/rules.html
You need to build the complete string first, then pass that to append:
// this creates the div with id 'a', and inserts it into
// the DOM (assuming you have an existing div with id 'main')
//
$("<div id='a'></div>").insertAfter('div#main');
// now you can build up additional content as a string...
//
var s = " <ul>";
s += " <li>A</li>";
s += " <li>B</li>";
s += " </ul>";
s += " <div id='X1'>";
s += " <div id='b'>";
s += " <div id='b1'></div>";
s += " <div id='b2'></div>";
s += " </div>";
s += " <div id='c'>";
s += " <p id='c1'></p>";
s += " </div>";
s += " </div>";
s += " <div id='X2'>B</div>";
// now, use the append() function to create DOM from the string,
// and append it to the content of your div#a all at once.
//
$('#a').append(s);
there are more efficient ways to build that string, but... you get the idea.
jQuery append is designed to work with a complete snippet of HTML. Modify your code to all append() only once and pass it all your code concatenated together. If you do not, append() will close any open tags automatically.
<script>
$('#a').html(your_html);
</script>
精彩评论