有没有办法getElementBy文本内容?

时间:2014-02-14 22:52:53

标签: javascript click getelementbyid tampermonkey

我遇到了一个问题我已经被困了一段时间,抱歉发布了一些垃圾论坛。

我有什么方法可以通过它的文字内容获得元素吗?这是一个例子:

<span id="result_5_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Navy</span>

我试图通过文本内容获取元素,即&#39;项目|阳极氧化海军&#39;。 是否可以做类似的事情:

function getelem {
    var item = document.getElementsByTextContent('Item | Anodized Navy');

    item[0].click();
}

我知道这不存在,但它只是让你明白了。此外,我不能使用ID或类名,我无法更改元素的HTML代码,因此必须使用文本内容,我不会看到另一种方式。

我非常感谢任何反馈,

谢谢!

5 个答案:

答案 0 :(得分:3)

即使jQuery公开:contains伪选择器,最好先使用类来限制结果:

$('.market_listing_item_name:contains("Item | Anodized Navy")')

缩小要搜索的初始标记集可以提高性能,否则将考虑所有标记;此外,重叠标签也会匹配。

在更现代的浏览器上,您可以根据this answer

来考虑这一点
function contains(selector, text) {
    var elements = document.querySelectorAll(selector);
    return [].filter.call(elements, function(element) {
        var contents = element.textContent || element.innerText || '';
        return contents.indexOf(text) != -1;
    });
}

var items = contains('.market_listing_item_name', 'Item | Anodized Navy')

items[0] && items[0].click();

答案 1 :(得分:2)

好吧,既然您使用标记了问题,则可以使用:contains选择器:

var item = $(':contains(Item | Anodized Navy)');

但请注意,这将返回包含该文本的每个元素,包括span和span的所有父元素。如果你想得到最内在的元素(假设只有一个),那就得到最后一项,如下:

var item = $(':contains(Item | Anodized Navy)').last();

要使用jQuery执行等效的而不使用,您必须实现这样的函数:

function getElementsByText(text) {
    var spans = document.getElementsByTagName('span'),
        results = [];
    for(var i = 0; i < spans.length; i++) {
        var content = spans[i].textContent || spans[i].innerText || '';
        if (content.indexOf(text) != -1)
            results.push(spans[i]);
    }
    return results;
}

或者可能是这样,具体取决于您的需求:

function getElementsByText(text) {
    function rec(ele, arr)
    {
        if (ele.childNodes.length > 0) 
            for (var i = 0; i < ele.childNodes.length; i++) 
                rec(ele.childNodes[i], arr);
        else if (ele.nodeType == Node.TEXT_NODE && 
                 ele.nodeValue.indexOf(text) != -1) 
            arr.push(ele.parentNode);
        return arr;
    }
    return rec(document.body, []);
}

然后像这样调用这个函数:

var item = getElementsByText('Item | Anodized Navy');

另请注意,在您的代码中,getelem需要在函数名后面加(),如下所示:

function getelem() {
    var item = getElementsByText('Item | Anodized Navy');
    ...
}

答案 2 :(得分:2)

你想要这样的东西

HTML

<span id="result_5_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Blue</span>
<span id="result_6_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Navy</span>
<span id="result_7_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Red</span>
<span id="result_8_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Green</span>
<span id="result_9_name" class="market_listing_item_name" style="color: #FFD700;">Item | Anodized Navy</span>

的Javascript

function walkTheDOM(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walkTheDOM(node, func);
        node = node.nextSibling;
    }
}

function getElementsByText(node, text) {
    var results = [];

    walkTheDOM(node, function (currentNode) {
        if (currentNode.nodeType === 3 && currentNode.nodeValue === text) {
            results.push(currentNode.parentNode);
        }
    });

    return results;
}

console.log(getElementsByText(document, 'Item | Anodized Navy'));

输出

[span#result_6_name.market_listing_item_name, span#result_9_name.market_listing_item_name]

jsFiddle

附加1 ,正如我们所讨论的treeWalker

function getElementsByText(node, text) {
    var results = [],
        treeWalker = document.createTreeWalker(
        node,
        NodeFilter.SHOW_TEXT, {
            acceptNode: function (node) {
                return NodeFilter.FILTER_ACCEPT;
            }
        }, false);

    while (treeWalker.nextNode()) {
        if (treeWalker.currentNode.nodeValue === text) {
            results.push(treeWalker.currentNode.parentNode);
        }
    }

    return results;
}

console.log(getElementsByText(document, 'Item | Anodized Navy'));

jsFiddle

附加2 ,我们谈到了getElementsByTagName('*')

function getElementsByText(node, text) {
    var results = [],
        tags = node.getElementsByTagName('*'),
        tagsLength = tags.length,
        tagsIndex,
        currentTag,
        childNodes,
        childNodesLength,
        ChildNodesIndex,
        currentChildNode;

    for (tagsIndex = 0; tagsIndex < tagsLength; tagsIndex += 1) {
        currentTag = tags[tagsIndex];
        childNodes = currentTag.childNodes;
        childNodesLength = childNodes.length;
        for (ChildNodesIndex = 0; ChildNodesIndex < childNodesLength; ChildNodesIndex += 1) {
            currentChildNode = childNodes[ChildNodesIndex];
            if (currentChildNode.nodeType === 3 && currentChildNode.nodeValue === text) {
                results.push(currentTag);
            }
        }
    }

    return results;
}

console.log(getElementsByText(document, 'Item | Anodized Navy'));

jsFiddle

请注意,这些解决方案是相同的,但它们与此处给出的所有contains解决方案不同。因为这些解决方案实际上为您提供了具有匹配文本节点作为子节点的节点。我使用的简单标记并没有证明这一点,但是当你的标记高度嵌套时,你很快就会注意到它的区别。

最后这是这3个解决方案的jsPerf

答案 3 :(得分:1)

也许我迟迟没有回答这个问题,但是我没有看到用JQuery标记的问题,所以这里是一个纯粹的JavaScript解决方案:

var myID = getElementsByTextContent('Item | Anodized Navy');

function getElementsByTextContent (elText){
    var spanID;
    var allSpans = document.getElementsByTagName("span"); 
    for (var i = 0; i < allSpans.length; i++) { 
        var spanText = allSpans[i].innerHTML;
        if(spanText == elText ){
            spanID = allSpans[i].id;
        }
    }
    return spanID;
}

答案 4 :(得分:0)

您可以简单地使用Jquery的:contains()

如果要选择包含文本“mytext”的所有范围,请使用

var elements=$('span:contains("mytext"));

如果我帮助你,请标记为答案。

谢谢:)