开发者

jquery .before() no unclosed tags allowed

have a function 开发者_如何学编程in jquery to automatically create the tab elements for a product in ecommerce system.

function structureTabs()
{
    $('#tabs').prepend('<ul id="tabbtns"></ul>');

    $('#tabs h2').each(function(index){

        if(index > 0)
        {
            $(this).before('</div><div id="tabs-'+(index+1)+'">');
        }
        else
        {
            $(this).before('<div id="tabs-'+(index+1)+'" class="jackie">');
        }

        var title = $(this).text();

        $('#tabbtns').append('<li><a href="#tabs-' + (index+1) + '">' + title + '</a></li>');

    });

    $('#tabs').append('</div>');
}

You cannot put unclosed tabs into .before()??

Basically the content this is trying to wrap around is:

<div id="tabs">
<h2>Details</h2>
details text...
<h2>tech specs</h2>
tech spec text...
<h2>Video Sample</h2>
video embed url
</div>

The client of the eccomerce store can't edit html, so need to build the tabs automatically in .js....


jQuery works with elements, not markup. Before, after and the rest of the dom manipulation functions as well as the $/jQuery function all work with elements. The only function which works with markup is html.

To do what you want you either have to rethink your logic, or modify the markup via the html function.


You might want to take a look at the .wrap() and .wrapAll() functions. They allow you to wrap your element(s) in another. For instance:

 $(this).wrap('<div id="tabs-'+(index+1)+'" class="jackie">');

You can take a slightly different approach: Create your <div> element, insert it before the element, and then add the elements you want to it as children. This is a little complicated when dealing with text nodes (i.e. not wrapped in a tag) because jQuery will just ignore them for its traversal methods. The following code should work given your example code:

$("#tabs h2").each(function(index) {

    var $div = $('<div id="tabs-' + (index + 1) + '" class="jackie">');
    $div.insertBefore(this);
    // jQuery skips text nodes, so lets grab all the nodes until we find another h2
    // using DOM
    var nodes = [this];
    var node = this.nextSibling;
    while (node && !(node.tagName && node.tagName.toUpperCase() == 'H2')) {
        nodes.push(node);
        node = node.nextSibling;
    }
    $div.append(nodes);

});

Demoed on jsFiddle

If you don't need to worry about text nodes, it could be shortened quite a bit using the .nextUntil() function for traversing.

$("#tabs h2").each(function(index) {

    var $div = $('<div id="tabs-' + (index + 1) + '" class="jackie">');
    // put the div before the <h2>
    $div.insertBefore(this);
    // append the <h2> and all the siblings forward until you find another <h2>
    $div.append(this, $(this).nextUntil('h2'));

});


So to sum up all the other answers, I think the final script you are looking for would be something like this:

$("#tabs h2").each(function(i) {
    $(this).nextUntil("h2").andSelf()
        .wrapAll('<div id="tab-'+ i +'"></div>');
});

$("#tabs").before('<ul id="menu"></ul>')
$("#tabs > div > h2").each(function(i) {
    $("#menu")
        .append('<li><a href="#tab-'+ i +'">'+$(this).text()+'</a></li>');
});

There is just one little problem, though. It won't work if you details text isn't inside some html element. jQuery's next or nextUntil function doesn't recognise plain text as an element.


Why not use the .wrap() function after you build the tabs?

$('#tabs').wrap('<ul id="tabbtns"></ul>');

That will wrap the <ul> tag around the html you built.


function structureTabs() { $('#tabs').prepend('');

$('#tabs h2').each(function(index){ $(this).nextUntil('h2').andSelf().wrapAll(''); var title = $(this).text(); $('#tabbtns').append('

  • ' + title + '
  • '); });

    $('#tabs div').remove('h2'); }

    structureTabs();


    I'd build up a jQuery object and append it to the element you need:

    (function() {
    
        var h2 = ["Details", "tech specs", "Video sample"];
        var text = ["details text...", "tech spec text...", "video embed url"]
    
        $(function() {
    
              // create tabs jQuery object
            var $tabs = $("<div/>").attr("id","tabs");
    
              // loop through all h2 contents
            $.each(h2, function(index, value) {
    
                  // Add h2 tags
                $tabs.append($("<h2/>").html(value));
    
                  // Add text after h2 tag
                $tabs.append(text[index]);        
            });
    
              // Add tabs to the DOM
            $("body").append($tabs);
        });
    })();
    
    0

    上一篇:

    下一篇:

    精彩评论

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

    最新问答

    问答排行榜