是否有一个只包装连续元素的wrapAll版本?所以这个:
<p>foo</p>
<p>foo</p>
<h2>bar</h2>
<p>foo</p>
变成了这个:
<div>
<p>foo</p>
<p>foo</p>
</div>
<h2>bar</h2>
<div>
<p>foo</p>
</div>
何时运行?
$('p').wrapAll2('<div />')
答案 0 :(得分:6)
这是一种方法:
$(function(){
var cWrap=$('<div />');
$('p').each(function(){
var o = $(this).next('p').length;
$(this).replaceWith(cWrap).appendTo(cWrap);
if (!o) cWrap=$('<div />');
});
});
或作为完全成熟的插件:
(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 />');
});
*请注意,它假定您将在同类集合上调用它(至少所有相同的节点类型)
实验上,我研究了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 />');
});
确实可以使用此类内容:$('p').add('span').wrapAll2('<div />');
答案 1 :(得分:2)
我阐述了Shad的优秀答案并创建了一些可以选择任何选择器的代码,而不仅仅是节点类型:
(function($){
$.wrapAll2 = function(sel, wrapSel) {
var wrap = $(wrapSel);
$(sel).each(function() {
var more = $(this).next(sel).length;
$(this).replaceWith(wrap).appendTo(wrap);
if (!more) wrap = $(wrapSel);
});
};
})(jQuery);
$(function() {
$.wrapAll2('p', '<div/>');
});
希望它可以传递给JQuery对象而不是选择器字符串,但这对我的目的来说已经足够好了。
答案 2 :(得分:1)
以下是适用于任何jQuery选择器的通用解决方案,也可在修改集合时使用,例如使用add()
或{{ 1}}或andSelf()
:
not()
演示基于操纵的集合显示它的工作:http://jsfiddle.net/wujX6/1/
唯一需要注意的是,连续元素之间的插入文本节点不包含在包装中。因此,例如,调用(function($){
$.fn.wrapConsecutive = function(wrapper){
if (!this.length) return this;
var thisRun,prev;
this.each(function(){
if (!prev || $(this).prev()[0]!=prev){
if (thisRun) thisRun.wrapAll(wrapper);
thisRun = $();
}
thisRun = thisRun.add(this);
prev = this;
});
if (thisRun) thisRun.wrapAll(wrapper);
return this;
};
})(jQuery);
这个HTML:
$('p').wrapConsecutive('<div/>')
...将导致此输出:
<p>foo</p>
<p>bar</b>
jim
<p>baz</p>
jar