论坛首页 Web前端技术论坛

Firefox中的nextSibling

浏览 3988 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-03-04  
在Firefox中, link2的nextSibling并不是link3, 因为两者之间有一个换行符, 这被认为是一个空格, 所以link2的nextSibling就是这个空格, 即一个text node, IE不存在这个问题。
<a href="link2" id="link2"></a>
<a href="link3" id="link3"></a>
   发表时间:2011-03-31  
这个问题差点导致一个BUG,还好我两个浏览器都测了一下
0 请登录后投票
   发表时间:2011-03-31  
IE不是标准
0 请登录后投票
   发表时间:2011-03-31   最后修改:2011-03-31
避免这个问题,你可以先find("a")得到一个集合,在集合里遍历,或者判断下个节点的类型。有时浏览器会自动补节点,你那种作法风险很大。
0 请登录后投票
   发表时间:2011-03-31  
.nextElementSibling || .nextSibling
这是IE的BUG
0 请登录后投票
   发表时间:2011-03-31   最后修改:2011-03-31
暴走的酱油瓶 写道
避免这个问题,你可以先find("a")得到一个集合,在集合里遍历,或者判断下个节点的类型。有时浏览器会自动补节点,你那种作法风险很大。

find("a")?这是什么函数? jQuery? 这里只跟大家讨论原生的JavaScript.
我这种做法风险很大? 你指什么? 什么情况下会导致错误?

这个例子很好的解决了这个问题:
function next( elem ) {
  do {
    elem = elem.nextSibling;
  } while ( elem && elem.nodeType != 1 );
    return elem;
}
0 请登录后投票
   发表时间:2011-03-31   最后修改:2011-03-31
int08h 写道
.nextElementSibling || .nextSibling
这是IE的BUG

这不能说是IE的BUG, 只能说IE跟其他浏览器的实现有所不同, IE6不支持XMLHttpRequest对象你能说这是他的bug吗?
IE通过attachEvent而不是标准的addEventListener来添加事件处理器, 这能说它是一个bug吗?
nextElementSibling
firstElementChild
lastElementChild
childElementCount
children
previousElementSibling
最新的浏览器确实已经已经支持如上的DOM标准, IE直到8还是不支持.
你的这种写法不错, 但是对于较老的非IE浏览器, 它就有问题了, 至少Firefox在3.5版本以前还不支持这些新的DOM标准.
而我提供的这个例子就没有问题.
0 请登录后投票
   发表时间:2011-04-01  
DOM标准明确说了nextSibling返回当前元素的下一个Node,而<a>元素后的Node明显是一个TextNode,其nodeValue是'\n',而IE竟然没有返回一个TextNode,跳过了一个Node,这个如果不称之为BUG的话,还能说是啥……

不要拿IE6很老,当时的标准不全为理由,MSDN上对nextSibling的解释就是"Retrieves a reference to the next child of the parent for the object."。而IE很明显的,直接把\n为nodeValue的TextNode从DOM树中除掉了

nextSibling的问题并不是IE对这个属性的理解有问题,而是涉及到IE对整个DOM树的解析和构建上的问题,这个我还是使认为应该称之为BUG,或者说,不按标准的,我认为就能说是BUG,好比要是IE的Math.pow(2, 2)返回了9,你也会认为这只是对标准的支持程度不同吗?
0 请登录后投票
   发表时间:2011-04-01  
引用
而<a>元素后的Node明显是一个TextNode,其nodeValue是'\n'

我觉得一点都不明显啊! 
好了, 跟你争论IE的这种行为到底是不是bug是没有意义的, 有意义的是如何去处理这个客观存在的问题,
一般人使用nextSibling是不会期望去得到一个换行符的, 所以新版的DOM标准提供了nextElementSibling来跳过
这些空白符和文本节点.
还有, 你的解决方案是.nextElementSibling||.nextSibling,
也就是说你准备通过判断对象的存在性来决定用nextElementSibling或nextSibling, 不过你注意哦,这些新的DOM标准只存在于element node中, 文本节点和注释节点是不支持该属性的. 因为你没有给出demo,
那我就斗胆猜测一下你可能的做法:
//这个function是要取node的下一个兄弟元素节点
function next(node){
  if(node.nextElementSibling){
    return node.nextElementSibling;
  }else{
    return node.nextSibling;
  }
}

好了, 这个函数正确处理了以下场景,即给你link2, 可以得到下一个element节点link3
<a href="link2" id="link2"></a>
<a href="link3" id="link3"></a>
测试代码:
<html>
<head>
<title>W3C DOM tests - childNodes and nextSibling</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
test result:
<div id='display'></div>
<a href="link2" id="link2"></a>
<a href="link3" id="link3"></a>
<script type="text/javascript" >
var display = document.getElementById('display');
function dwr(s){
	display.innerHTML+=s+'<br/>';
}
var link2 = document.getElementById('link2');

function next(node){
  if(node.nextElementSibling){
    return node.nextElementSibling;
  }else{
    return node.nextSibling;
  }
}

var nextEleSibling = next(link2);
dwr('node name: '+nextEleSibling.nodeName +', node value: '+nextEleSibling.nodeValue);

</script>
</body>
</html>

不过, 麻烦的来了, 如果传给这个函数的是一个文本节点, 并且该文本节点的下一个节点是一个注释节点, 如下:
<a href="link2" id="link2"></a>s
<!--This is a comment. Comments are not displayed in the browser-->
<a href="link3" id="link3"></a>
传s这个文本节点给next()
next(link2.nextSibling), 看看你将得到什么?
别说我举的例子很极端, js编程什么情况都有. 有人就是喜欢传一个文本节点给这个函数,咬我啊?
或许你会说:"我才不会写这么撮的next()函数呢!"
那么, 请给出你的方案吧! 估计你还是得判断nodeType, 还是会采用循环.

纯技术讨论, 欢迎指出我的错误!
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics