如何按类名获取子元素?

spy*_*g63 105 javascript yui

我正在尝试获得具有class = 4的子span.这是一个示例元素:

<div id="test">
 <span class="one"></span>
 <span class="two"></span>
 <span class="three"></span>
 <span class="four"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

我可用的工具是JS和YUI2.我可以这样做:

doc = document.getElementById('test');
notes = doc.getElementsByClassName('four');

//or

doc = YAHOO.util.Dom.get('#test');
notes = doc.getElementsByClassName('four');
Run Code Online (Sandbox Code Playgroud)

这些在IE中不起作用.我得到一个错误,对象(doc)不支持此方法或属性(getElementsByClassName).我已经尝试了一些getElementsByClassName的跨浏览器实现的例子,但是我无法使它们工作并且仍然有错误.

我认为我需要的是一个跨浏览器getElementsByClassName或者我需要使用doc.getElementsByTagName('span')并循环直到我找到第4类.我不知道如何做到这一点.

小智 85

使用querySelector和querySelectorAll

var testContainer = document.querySelector('#test');
var fourChildNode = testContainer.querySelector('.four');
Run Code Online (Sandbox Code Playgroud)

IE9和上层

;)

  • @SUM1 [如果你不关心IE](https://caniuse.com/mdn-css_selectors_scope),你可以使用CSS伪元素[`:scope`](https://developer.mozilla.org/ en-US/docs/Web/CSS/:scope) 检查直接后代,如下所示: `testContainer.querySelector(':scope &gt; .four')` (7认同)
  • 这会检查所有后代,而不仅仅是孩子。 (4认同)
  • IE9 +或任何现代浏览器;)https://caniuse.com/#feat=queryselector (2认同)
  • 为了获得所有的子节点,我们需要使用 ``var fourChildNode = testContainer.querySelectorAll('.four');``` (2认同)

Joã*_*lva 78

使用doc.childNodes通过每个迭代span,然后筛选其一个className等于4:

var doc = document.getElementById("test");
var notes = null;
for (var i = 0; i < doc.childNodes.length; i++) {
    if (doc.childNodes[i].className == "4") {
      notes = doc.childNodes[i];
      break;
    }        
}
Run Code Online (Sandbox Code Playgroud)

  • 如果element有多个类,则此代码不起作用.例如:如果您正在寻找具有"一个"类的元素,并且您的元素具有"一二三"类,则此函数将找不到它们. (5认同)
  • @FranVerona只是出于好奇,不会简单的"indexOf('className')> -1"解决多类问题? (2认同)
  • @JamesPoulose,它*不会*.考虑将元素设置为两个类:小而大.thatElement.className将返回一个等于"small larger"的String.如果你正在寻找一个名为big'relement.className.indexOf("big")的类会产生不等于负1的东西,尽管它实际上并不是该类的一部分.如果你对你的类名有100%的控制权,那么这样的修复就可以了,它只是不能保证,特别是当你编写的代码与你无法完全控制的代码交互时. (2认同)

Aug*_*ner 43

接受的答案只检查直接的孩子.通常我们会寻找具有该类名的任何后代.

此外,有时我们希望任何包含 className的子项.

例如:<div class="img square"></div>应匹配className"img"上的搜索,即使它的确切 className不是"img".

以下是这两个问题的解决方案:

使用类查找后代元素的第一个实例 className

   function findFirstChildByClass(element, className) {
        var foundElement = null, found;
        function recurse(element, className, found) {
            for (var i = 0; i < element.childNodes.length && !found; i++) {
                var el = element.childNodes[i];
                var classes = el.className != undefined? el.className.split(" ") : [];
                for (var j = 0, jl = classes.length; j < jl; j++) {
                    if (classes[j] == className) {
                        found = true;
                        foundElement = element.childNodes[i];
                        break;
                    }
                }
                if(found)
                    break;
                recurse(element.childNodes[i], className, found);
            }
        }
        recurse(element, className, false);
        return foundElement;
    }
Run Code Online (Sandbox Code Playgroud)

  • 仔.你的评论是必要的.很高兴我帮助了其他13个人(像我一样)经常寻找类似的答案来解决他们相似但可能更复杂或更普遍的问题. (12认同)
  • 不.我*不要*想要所有的后代,只是孩子喜欢问的问题. (6认同)
  • tnx,我认为这个答案适合更多用例 (3认同)

Ham*_*oun 25

使用 element.querySelector()。让我们假设: 'myElement' 是您已经拥有的父元素。'sonClassName' 是您正在寻找的孩子的班级。

let child = myElement.querySelector('.sonClassName');
Run Code Online (Sandbox Code Playgroud)

更多信息,请访问:https : //developer.mozilla.org/en-US/docs/Web/API/Element/querySelector

  • 但是你必须在类名querySelector('.sonClassName')旁边添加点,否则它会处理它,因为sonClassName是标签名而不是类名 (2认同)

Bil*_*ard 13

现代解决方案

const context = document.getElementById('context');
const selected = context.querySelectorAll(':scope > div');
Run Code Online (Sandbox Code Playgroud)

文件


小智 8

对我而言,似乎你想要第四个跨度.如果是这样,你可以这样做:

document.getElementById("test").childNodes[3]
Run Code Online (Sandbox Code Playgroud)

要么

document.getElementById("test").getElementsByTagName("span")[3]
Run Code Online (Sandbox Code Playgroud)

最后一个确保没有任何隐藏的节点可以搞砸它.


Kor*_*lum 7

你可以尝试:

notes = doc.querySelectorAll('.4');
Run Code Online (Sandbox Code Playgroud)

要么

notes = doc.getElementsByTagName('*');
for (var i = 0; i < notes.length; i++) { 
    if (notes[i].getAttribute('class') == '4') {
    }
}
Run Code Online (Sandbox Code Playgroud)


Guf*_*ffa 5

使用 id 的名称,前面getElementById没有#符号。然后,您可以使用 获取span子节点getElementsByTagName,并遍历它们以找到具有正确类的节点:

var doc = document.getElementById('test');

var c = doc.getElementsByTagName('span');

var e = null;
for (var i = 0; i < c.length; i++) {
    if (c[i].className == '4') {
        e = c[i];
        break;
    }
}

if (e != null) {
    alert(e.innerHTML);
}
Run Code Online (Sandbox Code Playgroud)

演示:http : //jsfiddle.net/Guffa/xB62U/


Ori*_*iol 5

但请注意,旧浏览器不支持getElementsByClassName.

然后,你可以做

function getElementsByClassName(c,el){
    if(typeof el=='string'){el=document.getElementById(el);}
    if(!el){el=document;}
    if(el.getElementsByClassName){return el.getElementsByClassName(c);}
    var arr=[],
        allEls=el.getElementsByTagName('*');
    for(var i=0;i<allEls.length;i++){
        if(allEls[i].className.split(' ').indexOf(c)>-1){arr.push(allEls[i])}
    }
    return arr;
}
getElementsByClassName('4','test')[0];
Run Code Online (Sandbox Code Playgroud)

看起来它有效,但请注意 HTML 类

  • 必须以字母开头:AZ 或 az
  • 后面可以跟字母 (A-Za-z)、数字 (0-9)、连字符 ("-") 和下划线 ("_")