[英]How to get child element by class name?
我正在尝试获取具有 class = 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 中不起作用。 我收到一条错误消息,指出 object (doc) 不支持此方法或属性 (getElementsByClassName)。 我已经尝试了几个跨浏览器实现 getElementsByClassName 的示例,但我无法让它们工作并且仍然出现该错误。
我想我需要的是跨浏览器 getElementsByClassName 或者我需要使用 doc.getElementsByTagName('span') 并循环直到找到 class 4。不过我不确定该怎么做。
使用 querySelector 和 querySelectorAll
var testContainer = document.querySelector('#test');
var fourChildNode = testContainer.querySelector('.four');
IE9及以上
;)
使用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;
}
}
接受的答案只检查直接的孩子。 很多时候,我们正在寻找具有该类名的任何后代。
此外,有时我们想要任何包含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;
}
使用 element.querySelector()。 让我们假设: 'myElement' 是您已经拥有的父元素。 'sonClassName' 是您正在寻找的孩子的班级。
let child = myElement.querySelector('.sonClassName');
更多信息,请访问: https : //developer.mozilla.org/en-US/docs/Web/API/Element/querySelector
你可以试试:
notes = doc.querySelectorAll('.4');
要么
notes = doc.getElementsByTagName('*');
for (var i = 0; i < notes.length; i++) {
if (notes[i].getAttribute('class') == '4') {
}
}
现代解决方案
const context = document.getElementById('context');
const selected = context.querySelectorAll(':scope > div');
对我来说,您似乎想要第四个跨度。 如果是这样,你可以这样做:
document.getElementById("test").childNodes[3]
要么
document.getElementById("test").getElementsByTagName("span")[3]
最后一个确保没有任何隐藏的节点可能会弄乱它。
使用带有getElementById
的 id 名称,在它之前没有#
符号。 然后,您可以使用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);
}
但请注意,旧浏览器不支持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 类
在我看来,每次可以时,都应该使用 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
})
我将使用 jquery 执行此操作的方式是这样的..
var targetchild = $("#test").children().find("span.four");
您可以通过添加下面的行来获取父类。 如果您有 id,则使用getElementById
会更容易。 尽管如此,
var parentNode = document.getElementsByClassName("progress__container")[0];
然后你可以在父<div>
上使用querySelectorAll
来获取所有匹配的div
类为.progress__marker
var progressNodes = progressContainer.querySelectorAll('.progress__marker');
querySelectorAll
将使用progress__marker
类获取每个div
这是一个相对简单的递归解决方案。 我认为广度优先搜索在这里是合适的。 这将返回与找到的类匹配的第一个元素。
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;
}
我知道这个问题已经有几年了,对此有一些答案,但我想我会添加我的解决方案,以防万一它对任何人都有帮助。 它与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
有关find
数组迭代器的更多信息
使用查询选择器
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>
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>
2018 年 6 月更新到 ES6
const doc = document.getElementById('test');
let notes = null;
for (const value of doc) {
if (value.className === '4') {
notes = value;
break;
}
}
我相信这会最好地回答你的问题
document.querySelector('* > span.four')
这将匹配它发现的第一个子元素(任何父元素),它是一个跨度并且还设置了一个“四”类
但是,由于在您的示例中,您还有一个可以通过 id 检索的父元素,因此您也可以使用它来代替
document.querySelector('#test > span.four')
如果您有一个父元素保存在您的示例中的变量中,并且您希望搜索该元素的子树,则使用:scope
,正如 Billizzard 已经提到的,可能是您的最佳选择
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
属性包含给定类名的第一个元素。
让 notes = document.querySelector('#test.four')
YUI2 有一个跨浏览器的getElementsByClassName
实现。
这是我使用 YUI 选择器的方法。 感谢汉克盖伊的建议。
notes = YAHOO.util.Dom.getElementsByClassName('four','span','test');
其中四 = 类名,跨度 = 元素类型/标签名称,测试 = 父 ID。
从这里使用YAHOO.util.Dom.getElementsByClassName()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.