209

我正在尝试获取具有类 = 4 的子跨度。这是一个示例元素:

<div id="test">
 <span class="one"></span>
 <span class="two"></span>
 <span class="three"></span>
 <span class="four"></span>
</div>

我可用的工具是 JS 和 YUI2。我可以做这样的事情:

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

//or

doc = YAHOO.util.Dom.get('#test');
notes = doc.getElementsByClassName('four');

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

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

4

21 回答 21

267

使用 querySelector 和 querySelectorAll

var testContainer = document.querySelector('#test');
var fourChildNode = testContainer.querySelector('.four');

IE9及以上

于 2018-03-15T11:05:16.250 回答
117

用于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;
    }        
}

​</p>

于 2012-08-28T20:10:26.357 回答
50

接受的答案只检查直系子女。很多时候,我们正在寻找具有该类名的任何后代。

此外,有时我们想要任何包含类名的孩子。

例如:<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;
    }
于 2014-08-20T21:31:11.547 回答
29

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

let child = myElement.querySelector('.sonClassName');

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

于 2019-08-29T09:39:49.910 回答
14

现代解决方案

const context = document.getElementById('context');
const selected = context.querySelectorAll(':scope > div');

文件

于 2020-06-20T17:56:48.720 回答
12

你可以试试:

notes = doc.querySelectorAll('.4');

或者

notes = doc.getElementsByTagName('*');
for (var i = 0; i < notes.length; i++) { 
    if (notes[i].getAttribute('class') == '4') {
    }
}
于 2012-08-28T20:22:44.173 回答
8

对我来说,您似乎想要第四个跨度。如果是这样,您可以这样做:

document.getElementById("test").childNodes[3]

或者

document.getElementById("test").getElementsByTagName("span")[3]

最后一个确保没有任何隐藏节点可能会搞砸它。

于 2012-08-28T20:26:43.297 回答
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);
}

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

于 2012-08-28T20:13:11.890 回答
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];

它似乎有效,但请注意 HTML 类

  • 必须以字母开头:AZ 或 az
  • 后面可以跟字母 (A-Za-z)、数字 (0-9)、连字符 ("-") 和下划线 ("_")
于 2012-08-28T20:24:02.667 回答
3

在我看来,每次可以时,都应该使用 Array 及其方法。它们比遍历整个 DOM / 包装器或将东西推入空数组要快得多。此处介绍的大多数解决方案都可以称为 Naive,如此处所述(btw 很棒的文章):

https://medium.com/@chuckdries/traversing-the-dom-with-filter-map-and-arrow-functions-1417d326d2bc

我的解决方案:(Codepen 上的实时预览:https ://codepen.io/Nikolaus91/pen/wEGEYe )

const wrapper = document.getElementById('test') // take a wrapper by ID -> fastest
const itemsArray = Array.from(wrapper.children) // make Array from his children

const pickOne = itemsArray.map(item => { // loop over his children using .map() --> see MDN for more
   if(item.classList.contains('four')) // we place a test where we determine our choice
     item.classList.add('the-chosen-one') // your code here
})
于 2018-08-27T15:26:00.310 回答
3

使用查询选择器

var doc=document.getElementById("test");
console.log(doc.querySelector('.two').innerHTML)
<div id="test">
 <span class="one"></span>
 <span class="two">two</span>
 <span class="three"></span>
 <span class="four"></span>
</div>
使用 querySelectorAll

var doc=document.getElementById("test");
console.log(doc.querySelectorAll('*')[1].innerHTML)
<div id="test">
 <span class="one"></span>
 <span class="two">two</span>
 <span class="three"></span>
 <span class="four"></span>
</div>

使用 getElementsByTagNames

var doc=document.getElementById("test");
console.log(doc.getElementsByTagName("SPAN")[1].innerHTML);
<div id="test">
 <span class="one"></span>
 <span class="two">two</span>
 <span class="three"></span>
 <span class="four"></span>
</div>
<span>ss</span>

使用 getElementsByClassName

var doc=document.getElementById("test");
console.log(doc.getElementsByClassName('two')[0].innerHTML)
<div id="test">
 <span class="one"></span>
 <span class="two">two</span>
 <span class="three"></span>
 <span class="four"></span>
</div>

于 2021-02-02T10:44:07.917 回答
2

我将使用 jquery 执行此操作的方式是这样的..

var targetchild = $("#test").children().find("span.four");

于 2013-07-17T06:22:48.377 回答
2

您可以通过添加下面的行来获取父类。如果你有一个 id,使用getElementById. 尽管如此,

var parentNode = document.getElementsByClassName("progress__container")[0];

然后你可以querySelectorAll在父级上使用<div>来获取所有匹配div的类.progress__marker

var progressNodes = progressContainer.querySelectorAll('.progress__marker');

querySelectorAll将获取每个divprogress__marker

于 2020-02-20T07:26:57.770 回答
2

其他方式

const result = [...(parentElement.children)].find(child => {
  return child.classList.contains('some-class-name');
});

首先,我们将 的元素展开NodeList以将其转换为一个,Array以便我们可以使用该find()方法。最后,find()将返回其classList属性包含给定类名的第一个元素。

于 2021-10-15T02:29:27.060 回答
1

这是一个相对简单的递归解决方案。我认为广度优先搜索在这里是合适的。这将返回与找到的类匹配的第一个元素。

function getDescendantWithClass(element, clName) {
    var children = element.childNodes;
    for (var i = 0; i < children.length; i++) {
        if (children[i].className &&
            children[i].className.split(' ').indexOf(clName) >= 0) {
            return children[i];
         }
     }
     for (var i = 0; i < children.length; i++) {
         var match = getDescendantWithClass(children[i], clName);
         if (match !== null) {
             return match;
         }
     }
     return null;
}
于 2014-10-09T14:11:31.913 回答
1

我知道这个问题已经有几年的历史了,对此已有一些答案,但我想我会添加我的解决方案,以防万一它对任何人有帮助。它与user2795540给出的答案相同,涉及一个数组迭代器。

如果您只是想获得第一个拥有four该类的孩子,那么您可以使用find数组迭代器。你的浏览器需要能够支持 ES6,或者你可以使用 Babel 将你的 JS 编译成所有浏览器都支持的东西。如果没有 polyfill,IE 将不支持此功能

使用您在问题中提供的相同详细信息,它可能看起来像这样:

const parentNode = document.getElementById('test');
const childNode = Array.from(parentNode.childNodes).find(({ className }) => className === 'four');

上述解决方案将返回您要定位的节点并将其存储在childNode变量中。

您可以在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find找到有关find数组迭代器的更多信息

于 2020-09-30T07:28:18.610 回答
1

我相信这会最好地回答你的问题

document.querySelector('* > span.four')

这将匹配它找到的第一个子元素(任何父元素),它是一个跨度并且还设置了一个类“四”

但是,由于在您的示例中,您还有一个可以通过 id 检索的父元素,因此您也可以使用它来代替

document.querySelector('#test > span.four')

如果您将父元素保存在示例中的变量中,并且您希望搜索该元素的子树,那么:scope正如 Billizzard 已经提到的,使用 可能是您的最佳选择

doc.querySelector(':scope > span.four');

额外的一点:如果您要查找的子元素不是直接子后代,而是在子树更下方的某个位置,您实际上可以省略>类似这样

document.querySelector('#test span.four')
于 2021-04-02T17:59:40.020 回答
0

2018 年 6 月对 ES6 的更新

    const doc = document.getElementById('test');
    let notes = null;
    for (const value of doc) {
        if (value.className === '4') {
            notes = value;
            break;
        }    
    }
于 2018-06-15T00:10:05.990 回答
-2

YUI2 有一个跨浏览器的实现getElementsByClassName

于 2012-08-28T20:33:56.197 回答
-3

这是我使用 YUI 选择器的方法。感谢 Hank Gay 的建议。

notes = YAHOO.util.Dom.getElementsByClassName('four','span','test');

其中四 = 类名,跨度 = 元素类型/标签名称,测试 = 父 ID。

于 2012-08-28T21:08:09.487 回答
-4

YAHOO.util.Dom.getElementsByClassName()这里使用。

于 2012-08-28T21:26:10.040 回答