如何在 jQuery 中实现任意文本节点选择

Posted

技术标签:

【中文标题】如何在 jQuery 中实现任意文本节点选择【英文标题】:How to implement arbitrary textnode selection in jQuery 【发布时间】:2012-11-11 17:20:03 【问题描述】:

我意识到最近几次我需要在一些 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 §');

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

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

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

或者也许有一个使用 .contents() 的表达技巧,我没想到它可以在我不必扩展 jQuery 的情况下做我想做的事?


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

【问题讨论】:

相关:jQuery custom selector for text nodes 【参考方案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 );

在demo 此处,我将按找到的顺序遍历找到的文本节点,以便您可以在页面上看到顺序。

【讨论】:

不错。我原以为它会比这更毛茸茸(-:

以上是关于如何在 jQuery 中实现任意文本节点选择的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET 中实现 Blueimp jQuery 文件上传

如何使用 jQuery 选择文本节点?

如何在 jquery 中实现 MVC [关闭]

如何使用jQuery在发票中实现折扣值

如何在 glsl 中实现任意大小的向量

如何在 JavaScript/jQuery 中实现重载?