寻找类似于wrapAll的jQuery函数,它只包含连续的元素

mat*_*ndr 5 jquery wrapall

是否有一个只包装连续元素的wrapAll版本?所以这:

<p>foo</p>
<p>foo</p>
<h2>bar</h2>
<p>foo</p>
Run Code Online (Sandbox Code Playgroud)

变成这样:

<div>
    <p>foo</p>
    <p>foo</p>
</div>
<h2>bar</h2>
<div>
    <p>foo</p>
</div>
Run Code Online (Sandbox Code Playgroud)

什么时候运行?

$('p').wrapAll2('<div />')
Run Code Online (Sandbox Code Playgroud)

Sha*_*had 6

这是一种方法:

$(function(){
    var cWrap=$('<div />');
    $('p').each(function(){
        var o = $(this).next('p').length;
        $(this).replaceWith(cWrap).appendTo(cWrap);
        if (!o) cWrap=$('<div />');
    });
});
Run Code Online (Sandbox Code Playgroud)

或者作为一个完全成熟的插件:

(function($){
    $.fn.wrapAll2 = function(wrapper){
        if (!this.length) return this;
        var cWrap=$(wrapper),
            tag = this.get(0).nodeName.toLowerCase();
        return this.each(function(){
            var o = $(this).next(tag).length;
            $(this).replaceWith(cWrap).appendTo(cWrap);
            if (!o) cWrap = $(wrapper);
        });
    };
})(jQuery);
$(function(){
    $('p').wrapAll2('<div />');
});
Run Code Online (Sandbox Code Playgroud)

*请注意,它假定您将在同类集合上调用它(至少所有相同的节点类型)

编辑

在实验上,我研究了jQuery的内部结构,发现它存储了用于创建集合的选择器![至少在实例化时],所以考虑到这一点,我创建了另一个版本,至少可以使用当前版本的jQuery,并接受任何选择器!

(function($) {
    $.fn.wrapAll2 = function(wrapper) {
        if (!this.length) return this;
        var wrap = $(wrapper),
            sel = this.selector || this.get(0).nodeName.toLowerCase();
        return this.each(function() {
            var more = $(this).next(sel).length;
            console.log(this,more);
            $(this).replaceWith(wrap).appendTo(wrap);
            if (!more) wrap = $(wrapper);
        });
    }
})(jQuery);
$(function() {
    $('p, span').wrapAll2('<div />');
});
Run Code Online (Sandbox Code Playgroud)

具有这样的事情,虽然工作:$('p').add('span').wrapAll2('<div />');