【问题标题】:jQuery nextUntil include text nodesjQuery nextUntil 包含文本节点
【发布时间】:2014-11-10 11:47:03
【问题描述】:

我正在使用nextUntil 方法来获取两个元素之间的所有内容。但是这种方法不包括text nodes 来输出。它给出了一个类似[<br>, <br>, <br>] 的数组。如何获取包括文本节点在内的所有内容?

这是 HTML 代码:

$('.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/

【问题讨论】:

  • .contents() 返回文本节点。
  • 如何修改contents()的代码?
  • 以下可能的答案(如果我正确理解了目标)

标签: javascript jquery wrapall


【解决方案1】:

您可以创建自己的 jquery 插件,其功能与 nextUntil 相同,但包含文本节点:

$.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);
};

因此,您可以将其称为 nextUntilWithTextNodes 而不是 nextUntil,您就可以开始了。

【讨论】:

  • 谢谢!你让我开心。
【解决方案2】:

只有 jQuery .contents() 方法返回所有节点(包括文本节点,通常被忽略)。

所以也许是这样的?:

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>');
    }
});

它只是迭代所有节点并基于一个标志开始一个新的集合,或者包装找到的节点。

最后的if (open) 允许在content 分类的div 内有一个未封闭的spolier 块。

注意事项:

  • $() 是一个空的 jQuery 集合(类似于一个空数组,但用于 jQuery 对象)
  • 我建议你为你的剧透使用一种风格并使用一个类,例如result.wrapAll('&lt;div class="spoiler"&gt;&lt;/div&gt;');

例如http://jsfiddle.net/ykv3gf5L/3/

【讨论】:

    猜你喜欢
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多