如何通过类名获得子元素?

我试图得到class = 4的子span。下面是一个示例元素:

<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。但我不知道该怎么做。

552928 次浏览

使用doc.childNodes遍历每个span,然后过滤出className等于4span:

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

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

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/

你可以试试:

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

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

但是要注意旧的浏览器不支持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类

  • 必须以字母开头:a-z还是a-z
  • 后面可以跟着字母(A-Za-z)、数字(0-9)、连字符(-)和下划线(_)。

在我看来,你想要的是第四张成的空间。如果是这样,你可以这样做:

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

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

最后一个方法确保没有任何隐藏的节点会把它搞砸。

下面是我如何使用YUI选择器做到这一点。感谢汉克·盖伊的建议。

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

其中four = classname, span =元素类型/标签名,test =父id。

使用在这里中的YAHOO.util.Dom.getElementsByClassName()

我将使用jquery这样做的方式是这样的..

Var targetedchild = $("#test").children().find("span.four");

接受的答案只检查直系子女。通常情况下,我们正在寻找具有该类名的任何后代。

同样,有时我们希望任何包含为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;
}

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

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

使用querySelector和querySelectorAll

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

IE9及以上版本

2018年6月更新至ES6

    const doc = document.getElementById('test');
let notes = null;
for (const value of doc) {
if (value.className === '4') {
notes = value;
break;
}
}

在我看来,只要可以,就应该使用Array及其方法。它们比遍历整个DOM /包装器或将东西推入空数组快得多。这里提出的大多数解决方案都可以调用Naive(顺便说一句,这是一篇很棒的文章):

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
})
< p >使用element.querySelector()。 让我们假设: 'myElement'是你已经拥有的父元素。 'sonClassName'是你要查找的child的类
let child = myElement.querySelector('.sonClassName');

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

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

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

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

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

querySelectorAll将获取类为progress__marker的每个div

现代的解决方案

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

文档

我知道这个问题已经存在几年了,也有一些答案,但我想我会补充我的解决方案,以防它能帮助到任何人。它与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数组迭代器的信息

使用querySelector

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 < / p >

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>

使用getelementsbytagname

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>

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

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

这将匹配它发现的第一个子元素(任何父元素),它是一个span,也有一个类"four"开始吧

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

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

如果你有一个父元素保存在一个变量中,就像在你的例子中,你希望搜索该元素的子树,使用:scope,正如台球已经提到的,可能是你最好的选择

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

额外提示:如果你要查找的子元素不是直接的子代元素,而是在子树的更下方的某个地方,你实际上可以像这样省略>

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

另一种方式

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

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