jQuery nextUntil includes text nodes

I use the nextUntil method to get all things between two elements. But this method does not include text nodes for output. This gives an array like [<br>, <br>, <br>] . How can I get all things, including text nodes?

This is the HTML code:

 $('.content a:contains("spoiler").b:even').each(function() { $(this).nextUntil('.content a:contains("spoiler").b') .wrapAll('<div style="border:solid 1px black;"></div>'); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="content"> --- <a class="b" href="/?q=spoiler">spoiler</a> --- <br> <br> dangerous text here <br> --- <a class="b" href="/?q=spoiler">spoiler</a> --- <br> safe text here <br> --- <a class="b" href="/?q=spoiler">spoiler</a> --- <br> <br> dangerous text here <br> --- <a class="b" href="/?q=spoiler">spoiler</a> --- </div> 

JSFiddle: http://jsfiddle.net/Lwk97rvq/1/

+6
source share
2 answers

Only the jQuery .contents() method returns all nodes (including text nodes that are usually ignored).

So maybe something like this ?:

http://jsfiddle.net/ykv3gf5L/2/

 $('.content').each(function () { var open = false; var result = $(); $(this).contents().each(function () { var $this = $(this); if ($this.text() == "spoiler") { if (open) { result.wrapAll('<div style="border:solid 1px black;"></div>'); open = false; } else { result = $(); open = true; } } else { result = result.add($this) } }); if (open) { result.wrapAll('<div style="border:solid 1px black;"></div>'); } }); 

It simply iterates over all the nodes and, based on the flag, starts a new collection or wraps the found nodes.

The final if (open) resolves the unclosed argument block in the content classed div.

Notes:

  • $() is an empty jQuery collection (e.g. an empty array, but for jQuery objects)
  • I suggest you use a style for your spoilers and use a class, for example. result.wrapAll('<div class="spoiler"></div>');

eg. http://jsfiddle.net/ykv3gf5L/3/

+4
source

You can create your own jquery plugin that does the same as nextUntil but contains text nodes:

 $.fn.nextUntilWithTextNodes = function (until) { var matched = $.map(this, function (elem, i, until) { var matched = []; while ((elem = elem.nextSibling) && elem.nodeType !== 9) { if (elem.nodeType === 1 || elem.nodeType === 3) { if (until && jQuery(elem).is(until)) { break; } matched.push(elem); } } return matched; }, until); return this.pushStack(matched); }; 

So you can call this nextUntilWithTextNodes instead of nextUntil and all nextUntil .

+2
source

Source: https://habr.com/ru/post/1202697/


All Articles