JavaScript中nextSibling与previousSibling的跨浏览器兼容处理

作者:白露

时间:2026-10-29

浏览:581

本文详解JavaScript中nextSibling和previousSibling的正确用法。针对IE与Firefox对空白文本节点处理的差异,提供了通过nodeType过滤非元素节点的方法,确保在批量生成表单时能准确获取兄弟节点的值,避免跨浏览器兼容性问题。

文章目录

基于DOM节点的日期验证场景

在进行日期验证时,无需验证具体格式,只需确保起始日期不大于结束日期。由于输入页面采用批量生成方式,且每一行由脚本动态创建,无法直接使用ID作为参数,必须通过DOM节点进行操作,这增加了验证逻辑的复杂度。

以下是JSP页面中相关部分的代码结构:


<td><input id="warrantyStartDateStr" name="warrantyStartDateStr"        

 class="toolbar_button_input_80" type="Text" onClick="WdatePicker()"></td>
<td><input id="warrantyEndDateStr" name="warrantyEndDateStr" class="toolbar_button_input_80" type="Text" onClick="WdatePicker()" onBlur="checkDateOne(this)"></td>

最终的JavaScript函数实现如下:

该函数的核心目标是不依赖ID,直接通过DOM节点获取两个input元素的value值(即起始时间和结束时间),进而比较这两个时间的大小关系。


function checkDateOne(inputsNode){
var p = inputsNode.parentNode; //取得input节点的父节点td
var preNode=p.previousSibling.firstChild;//取得td节点的前一个兄弟节点的第一个子结点
var startDate = document.getElementByIdx_x(preNode.id).value;
var endDate = document.getElementByIdx_x(inputsNode.id).value;      
if(startDate.length>0 && endDate.length>0){   
 var startTmp=startDate.split("-"); 
 var endTmp=endDate.split("-"); 
 var sd=new Date(startTmp[0],startTmp[1],startTmp[2]); 
 var ed=new Date(endTmp[0],endTmp[1],endTmp[2]); 
 if(sd.getDate()>=ed.getDate()){  
  alert("起始日期不能大于结束日期");   
   //return false;   
  }   
  }
 }

实现思路首先获取当前input节点的父节点p(即td节点),然后获取父节点的上一个兄弟节点的第一个子节点input,从而成功获取到目标值。

需要特别注意,td节点是input节点的父节点,而非兄弟节点,在遍历时应明确这一层级关系。

IE与Firefox对空白节点处理的差异

此外,nextSibling和previousSibling在Internet Explorer(IE)与Firefox(FF)之间存在显著的行为差异,需特别处理。

通过以下示例进行说明:


<body>  
<div>  
<input id= "a4" type= "button" onclick= "alert(this.nextSibling);" value= "d" />  
<input id= "a5" type= "button" onclick= "alert(this.nextSibling);" value= "e" />  
</div>  
</body> 

从表面结构看,div的nextSibling似乎只包含两个input节点,但实际上包含5个节点:换行符、input、换行符、input、换行符。这是因为IE在生成表单控件(如button、checkbox、radio等)时,会自动在标签后插入一个1字节宽的空白节点。

IE会自动跳过节点间的空格文档节点(如换行字符),而Firefox不会这样做。Firefox会将空格、换行等排版元素视为节点进行读取。因此,在IE中使用nextSibling可直接读取下一个节点元素,而在Firefox中则需要使用nextSibling.nextSibling才能定位到实际的元素节点。

previousSibling的作用与nextSibling相反,但处理逻辑相同,同样需要考虑浏览器对空白节点的差异处理。

以下是关于nextSibling和previousSibling的详细介绍及兼容性问题解决方案。

通过nodeType实现跨浏览器兼容

在Firefox中,节点间包含大量作为文本节点的空白字符,直接使用nextSibling和previousSibling会导致获取到文本节点而非元素节点。Firefox会将文本节点误判为元素节点的兄弟节点。解决方法是添加nodeType判断,当获取到的上一节点或下一节点为文本节点时,继续向上或向下查找,直到找到nodeType为1的元素节点。以下代码已在Firefox中测试通过,供参考:


        //下一个兄弟节点
    function nextSibling(node) {
      var tempLast = node.parentNode.lastChild;
      if (node == tempLast) return null;
      var tempObj = node.nextSibling;
      while (tempObj.nodeType != 1 && tempObj.nextSibling != null) {
        tempObj = tempObj.nextSibling;
      }
      return (tempObj.nodeType==1)? tempObj:null;
    }
    //前一个兄弟节点
    function prevSibling(node) {
      var tempFirst = node.parentNode.firstChild;
      if (node == tempFirst) return null;
      var tempObj = node.previousSibling;
      while (tempObj.nodeType != 1 && tempObj.previousSibling != null) {
        tempObj = tempObj.previousSibling;
      }
      return (tempObj.nodeType==1)? tempObj:null;
    }  

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <script type="text/javascript" language="javascript" >
    window.onload = function () {
      var oUl = document.getElementsByTagName("UL");
      var nodeLi = oUl[0].childNodes[3];
      var nextListItem = nodeLi.nextSibling;
      var preListItem = nodeLi.previousSibling;
      alert(nextListItem.tagName + " " + preListItem.tagName);
      nextListItem = nextSibling(nodeLi);
      preListItem = prevSibling(nodeLi);
      alert(nextListItem.tagName + " " + preListItem.tagName);
    }
    //下一个兄弟节点
    function nextSibling(node) {
      var tempLast = node.parentNode.lastChild;
      if (node == tempLast) return null;
      var tempObj = node.nextSibling;
      while (tempObj.nodeType != 1 && tempObj.nextSibling != null) {
        tempObj = tempObj.nextSibling;
      }
      return (tempObj.nodeType==1)? tempObj:null;
    }
    //前一个兄弟节点
    function prevSibling(node) {
      var tempFirst = node.parentNode.firstChild;
      if (node == tempFirst) return null;
      var tempObj = node.previousSibling;
      while (tempObj.nodeType != 1 && tempObj.previousSibling != null) {
        tempObj = tempObj.previousSibling;
      }
      return (tempObj.nodeType==1)? tempObj:null;
    }  
  </script>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <ul>
      <li>HTML</li>
      <li>CSS</li>
      <li>JavaScript</li>
      <li>JQuery</li>
      <li>Dom</li>
    </ul>
    <ul>
      <li>ASP.NET</li>
      <li>JSP</li>
      <li>PHP</li>
      <li>VB.NET</li>
    </ul>
  </div>
  </form>
</body>
</html>

其中,nodeType的值主要有以下几种常见类型:

元素节点的nodeType值为1 属性节点的nodeType值为2 文本节点的nodeType值为3

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章