:包括()不返回预期的节点(:contains() does not return the expe

2019-10-20 20:25发布

请考虑下面的代码:

// @include     /(^https?:\/\/www\.|^https?:\/\/)google\.com(\.|\/).*/
// @include     /(^https?:\/\/www\.|^https?:\/\/)stackoverflow\.com\/.*/
// @include     /(^https?:\/\/www\.|^https?:\/\/)userscripts-mirror\.org\/.*/
// @include     http://wiki.greasespot.net/*
// @version     1.0
// @require     https://code.jquery.com/jquery-2.1.1.min.js
// @grant       GM_addStyle


$ ( 'body:contains("serscripts.org")').each ( function ()  {

var results = $(this);
var text = results.text();
console.log(text);
text = text.replace( /serscripts\.org/ig, "serscripts-mirror.org" );
text = text.replace( /(:8080|%3A8080)/ig, "");
    //results.text ( text );

} );

我预期回报应该只是包含字符串的元素,但在控制台上的结果是身体的所有文本。


考虑这个页面在行:

// @updateURL       https://userscripts.org/scripts/so...

我想改变这种状况。


或者这一个 :

// @require http://userscripts.org/scripts/source...

我想改变太多。


标签之间的所有的话应该进行检查的字符串,并返回只有拥有它的人。

什么是这个正确的选择?


注意
链接属性之间的文本<a></a>使用类似的已经改变了.each ( function )

Answer 1:

:contains在返回正是预期。 从规范 :

匹配的文本可以直接选定元件内出现,在任何该元素的后代或其组合


在一般情况下,更换,包装或高亮显示网页上的文本而言,你需要在单个工作TEXT_NODE水平。 还有什么风险捣毁:网址,ID的,事件处理程序的,等等。

您可以使用树沃克为此:

var txtWalker   = document.createTreeWalker (
    document.body,
    NodeFilter.SHOW_TEXT,
    {   acceptNode: function (node) {
            //-- Skip whitespace-only nodes
            if (node.nodeValue.trim() )
                return NodeFilter.FILTER_ACCEPT;

            return NodeFilter.FILTER_SKIP;
        }
    },
    false
);
var txtNode     = null;

while (txtNode  = txtWalker.nextNode () ) {
    var oldTxt  = txtNode.nodeValue;
    var newTxt  = oldTxt.replace (/serscripts\.org/ig, "serscripts-mirror.org");
    newTxt      = newTxt.replace (/(:8080|%3A8080)/ig, "");

    txtNode.nodeValue = newTxt;
}

这将安全地照顾一切的页面上,除了HTML属性,如hrefsrc等。

如果你想改变这些,使用单独的,有针对性的.each ()的代码-就像你说你做-但不更改的文字<a></a>为将已经由树做步行者。



文章来源: :contains() does not return the expected nodes