【问题标题】:Get element inside element by class and ID - JavaScript通过类和 ID 获取元素内的元素 - JavaScript
【发布时间】:2011-12-10 13:13:35
【问题描述】:

好吧,我之前涉足过 JavaScript,但我写过的最有用的东西是 CSS 样式切换器。所以我对此有些陌生。假设我有这样的 HTML 代码:

<div id="foo">
    <div class="bar">
        Hello world!
    </div>
</div>

如何将Hello world! 更改为Goodbye world!

我知道document.getElementsByClassNamedocument.getElementById 的工作原理,但我想更具体一些。抱歉,如果之前有人问过这个问题。

【问题讨论】:

    标签: javascript getelementbyid getelementsbyclassname


    【解决方案1】:

    嗯,首先你需要用getElementById之类的函数来选择元素。

    var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];
    

    getElementById 只返回一个节点,但getElementsByClassName 返回一个节点列表。由于只有一个具有该类名的元素(据我所知),因此您只需获取第一个元素(这就是 [0] 的用途——它就像一个数组)。

    然后,您可以使用.textContent 更改html。

    targetDiv.textContent = "Goodbye world!";
    

    var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];
    targetDiv.textContent = "Goodbye world!";
    <div id="foo">
        <div class="bar">
            Hello world!
        </div>
    </div>

    【讨论】:

    • 在这种情况下不需要通过 ID 获取父级。 document.getElementsByClassName 可以正常工作。
    • @rvighne OP 的确切要求是他“想要更具体”。问这个问题的人是在问他如何才能更具体地遍历 DOM 树。 getElementByClassName 的使用并不是一个混淆点,但我可以看到有人可能很容易认为我在必要时指出了两者。他们不是。如果您只想定位给定 ID 的特定节点下的某个类的元素,而不是不同节点下的同一类的元素,这就是您将使用的。
    • 为了复制/粘贴编码器的安全利益,编辑此答案并将 .innerHtml 更改为 .textContent 可能会很好。
    【解决方案2】:

    你可以这样做:

    var list = document.getElementById("foo").getElementsByClassName("bar");
    if (list && list.length > 0) {
        list[0].innerHTML = "Goodbye world!";
    }
    

    或者,如果你想用更少的错误检查和更简洁的方式来完成它,可以像这样在一行中完成:

    document.getElementById("foo").getElementsByClassName("bar")[0].innerHTML = "Goodbye world!";
    

    解释:

    1. 您将获得带有id="foo" 的元素。
    2. 然后您会找到包含在该对象中的具有class="bar" 的对象。
    3. 这会返回一个类似数组的节点列表,因此您引用该节点列表中的第一项
    4. 然后您可以设置该项目的innerHTML 以更改其内容。

    警告:一些旧版浏览器不支持getElementsByClassName(例如旧版 IE)。如果缺少该功能,可以将其填充到位。


    这是我建议使用具有内置 CSS3 选择器支持的库的地方,而不是自己担心浏览器兼容性(让其他人完成所有工作)。如果你只想要一个库来做到这一点,那么 Sizzle 会很好用。在 Sizzle 中,这将是这样完成的:

    Sizzle("#foo .bar")[0].innerHTML = "Goodbye world!";
    

    jQuery 内置了 Sizzle 库,在 jQuery 中,它是:

    $("#foo .bar").html("Goodbye world!");
    

    【讨论】:

    • 谢谢,我在使用 document.getElementBy* 时遇到了问题。 jQuery 让事情变得如此简单。
    【解决方案3】:

    如果这需要在 IE 7 或更低版本中工作,您需要记住 getElementsByClassName 并非在所有浏览器中都存在。因此,您可以创建自己的 getElementsByClassName,也可以试试这个。

    var fooDiv = document.getElementById("foo");
    
    for (var i = 0, childNode; i <= fooDiv.childNodes.length; i ++) {
        childNode = fooDiv.childNodes[i];
        if (/bar/.test(childNode.className)) {
            childNode.innerHTML = "Goodbye world!";
        }
    }
    

    【讨论】:

    • getElementsByClassName 在 IE8 中也不起作用,但您可以使用 querySelectorAll 代替它(无论如何)。
    • @Ӫ_._Ӫ ...大声笑...您是对的,但您只是进一步证明了我的回答。如果您的页面需要跨多个浏览器运行,则不能依赖 getElementsByClassName。 jQuery 肯定是一个选项,但上面的代码也是。
    • 是的,我的意思是支持您的回答的评论,但也指出可以在 shim 中使用 qSA,以便您仍然可以在 IE8 中使用本机代码。尽管仔细研究了您的解决方案,但您仍有一些问题需要解决。
    • @Ӫ_._Ӫ ...好奇你看到了什么...因为我没有看到它。
    • var i = 0, var child = fooDiv.childNodes[i] 无效。 i &lt;= fooDiv.childNodes 真的没有意义。 childNode.className.test("bar") 没有childNode 变量,字符串也没有test() 方法。
    【解决方案4】:

    最简单的方法是:

    function findChild(idOfElement, idOfChild){
      let element = document.getElementById(idOfElement);
      return element.querySelector('[id=' + idOfChild + ']');
    }
    

    或更好的可读性:

    findChild = (idOfElement, idOfChild) => {
        let element = document.getElementById(idOfElement);
        return element.querySelector(`[id=${idOfChild}]`);
    }
    

    【讨论】:

      【解决方案5】:

      递归函数:

      function getElementInsideElement(baseElement, wantedElementID) {
          var elementToReturn;
          for (var i = 0; i < baseElement.childNodes.length; i++) {
              elementToReturn = baseElement.childNodes[i];
              if (elementToReturn.id == wantedElementID) {
                  return elementToReturn;
              } else {
                  return getElementInsideElement(elementToReturn, wantedElementID);
              }
          }
      }
      

      【讨论】:

      • 上面的示例中有一个小错误。而不是立即返回 else 路径,您必须首先检查是否找到了某些东西。否则不会循环其他子节点。像这样: if(elementToReturn) { return elementToReturn; }
      【解决方案6】:

      您也可以在 DOM 元素上使用 getElementByIdgetElementsByClassName。而不仅仅是document

      var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];
      targetDiv.textContent = "Goodbye world!";
      <div id="foo">
          <div class="bar">
              Hello world!
          </div>
      </div>

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      【解决方案7】:

      您不应该使用 document.getElementByID,因为它仅适用于客户端控制哪些 id 是固定的。您应该使用 jquery,如下例所示。

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>                                                                                                             
      <div id="foo">
         <div class="bar"> 
                Hello world!
           </div>
      </div>
      

      使用这个:

      $("[id^='foo']").find("[class^='bar']")
      
      // do not forget to add script tags as above
      

      如果您想要任何删除编辑任何操作,那么只需添加“。”后面做操作

      【讨论】:

      • 使用热核武器杀死一头鹿是可行的,但有点矫枉过正。当 Javascript 在其基本代码中提供该功能时,使用多 kb jQuery 库来选择一个元素稍微有点矫枉过正。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 2022-11-27
      • 2019-06-11
      • 2015-09-02
      • 2013-01-16
      相关资源
      最近更新 更多