开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜