我需要包装两个<hr>
元素之间的所有内容,包括自由文本。
鉴于此来源:
<hr class=begin>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href=mauris.html>Mauris</a> id diam turpis, et faucibus nunc.
<div><img src=foo.png /></div>
<hr class=end>
我需要在hr.begin
和hr.end
标记之间包装所有内容,如下所示:
<hr class=begin>
<div class=content>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href=mauris.html>Mauris</a> id diam turpis, et faucibus nunc.
<div><img src=foo.png /></div>
</div>
<hr class=end>
我无法使用像.nextUntil('hr.end')
这样的方法,因为这不会选择未标记的文字。
答案 0 :(得分:5)
<强>更新强>
我比以前更喜欢这个版本:http://jsfiddle.net/LbmCg/3/
(部分灵感来自 J-P 给出的答案。)
$('hr.begin').each(function(){
var $set = $();
var nxt = this.nextSibling;
while(nxt) {
if(!$(nxt).is('hr.end')) {
$set.push(nxt);
nxt = nxt.nextSibling;
} else break;
}
$set.wrapAll('<div class="content" />');
});
原始回答
试试这个:http://jsfiddle.net/LbmCg/
如果要包装多个套装,则需要进行一些调整。
var foundBegin = false;
var foundEnd = false;
$('hr.begin').parent()
.contents()
.filter(function() {
if($(this).is('hr.begin')) {
foundBegin = true;
}
if($(this).is('hr.end')) {
foundEnd = true;
}
return foundBegin && !foundEnd;
})
.wrapAll('<div class="content"/>');
jQuery的.contents()
返回包括文本节点在内的所有节点。因此,我们在此处遍历.parent()
的{{1}},使用hr.begin
获取所有节点,然后对其进行过滤,跟踪我们何时找到开头和结尾,并且仅返回他们之间的元素。
然后我们使用.contents()
用.wrapAll()
包装它们。
编辑:如果有多套要换行,请试试:http://jsfiddle.net/LbmCg/1/
编辑:在两个示例中都清理了一点。
答案 1 :(得分:2)
$('hr.begin ~ hr.end').each(function(){
var contents = [], node, begin = $(this).prevAll('hr.begin')[0];
if (node = this.previousSibling) do {
if (node === begin) break;
contents.unshift(node);
} while (node = node.previousSibling);
$(contents).wrapAll('<div class="content">');
});
这可以处理多组begin - contents - end
序列。它将查找hr.end
元素前面的所有hr.begin
元素,并且对于每个hr.end
,将查找它与hr.begin
之间的前面节点,然后它将包装它们全部在<div class=content>
。
答案 2 :(得分:1)
theElement.contents()
将识别文本节点。由于jQuery.nextUntil()
实际上是jQuery.dir
的包装,而
dir: function( elem, dir, until ) {
var matched = [], cur = elem[dir];
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
if ( cur.nodeType === 1 ) {
matched.push( cur );
}
cur = cur[dir];
}
return matched;
},
过滤掉的文本节点的nodeType
为3,自定义jQuery.dir
可能会有所帮助。
-
我用Patrick的测试数据尝试了这个解决方案并且它可以工作:
jQuery.dirIncludingTextNodes = function( elem, dir, until ) {
var matched = [], cur = elem[dir];
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
if ( cur.nodeType === 1 ||cur.nodeType === 3 ) {
matched.push( cur );
}
cur = cur[dir];
}
return matched;
};
jQuery.nextUntilIncludingTextNodes = function( elem, i, until ) {
return jQuery.dirIncludingTextNodes( elem, "nextSibling", until );
};
$('hr.begin').nextUntilIncludingTextNodes("hr").wrap($("<div>").addClass("content"));
答案 3 :(得分:1)
有一个类似的问题,但是我使用的是基于FCKEditor的CMS,由于使用nextSibling属性插入换行符号TextNodes,因此工作不太热。如果我能帮助它,我通常不喜欢将jQuery的东西与原生JavaScript混合在一起。我想出了这个片段,它更新了Patrick DW的解决方案,可能对jQuery的使用更加友好。也不需要类来确定下一个块。
$('hr').each(function(){
var $set = $([]);
var $nxt = $(this).next();
while($nxt.length) {
if(!$($nxt).is('hr')) {
$set = $set.add($nxt);
$nxt=$nxt.next();
} else break;
}
$set.wrapAll('<div class="content" />');
});
答案 4 :(得分:0)
如果HR和其他标签位于div内,例如
<div id="mydiv">
<hr class=begin>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href=mauris.html>Mauris</a> id diam turpis, et faucibus nunc.
<div><img src=foo.png /></div>
<hr class=end>
</div>
您可以使用jQuery.contents()例如
$("#mydiv").contents().each(function(i,el){
console.log(i,el)
})
输出:
0, [object Text]
1, [object HTMLHRElement]
2, [object Text]
3, http://jsbin.com/mauris.html
4, [object Text]
5, [object HTMLDivElement]
6, [object Text]
7, [object HTMLHRElement]
8, [object Text]
因此,您可以根据需要轻松地分组。
答案 5 :(得分:0)
user191688代码的扩展版本。 这不仅仅是在兄弟姐妹中寻找“直到”,而且还在树上寻找。
(function($){
$.fn.extend({
nextUntilExtended: function(until) {
var $set = $();
var nxt = this.get(0).nextSibling;
while(nxt) {
if(!$(nxt).is(until)) {
if(nxt.nodeType != 3 && $(nxt).has(until)){
nxt = nxt.firstChild;
}else{
$set.push(nxt);
if(nxt.nextSibling){
nxt = nxt.nextSibling;
}else{
nxt = nxt.parentNode.nextSibling;
}
}
} else break;
}
return($set);
}
});
})(jQuery);