我正在尝试使用parentNode,firstChild,nextSibling,childNodes []等编写javascript来查找相对于给定元素的页面元素。 Firefox通过在每个html元素之间插入文本节点来搞乱这一点。我已经读过,我可以通过删除元素之间的所有空格来打败它,但我已经尝试过了,但它并不起作用。有没有办法编写适用于所有现代浏览器的代码?
例如:
<div id="parent"><p id="child">Hello world</p></div>
在IE中,parent.firstChild是child,但在Firefix中,它是一个幻像Text元素。
答案 0 :(得分:1)
我有一个解决方法。您可以插入以下两种方法:
Element.prototype.fChild = function(){
var firstChild = this.firstChild;
while(firstChild != null && firstChild.nodeType === 3){
firstChild = firstChild.nextSibling;
}
return firstChild;
}
Element.prototype.nSibling = function(){
var nextSibling = this.nextSibling;
while(nextSibling != null && nextSibling.nodeType === 3){
nextSibling = nextSibling.nextSibling;
}
return nextSibling;
}
现在可以使用:
document.getElementById("parent").fChild();
document.getElementById("parent").nSibling();
而不是:
document.getElementById("parent").firstChild;
document.getElementById("parent").nextSibling;
答案 1 :(得分:1)
您必须检查nodeType == 1。
if (el.nodeType === 1) {
return el;
}
我为ya编写了一个小的DOM遍历类(主要是从MooTools复制而来)。 在此下载:http://gist.github.com/41440
DOM = function () {
function get(id) {
if (id && typeof id === 'string') {
id = document.getElementById(id);
}
return id || null;
}
function walk(element, tag, walk, start, all) {
var el = get(element)[start || walk], elements = all ? [] : null;
while (el) {
if (el.nodeType === 1 && (!tag || el.tagName.toLowerCase() === tag)) {
if (!all) {
return el;
}
elements.push(el);
}
el = el[walk];
}
return elements;
}
return {
// Get the element by its id
get: get,
walk: walk,
// Returns the previousSibling of the Element (excluding text nodes).
getPrevious: function (el, tag) {
return walk(el, tag, 'previousSibling');
},
// Like getPrevious, but returns a collection of all the matched previousSiblings.
getAllPrevious: function (el, tag) {
return walk(el, tag, 'previousSibling', null, true);
},
// As getPrevious, but tries to find the nextSibling (excluding text nodes).
getNext: function (el, tag) {
return walk(el, tag, 'nextSibling');
},
// Like getNext, but returns a collection of all the matched nextSiblings.
getAllNext: function (el, tag) {
return walk(el, tag, 'nextSibling', null, true);
},
// Works as getPrevious, but tries to find the firstChild (excluding text nodes).
getFirst: function (el, tag) {
return walk(el, tag, 'nextSibling', 'firstChild');
},
// Works as getPrevious, but tries to find the lastChild.
getLast: function (el, tag) {
return walk(el, tag, 'previousSibling', 'lastChild');
},
// Works as getPrevious, but tries to find the parentNode.
getParent: function (el, tag) {
return walk(el, tag, 'parentNode');
},
// Like getParent, but returns a collection of all the matched parentNodes up the tree.
getParents: function (el, tag) {
return walk(el, tag, 'parentNode', null, true);
},
// Returns all the Element's children (excluding text nodes).
getChildren: function (el, tag) {
return walk(el, tag, 'nextSibling', 'firstChild', true);
},
// Removes the Element from the DOM.
dispose: function (el) {
el = get(el);
return (el.parentNode) ? el.parentNode.removeChild(el) : el;
}
};
}();
// Now you can do:
DOM.getFirst("parent") // first child
// or
DOM.getFirst("parent", "p") // first p tag child
// or
var el = DOM.get("parent") // get element by id
DOM.getFirst(el) // first child
答案 2 :(得分:0)
您可以使用tagName检查标记的名称。如果未定义,则这是您的“幻像”文本节点。
e.g。
function getFirstTag(node) {
return ((node.firstChild.tagName) ? node.firstChild : node.firstChild.nextSibling);
}
答案 3 :(得分:0)
检查DOM level 2 core reference以查看各种可能类型的节点,以便您可以使用简单的JavaScript代码段过滤掉不需要的节点。一种解决方案是修补对象(请参阅Vernicht的答案)或者如果您不喜欢猴子修补,那么您可以将这些方法添加到您自己的库中,或者更好的解决方案可能是使用像jQuery这样的花哨库或原型。