Я должен перенести все, включая произвольный текст, который является между два <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')
потому что это не выберет текст, с которого снимают метку.
Обновлено
Эта версия мне нравится больше, чем моя предыдущая: http://jsfiddle.net/LbmCg/3/
(Частично на основе ответа JP дал.)
$('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 ()
из hr.begin
, получаем все его узлы с помощью .contents ()
, затем фильтруем их, отслеживая когда мы нашли начало и конец и возвращаем только элементы между ними.
Затем мы используем .wrapAll ()
, чтобы обернуть их div.content
.
РЕДАКТИРОВАТЬ: Если нужно обернуть несколько наборов, попробуйте следующее: http://jsfiddle.net/LbmCg/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
.
-
Я попробовал это решение с тестовыми данными Патрика, и оно работает:
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"));
Если 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)
})
outputs:
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]
Так вы можете легко объединить их в группы, как вам нужно.
$('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">');
});
Это может обрабатывать несколько наборов последовательности начало - содержимое - конец
. Он будет искать все элементы hr.end
, которым предшествуют элементы hr.begin
, и для каждого hr.end
найдет предыдущие узлы между ним и hr.begin
, а затем все они будут заключены в