原生 javascript 相当于 jQuery :contains() 选择器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17799236/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:40:33  来源:igfitidea点击:

Native javascript equivalent of jQuery :contains() selector

javascriptjqueryuserscripts

提问by coulbourne

I am writing a UserScript that will remove elements from a page that contain a certain string.

我正在编写一个 UserScript,它将从包含某个字符串的页面中删除元素。

If I understand jQuery's contains() function correctly, it seems like the correct tool for the job.

如果我正确理解 jQuery 的 contains() 函数,它似乎是完成这项工作的正确工具。

Unfortunately, since the page I'll be running the UserScript on does not use jQuery, I can't use :contains(). Any of you lovely people know what the native way to do this is?

不幸的是,由于我将在其上运行 UserScript 的页面不使用 jQuery,因此我无法使用 :contains()。你们中的任何一个可爱的人都知道这样做的本地方式是什么吗?

http://codepen.io/coulbourne/pen/olerh

http://codepen.io/coulbourne/pen/olerh

回答by elclanrs

This should do in modern browsers:

这应该在现代浏览器中执行:

function contains(selector, text) {
  var elements = document.querySelectorAll(selector);
  return [].filter.call(elements, function(element){
    return RegExp(text).test(element.textContent);
  });
}

Then use it like so:

然后像这样使用它:

contains('p', 'world'); // find "p" that contain "world"
contains('p', /^world/); // find "p" that start with "world"
contains('p', /world$/i); // find "p" that end with "world", case-insensitive
...

回答by Claudio Redi

If you want to implement containsmethod exaclty as jQuery does, this is what you need to have

如果你想像containsjQuery 一样实现方法 exaclty,这就是你需要的

function contains(elem, text) {
    return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
}

function getText(elem) {
    var node,
        ret = "",
        i = 0,
        nodeType = elem.nodeType;

    if ( !nodeType ) {
        // If no nodeType, this is expected to be an array
        for ( ; (node = elem[i]); i++ ) {
            // Do not traverse comment nodes
            ret += getText( node );
        }
    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
        // Use textContent for elements
        // innerText usage removed for consistency of new lines (see #11153)
        if ( typeof elem.textContent === "string" ) {
            return elem.textContent;
        } else {
            // Traverse its children
            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                ret += getText( elem );
            }
        }
    } else if ( nodeType === 3 || nodeType === 4 ) {
        return elem.nodeValue;
    }
    // Do not include comment or processing instruction nodes

    return ret;
};

SOURCE: Sizzle.js

来源:Sizzle.js

回答by Elad Meidar

Well, jQuery comes equipped with a DOM traversing engine that operates a lot better than the one i'm about to show you, but it will do the trick.

嗯,jQuery 配备了一个 DOM 遍历引擎,它的运行效果比我将要向您展示的要好得多,但它可以解决问题。

var items = document.getElementsByTagName("*");
for (var i = 0; i < items.length; i++) {
  if (items[i].innerHTML.indexOf("word") != -1) { 
    // Do your magic
  }
}

Wrap it in a function if you will, but i would strongly recommend to use jQuery's implementation.

如果愿意,可以将它包装在一个函数中,但我强烈建议使用 jQuery 的实现。

回答by avalanche1

This is the modern approach

这是现代方法

function get_nodes_containing_text(selector, text) {
    const elements = [...document.querySelectorAll(selector)];

    return elements.filter(
      (element) =>
        element.childNodes[0]
        && element.childNodes[0].nodeValue
        && RegExp(text, "u").test(element.childNodes[0].nodeValue.trim())
    );
  }

回答by br.

Super modern one-line approach with optional chaining operator

带有可选链操作符的超现代单线方法

[...document.querySelectorAll('*')].filter(element => element.childNodes?.[0]?.nodeValue?.match('?'));

And better way is to search in all child nodes

更好的方法是在所有子节点中搜索

[...document.querySelectorAll("*")].filter(e => e.childNodes && [...e.childNodes].find(n => n.nodeValue?.match("?")))