1

我已经意识到最近几次我需要在一些 jQuery 选择器中加入文本节点选择。

jQuery 本身并不真正支持文本节点。大多数关于此类问题的答案都建议使用.contents(),但这并不真正属于“选择器”,而是“遍历”。因此,它只给出直接子节点,它给出所有子节点,而不仅仅是文本节点。

我发现我需要在任意标记的文本中选择所有文本节点,所以我感兴趣的一些文本节点将是孙子、曾孙等:

<div id="formattedText">
  This is a <b>sample</b> block <a href="http://somewhere.com">of <em>text</em></a>
  that I might want to get a list of <span class="groovy">all</span> text nodes in.
</div>

因此,实现这一点而不是尝试实现递归调用的最具表现力的方法.children()是将 jQuery 选择器扩展为如下所示:

var txtNodes = $('#formattedText §');

where§代表一些新的语法,我将添加到表示文本节点的 jQuery 中。我必须找到一些未使用的 ASCII 符号或类似:odd()扩展的东西:

var txtNodes = $('#formattedText:textNodes()');

如何以这种方式扩展 jQuery 的选择器引擎?我假设我想使用他们现有的 DOM 遍历方法,而不必求助于构建新方法?

或者也许有一个表达技巧.contents(),我没有想到它可以做我想做的事,而无需我扩展 jQuery?


我的用例:我想在用户脚本(greasemonkey 等)中对来自第三方网站的文本进行自定义“突出显示”。通过“自定义”,我的意思是不同的模式会得到不同background-color的 s 等等。所以我需要所有的文本节点,无论它们的深度如何,我不希望它们周围有标签,我也不希望所有文本都像.text()这样给我吗。

4

1 回答 1

1

:我还没有掌握制作-pseudo-selector 扩展所需的新签名,但这里有一个方法:

(function($){

    function walk( node, ret ) {
        var ret = ret || [],
            cur,
            nodes = node.childNodes;

        for( var i = 0, l = nodes.length; i < l; ++i ) {
            cur = nodes[i];

            if( cur.nodeType === 1 ) {
                walk( cur, ret );
            }
            else if( cur.nodeType === 3 ) {
                ret.push( cur );
            }
        }

        return ret;
    }

    $.fn.findText = function() {

        var ret = this.map( function() {
            return walk( this );
        });

        return this.pushStack( ret, "textNodes", "" );
    };

})( jQuery );

在这里的演示中,我将按找到的顺序遍历找到的文本节点,以便您可以在页面上看到顺序。

于 2012-11-23T10:56:44.210 回答