【问题标题】:How to get element by innerText如何通过innerText获取元素
【发布时间】:2011-04-18 07:36:47
【问题描述】:

如果我知道文本标签包含什么,如何在 html 页面中获取标签。 例如:

<a ...>SearchingText</a>

【问题讨论】:

标签: javascript innertext


【解决方案1】:

您可以使用 xpath 来完成此操作

var xpath = "//a[text()='SearchingText']";
var matchingElement = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

您还可以使用此 xpath 搜索包含某些文本的元素:

var xpath = "//a[contains(text(),'Searching')]";

【讨论】:

  • 这应该是最佳答案。 XPath 可以做更多的事情,比如按属性值选择节点,选择节点集...简单介绍:w3schools.com/xml/xpath_syntax.asp
  • 问题是,这个诡计的性能损失是什么
  • @vsync 我认为这将比任何其他答案都快,因为 xpath 是由浏览器提供的算法执行的,而不是像这里的所有其他答案一样在 javascript 中执行。这是一个有趣的问题。
  • IE 浏览器中显示为 Document.evaluate() isn't supposed
  • @Daniel 您需要将调用更改为:js var matchingElementSet = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while(element = result.iterateNext()) { // do something with each element } developer.mozilla.org/en-US/docs/Web/API/XPathResult/…
【解决方案2】:

您必须手动遍历。

var aTags = document.getElementsByTagName("a");
var searchText = "SearchingText";
var found;

for (var i = 0; i < aTags.length; i++) {
  if (aTags[i].textContent == searchText) {
    found = aTags[i];
    break;
  }
}

// Use `found`.

【讨论】:

  • @AutoSponge 实际上 innerHTML 是标准的。 innerText 在 FF 中不起作用
  • 更新了示例, textContent 在这种情况下可能是您想要的。谢谢,伙计们:)
  • @AugustLilleaas,i &lt; il 怎么了?这是在做什么?
  • 我发现如果您有 搜索文本,此方法可能会返回外部跨度而不是内部跨度。
  • 不,这个问题是关于 JavaScript 和 HTML,而不是 Java
【解决方案3】:

使用目前可用的最现代的语法,它可以像这样非常干净地完成:

for (const a of document.querySelectorAll("a")) {
  if (a.textContent.includes("your search term")) {
    console.log(a.textContent)
  }
}

或者使用单独的过滤器:

[...document.querySelectorAll("a")]
   .filter(a => a.textContent.includes("your search term"))
   .forEach(a => console.log(a.textContent))

当然,旧版浏览器不会处理此问题,但如果需要旧版支持,您可以使用转译器。

【讨论】:

  • 比为 xpath 学习一种新的解析语言要好得多,而且更容易迭代。
【解决方案4】:

你可以使用jQuery:contains() Selector

var element = $( "a:contains('SearchingText')" );

【讨论】:

  • 我得到:Error: &lt;![EX[["Tried to get element with id of \"%s\" but it is not present on the page","a:contains('SearchingText')"]]]&gt; TAAL[1] 虽然我的元素中有“SearchingText”。
【解决方案5】:

function findByTextContent(needle, haystack, precise) {
  // needle: String, the string to be found within the elements.
  // haystack: String, a selector to be passed to document.querySelectorAll(),
  //           NodeList, Array - to be iterated over within the function:
  // precise: Boolean, true - searches for that precise string, surrounded by
  //                          word-breaks,
  //                   false - searches for the string occurring anywhere
  var elems;

  // no haystack we quit here, to avoid having to search
  // the entire document:
  if (!haystack) {
    return false;
  }
  // if haystack is a string, we pass it to document.querySelectorAll(),
  // and turn the results into an Array:
  else if ('string' == typeof haystack) {
    elems = [].slice.call(document.querySelectorAll(haystack), 0);
  }
  // if haystack has a length property, we convert it to an Array
  // (if it's already an array, this is pointless, but not harmful):
  else if (haystack.length) {
    elems = [].slice.call(haystack, 0);
  }

  // work out whether we're looking at innerText (IE), or textContent 
  // (in most other browsers)
  var textProp = 'textContent' in document ? 'textContent' : 'innerText',
    // creating a regex depending on whether we want a precise match, or not:
    reg = precise === true ? new RegExp('\\b' + needle + '\\b') : new RegExp(needle),
    // iterating over the elems array:
    found = elems.filter(function(el) {
      // returning the elements in which the text is, or includes,
      // the needle to be found:
      return reg.test(el[textProp]);
    });
  return found.length ? found : false;;
}


findByTextContent('link', document.querySelectorAll('li'), false).forEach(function(elem) {
  elem.style.fontSize = '2em';
});

findByTextContent('link3', 'a').forEach(function(elem) {
  elem.style.color = '#f90';
});
<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

当然,还有一种更简单的方法:

var textProp = 'textContent' in document ? 'textContent' : 'innerText';

// directly converting the found 'a' elements into an Array,
// then iterating over that array with Array.prototype.forEach():
[].slice.call(document.querySelectorAll('a'), 0).forEach(function(aEl) {
  // if the text of the aEl Node contains the text 'link1':
  if (aEl[textProp].indexOf('link1') > -1) {
    // we update its style:
    aEl.style.fontSize = '2em';
    aEl.style.color = '#f90';
  }
});
<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

参考资料:

【讨论】:

    【解决方案6】:

    功能方法。返回所有匹配元素的数组并在检查时修剪周围的空格。

    function getElementsByText(str, tag = 'a') {
      return Array.prototype.slice.call(document.getElementsByTagName(tag)).filter(el => el.textContent.trim() === str.trim());
    }
    

    用法

    getElementsByText('Text here'); // second parameter is optional tag (default "a")
    

    如果您正在查看不同的标签,即跨度或按钮

    getElementsByText('Text here', 'span');
    getElementsByText('Text here', 'button');
    

    默认值 tag = 'a' 对于旧浏览器需要 Babel

    【讨论】:

    • 这是不正确的,因为它还包括所有子节点的结果。 IE。如果a 的子节点将包含str - el 将包含在getElementsByText 结果中;这是错误的。
    • @avalanche1 这取决于是否不受欢迎。即使它包含在另一个标签中,也可能需要按文本选择,即
    【解决方案7】:

    只需将您的 子字符串 传递到以下行:

    外部 HTML

    document.documentElement.outerHTML.includes('substring')
    

    内部 HTML

    document.documentElement.innerHTML.includes('substring')
    

    您可以使用它们搜索整个文档并检索包含您的搜索词的标签:

    function get_elements_by_inner(word) {
        res = []
        elems = [...document.getElementsByTagName('a')];
        elems.forEach((elem) => { 
            if(elem.outerHTML.includes(word)) {
                res.push(elem)
            }
        })
        return(res)
    }
    

    用法

    用户“T3rm1”在此页面上被提及了多少次?

    get_elements_by_inner("T3rm1").length
    

    1

    jQuery 被提及了多少次?

    get_elements_by_inner("jQuery").length
    

    3

    获取所有包含单词“Cyber​​netic”的元素:

    get_elements_by_inner("Cybernetic")
    

    【讨论】:

    • 返回真或假,但不返回元素。
    • 您可以使用真值条件遍历检索到的元素并从这些元素中获取您需要的任何内容。查看更新的答案。
    【解决方案8】:

    user1106925 获取过滤方法在

    您可以将扩展运算符替换为:

    [].slice.call(document.querySelectorAll("a"))

    以及包含a.textContent.match("your search term")的调用

    效果非常好:

    [].slice.call(document.querySelectorAll("a"))
       .filter(a => a.textContent.match("your search term"))
       .forEach(a => console.log(a.textContent))
    

    【讨论】:

    • 我喜欢这种方法。您也可以Array.from 代替[].slice.call。例如:Array.from(document.querySelectorAll('a'))
    【解决方案9】:

    与其他答案相比,我发现使用新语法的时间要短一些。所以这是我的建议:

    const callback = element => element.innerHTML == 'My research'
    
    const elements = Array.from(document.getElementsByTagName('a'))
    // [a, a, a, ...]
    
    const result = elements.filter(callback)
    
    console.log(result)
    // [a]
    

    JSfiddle.net

    【讨论】:

      【解决方案10】:

      您可以使用TreeWalker 遍历 DOM 节点,并找到包含该文本的所有文本节点,并返回其父节点:

      const findNodeByContent = (text, root = document.body) => {
        const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
      
        const nodeList = [];
      
        while (treeWalker.nextNode()) {
          const node = treeWalker.currentNode;
      
          if (node.nodeType === Node.TEXT_NODE && node.textContent.includes(text)) {
            nodeList.push(node.parentNode);
          }
        };
      
        return nodeList;
      }
      
      const result = findNodeByContent('SearchingText');
      
      console.log(result);
      &lt;a ...&gt;SearchingText&lt;/a&gt;

      【讨论】:

        【解决方案11】:

        虽然可以通过内部文本获得,但我认为您走错路了。该内部字符串是动态生成的吗?如果是这样,你可以给标签一个类或者——更好的是——当文本进入那里时的ID。如果它是静态的,那就更容易了。

        【讨论】:

          【解决方案12】:

          这样就可以了。
          返回包含text 的节点数组。

          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())
              );
            }
          

          【讨论】:

            【解决方案13】:

            我认为您需要更具体一些,以便我们为您提供帮助。

            1. 你是怎么找到这个的? Javascript? php? Perl?
            2. 您能否将 ID 属性应用于标记?

            如果文本是唯一的(或者实际上,如果不是,但你必须遍历一个数组)你可以运行一个正则表达式来找到它。使用 PHP 的 preg_match() 就可以了。

            如果您使用 Javascript 并且可以插入 ID 属性,则可以使用 getElementById('id')。然后,您可以通过 DOM 访问返回元素的属性:https://developer.mozilla.org/en/DOM/element.1

            【讨论】:

              【解决方案14】:

              我只是需要一种方法来获取包含特定文本的元素,这就是我想出的。

              使用document.getElementsByInnerText() 获取多个元素(多个元素可能具有完全相同的文本),并使用document.getElementByInnerText() 获取一个元素(第一个匹配项)。

              此外,您可以使用元素(例如 someElement.getElementByInnerText())而不是 document 来本地化搜索。

              您可能需要对其进行调整以使其跨浏览器或满足您的需求。

              我认为代码是不言自明的,所以我将保持原样。

              HTMLElement.prototype.getElementsByInnerText = function (text, escape) {
                  var nodes  = this.querySelectorAll("*");
                  var matches = [];
                  for (var i = 0; i < nodes.length; i++) {
                      if (nodes[i].innerText == text) {
                          matches.push(nodes[i]);
                      }
                  }
                  if (escape) {
                      return matches;
                  }
                  var result = [];
                  for (var i = 0; i < matches.length; i++) {
                      var filter = matches[i].getElementsByInnerText(text, true);
                      if (filter.length == 0) {
                          result.push(matches[i]);
                      }
                  }
                  return result;
              };
              document.getElementsByInnerText = HTMLElement.prototype.getElementsByInnerText;
              
              HTMLElement.prototype.getElementByInnerText = function (text) {
                  var result = this.getElementsByInnerText(text);
                  if (result.length == 0) return null;
                  return result[0];
              }
              document.getElementByInnerText = HTMLElement.prototype.getElementByInnerText;
              
              console.log(document.getElementsByInnerText("Text1"));
              console.log(document.getElementsByInnerText("Text2"));
              console.log(document.getElementsByInnerText("Text4"));
              console.log(document.getElementsByInnerText("Text6"));
              
              console.log(document.getElementByInnerText("Text1"));
              console.log(document.getElementByInnerText("Text2"));
              console.log(document.getElementByInnerText("Text4"));
              console.log(document.getElementByInnerText("Text6"));
              <table>
                  <tr>
                      <td>Text1</td>
                  </tr>
                  <tr>
                      <td>Text2</td>
                  </tr>
                  <tr>
                      <td>
                          <a href="#">Text2</a>
                      </td>
                  </tr>
                  <tr>
                      <td>
                          <a href="#"><span>Text3</span></a>
                      </td>
                  </tr>
                  <tr>
                      <td>
                          <a href="#">Special <span>Text4</span></a>
                      </td>
                  </tr>
                  <tr>
                      <td>
                          Text5
                          <a href="#">Text6</a>
                          Text7
                      </td>
                  </tr>
              </table>

              【讨论】:

                猜你喜欢
                • 2022-09-23
                • 1970-01-01
                • 2023-01-17
                • 2019-07-25
                • 2012-01-22
                • 2020-07-07
                • 2012-03-09
                • 2015-12-05
                • 2020-12-24
                相关资源
                最近更新 更多