我正在尝试在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。
有人可以启发我吗?
答案 0 :(得分:2)
对照传递的参数检查节点的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>
答案 1 :(得分:1)
检查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];
}
答案 2 :(得分:1)
原生zero
不会在DOM树中搜索您的元素,这就是为什么它比其他DOM选择方法更快的原因。
实际上,浏览器必须在活动文档中保留所有具有id的Elements的哈希图。因此,他们只是对该 hash-map (不是一个)执行查找,并在找到元素后返回该元素。
感谢IE ,它们确实将此 hash-map 的某些条目公开为全局document.getElementById
对象的属性。
因此,如果要进行自己的实现,则可以首先检查此属性是否返回您的Element。
不幸的是,可能会发生Element的ID与window
对象的其他属性一致的情况。因此,我们可能仍然需要遍历DOM。
在这种情况下,请使用TreeWalker,这是我们仅需对某种类型的节点(此处为Elements)感兴趣时就必须遍历DOM树的最快API。
总而言之,更好的实现可能看起来像这样:
window
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'));
如您所见,在此实现中,仅当窗口的属性设置为其他值时,我们才遍历DOM,从而大大提高了性能。
答案 3 :(得分:0)
要检查节点是否具有属性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')