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插件 autoComboBox 下拉框
Dec 22 Javascript
提交按钮的name='submit'引起的js失效问题及原因
Feb 25 Javascript
js实现在网页上简单显示时间的方法
Mar 02 Javascript
多个js毫秒倒计时同时进行效果
Jan 05 Javascript
javascript简单判断输入内容是否合法的方法
May 11 Javascript
关于JS变量和作用域详解
Jul 28 Javascript
利用Js+Css实现折纸动态导航效果实例源码
Jan 25 Javascript
AngularJS创建一个上传照片的指令实例代码
Feb 24 Javascript
vue.js前后端数据交互之提交数据操作详解
Apr 24 Javascript
关于vue的npm run dev和npm run build的区别介绍
Jan 14 Javascript
Angular实现svg和png图片下载实现
May 05 Javascript
vue项目多环境配置(.env)的实现
Jul 21 Vue.js
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 Mysql编程之高级技巧
2008/08/27 PHP
如何用phpmyadmin设置mysql数据库用户的权限
2012/01/09 PHP
php跨服务器访问方法小结
2015/05/12 PHP
php实现在线通讯录功能(附源码)
2016/05/13 PHP
Yii中srbac权限扩展模块工作原理与用法分析
2016/07/14 PHP
php中get_magic_quotes_gpc()函数说明
2017/02/06 PHP
PHP进程通信基础之信号量与共享内存通信
2017/02/19 PHP
Swoole实现异步投递task任务案例详解
2019/04/02 PHP
IE关闭时判断及AJAX注销案例学习
2013/02/18 Javascript
Table冻结表头示例代码
2013/08/20 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
2014/04/16 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
JQuery包裹DOM节点的方法
2015/06/11 Javascript
微信小程序基础教程之worker线程的使用方法
2019/07/15 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
JS动态显示倒计时效果
2019/12/12 Javascript
如何在JavaScript中创建具有多个空格的字符串?
2020/02/23 Javascript
vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)
2020/11/12 Javascript
Python中的defaultdict模块和namedtuple模块的简单入门指南
2015/04/01 Python
利用Python实现简单的相似图片搜索的教程
2015/04/23 Python
Python如何import文件夹下的文件(实现方法)
2017/01/24 Python
详解在python操作数据库中游标的使用方法
2019/11/12 Python
DC Shoes官网:美国滑板鞋和服饰品牌
2017/09/03 全球购物
约瑟夫·特纳男装:Joseph Turner
2017/10/10 全球购物
英国婚礼商城:Wedding Mall
2019/11/02 全球购物
家乐福台湾线上购物网:Carrefour台湾
2020/09/15 全球购物
Java的类与C++的类有什么不同
2014/01/18 面试题
一名毕业生的自我鉴定
2013/12/04 职场文书
建筑人员岗位职责
2013/12/25 职场文书
师范毕业生自我鉴定
2014/01/15 职场文书
群众路线领导干部个人对照检查材料(集锦)
2014/09/23 职场文书
党的群众路线教育实践活动领导班子整改方案
2014/10/25 职场文书
售后服务承诺函格式
2015/01/21 职场文书
写给女朋友的保证书
2015/05/09 职场文书
Python办公自动化解决world文件批量转换
2021/09/15 Python