javascript中的previousSibling和nextSibling的正确用法


Posted in Javascript onSeptember 16, 2015

我做的时间的验证,格式是不需要验证的,只需要验证起始日期与结束日期的大小,但是因为输入页面是批量的,而且每一行又是自动生成的,这样就不能用id来作为参数,只能用节点。这就给验证增加了难度。

    以下是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>

而我的js函数最终是这样写的:

   js函数的目的就是不通过id,却能够获得两个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节点的父节点,不能当成是它的兄弟节点。

另外还想说:previousSibling和nextSibling在IE和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只有2项——两个input节点。但实际上有5项——/n,input,/n,input,/n。这是因为input作为创建各种表单输入控件的标签,无论是生成button、checkbox、radio...等或其他表单控件,IE都会自动在后面创建一个1字节位的空白。

       IE将跳过在节点之间产生的空格文档节点(如:换行字符),而Mozilla不会这样——FF会把诸如空格换行之类的排版元素视作节点读取,因此,在ie 中用nextSibling便可读取到的下一个节点元素,在FF中就需要这样写:nextSibling.nextSibling了。

     previousSibling的作用正好相反,但是用法也是同样的道理!

nextSibling和previousSibling介绍

在FireFox中包含众多空格作为文本节点,因此在我们使用nextSibling和previousSibling时就会出现问题。因为FireFox会把文本节点误当做元素节点的兄弟节点来处理。我们可以添加nodeType来判断。当上一节点或者是下一节点为文本节点时,就继续寻找,直到找到下一个元素节点。以下代码仅供参考,在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

Javascript 相关文章推荐
jQuery ajax cache缓存问题
Jul 01 Javascript
JavaScript中的常见问题解决方法(乱码,IE缓存,代理)
Nov 28 Javascript
JS实现完全语义化的网页选项卡效果代码
Sep 15 Javascript
JS与jQ读取xml文件的方法
Dec 08 Javascript
Bootstrap网格系统详解
Apr 26 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
Aug 02 Javascript
原生的强大DOM选择器querySelector介绍
Dec 21 Javascript
JavaScript转换数据库DateTime字段类型方法
Jun 27 Javascript
利用yarn代替npm管理前端项目模块依赖的方法详解
Sep 04 Javascript
jquery鼠标悬停导航下划线滑出效果
Sep 29 jQuery
jQuery常见的遍历DOM操作详解
Sep 05 jQuery
Element PageHeader页头的使用方法
Jul 26 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
Sep 16 #Javascript
JS+CSS实现的经典tab选项卡效果代码
Sep 16 #Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
Sep 16 #Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
Sep 16 #Javascript
jQuery实现的简单折叠菜单(折叠面板)效果代码
Sep 16 #Javascript
JS实现不规则TAB选项卡效果代码
Sep 16 #Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
Sep 15 #Javascript
You might like
PHP中,文件上传
2006/12/06 PHP
php命令行用法入门实例教程
2014/10/27 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
2016/04/02 PHP
php生成微信红包数组的方法
2019/09/05 PHP
javascript 对象定义方法 简单易学
2009/03/22 Javascript
javascript 兼容鼠标滚轮事件
2009/04/07 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
2014/05/29 Javascript
jQuery中:header选择器用法实例
2014/12/29 Javascript
jQuery实现的经典滑动门效果
2015/09/22 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
2016/02/20 Javascript
JavaScript中三种异步上传文件方式
2016/03/06 Javascript
AngularJS 入门教程之HTML DOM实例详解
2016/07/28 Javascript
JavaScript实现动态增删表格的方法
2017/03/09 Javascript
详解Angular Reactive Form 表单验证
2017/07/06 Javascript
jQuery实现火车票买票城市选择切换功能
2017/09/15 jQuery
vue实现在表格里,取每行的id的方法
2018/03/09 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
详解搭建es6+devServer简单开发环境
2018/09/25 Javascript
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
解决vue中el-tab-pane切换的问题
2020/07/19 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
nestjs中异常过滤器Exceptionfilter的具体使用
2021/02/07 Javascript
在漏洞利用Python代码真的很爽
2007/08/26 Python
Linux下使用python自动修改本机网关代码分享
2015/05/21 Python
python 巧用正则寻找字符串中的特定字符的位置方法
2018/05/02 Python
利用python提取wav文件的mfcc方法
2019/01/09 Python
详解pandas库pd.read_excel操作读取excel文件参数整理与实例
2019/02/17 Python
基于python计算滚动方差(标准差)talib和pd.rolling函数差异详解
2020/06/08 Python
微信小程序实现可实时改变转速的css3旋转动画实例代码
2018/09/11 HTML / CSS
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
亚洲领先的旅游体验市场:Voyagin
2019/11/23 全球购物
路政管理专业个人自荐信范文
2013/11/30 职场文书
关于赌博的检讨书
2014/01/24 职场文书
优质服务演讲稿
2014/05/14 职场文书
企业法人代表任命书
2014/06/06 职场文书
合伙经营协议书范本
2014/09/13 职场文书