按类和 ID 获取元素内的元素 - JavaScript

IT技术 javascript getelementbyid getelementsbyclassname
2021-02-20 00:02:11

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

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

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

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

6个回答

好吧,首先您需要选择具有类似函数的元素getElementById

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

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

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

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>

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

你可以这样做:

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. 这将返回一个类似数组的 nodeList,因此您引用该 nodeList 中的第一项
  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 让事情变得如此简单。
2021-05-02 00:02:11

如果这需要在 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。jQuery 肯定是一个选项,但上面的代码也是如此。
2021-04-22 00:02:11
@Ӫ_._Ӫ ...好奇你看到了什么...因为我没有看到它。
2021-04-22 00:02:11
var i = 0, var child = fooDiv.childNodes[i]是无效的。i <= fooDiv.childNodes没有意义。childNode.className.test("bar")没有childNode变量,字符串也没有test()方法。
2021-04-22 00:02:11
getElementsByClassName也不能在 IE8 中工作,但您可以querySelectorAll在它的位置使用(几乎无论如何)。
2021-04-24 00:02:11
是的,我的意思是该评论支持您的回答,但同时也指出可以qSA在 shim 中使用,以便您仍然可以在 IE8 中使用本机代码。尽管仔细研究了您的解决方案,但仍有一些问题需要修复。
2021-05-08 00:02:11

最简单的方法是:

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}]`);
}

递归函数:

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; }
2021-05-01 00:02:11