обтекающий текст jQuery и элементы между <часом> теги

Я должен перенести все, включая произвольный текст, который является между два <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') потому что это не выберет текст, с которого снимают метку.

5
задан user191688 18 July 2010 в 15:35
поделиться

4 ответа

Обновлено

Эта версия мне нравится больше, чем моя предыдущая: 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/

РЕДАКТИРОВАТЬ: Немного поправили в обоих примерах.

5
ответ дан 14 December 2019 в 01:00
поделиться

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"));​​​​​​​​​​​​​​​​​
1
ответ дан 14 December 2019 в 01:00
поделиться

Если 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]

Так вы можете легко объединить их в группы, как вам нужно.

0
ответ дан 14 December 2019 в 01:00
поделиться
​$('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 , а затем все они будут заключены в

.

2
ответ дан 14 December 2019 в 01:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: