[英]Implementing document.getElementById in javascript
我正在尝试在javascript中实现原生document.getElementById
。 我在javascript中实现了document.getElementsByClassName
。
function getElementsByClassName (className) { var nodeList = []; function test(node) { if (node.classList && node.classList.contains(className)) { nodeList.push(node); } for (var index = 0; index < node.childNodes.length; index++) { test(node.childNodes[index]); } return nodeList; } test(document.body); return nodeList; }; // Fails here. function getElementById(className) { const result = []; function getEachIDNode(node) { if(node.contains(className)) { return node; } for(let i=0; i<node.childNodes.length; i++) { getEachIDNode(node.childNodes[i]); } } getEachIDNode(document.body); } console.log(getElementsByClassName('winner')); console.log(getElementById('test'));
<table> <tr id="test"> <td>#</td> <td class="winner">aa</td> <td>bb</td> <td>cc</td> <td>dd</td> </tr> </table> <table> <tr> <td>#</td> <td class="winner">aa</td> <td>bb</td> <td>cc</td> <td>dd</td> </tr> </table> <table> <tr> <td>#</td> <td class="winner">dd</td> <td>cc</td> <td>bb</td> <td>aa</td> </tr> </table>
我试图了解如何检查节点是否具有属性ID。
有人可以开导我吗?
根据传递的参数检查节点的id
属性(最好使用id
作为参数而不是className
):
function getElementById(id) { const result = []; function getEachIDNode(node) { if(node.id === id) { result.push(node); } for(let i=0; i<node.childNodes.length; i++) { getEachIDNode(node.childNodes[i]); } } getEachIDNode(document.body); return result; } console.log(getElementById('subchild')[0].innerHTML);
<div id="parent"> <div id="child1"> </div> <div id="child2"> <div id="subchild"> subchild! </div> </div> </div>
但是如果你真的想要复制getElementById
,不要尝试返回一个数组,返回一个元素:
function getElementById(id) { let match = null; const doFind = node => { if (!match && node.id === id) match = node; if (!match) return [...node.childNodes].find(doFind); } doFind(document.body); return match; } console.log(getElementById('subchild').innerHTML);
<div id="parent"> <div id="child1"> </div> <div id="child2"> <div id="subchild"> subchild! </div> </div> </div>
检查DOM元素的属性属性。
function getElementById(id) {
const result = [];
function getEachIDNode(node) {
if(!(node instanceof HTMLElement))
return;
if(node.hasAttribute('id') && node.getAttribute('id') === id) {
result.push(node);
}
for(let i=0; i<node.childNodes.length; i++) {
if(result.length > 0)
return;
getEachIDNode(node.childNodes[i]);
}
}
getEachIDNode(document.body);
return result[0];
}
本机document.getElementById
不会遍历搜索Element的DOM树,这就是为什么它比其他DOM选择方法更快的原因。
实际上,浏览器必须在活动文档中保留一种带有id的所有Elements的哈希映射。 所以他们只是对这个哈希映射 (不是一个)执行查找,如果找到它就返回该元素。
感谢IE </ irony>,他们确实将这个哈希映射的一些条目公开为全局window
对象的属性。
因此,如果您要进行自己的实现,可以先检查此属性是否返回Element。
不幸的是,可能会发生Element的id与window
对象的其他属性一致。 所以我们仍然需要走DOM。
在这种情况下,使用TreeWalker ,它是我们必须遍历DOM树的最快的API,而且当我们只对某种类型的节点(这里是Elements)感兴趣时。
总而言之,更好的实现可能如下所示:
function getElementById(id) { if (!(id in window)) { console.log(id, 'not found'); return null; // we are sure it's not set } // id maps are not marked as 'own property' if (!window.hasOwnProperty(id)) { if (window[id] instanceof Element && window[id].id === id) { // it's our Element console.log(id, 'found in window'); return window[id]; } // in case of duplicate window[id] should return an HTMLCollection // (IIRC only Chrome does it correctly though) if (window[id] instanceof HTMLCollection && window[id][0].id === id) { console.log(id, 'duplicate id is bad'); return window[id][0]; } } console.log(id, 'walking...'); var walker = document.createTreeWalker( document.documentElement, NodeFilter.SHOW_ELEMENT, null, false ); while (walker.nextNode()) { if (walker.currentNode.id === id) { return walker.currentNode; } } return null; } console.log(getElementById('foo')); console.log(getElementById('unique')); console.log(getElementById('duplicate')); window.overwritten = 'oups'; console.log(getElementById('overwritten'));
<div id="unique"> <div id="duplicate"></div> <div id="duplicate"></div> <div id="overwritten"></div> </div>
正如您所看到的,在此实现中,只有在窗口的属性已设置为其他值时才会遍历DOM,从而大大提高了性能。
检查节点是否具有属性ID。您必须这样写:
var attr_check = $(".selector").attr('id')
if(attr_check != undefined || attr_check != false)
{
console.log("this element has attribute id")
}
你也写这个代码:
var attr_check = document.getElementById('div-id').attr('id')
而不是这个:
var attr_check = $(".selector").attr('id')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.