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 相关文章推荐
js 替换功能函数,用正则表达式解决,js的全部替换
Dec 08 Javascript
jQuery控制图片的hover效果(smartRollover.js)
Mar 18 Javascript
为指定的元素添加遮罩层的示例代码
Jan 15 Javascript
网页广告中JS代码的信息监听示例
Apr 02 Javascript
基于insertBefore制作简单的循环插空效果
Sep 21 Javascript
学习JavaScript设计模式(多态)
Nov 25 Javascript
Bootstrap模态框(Modal)实现过渡效果
Mar 17 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
Jun 17 Javascript
vue-cli 3 全局过滤器的实例代码详解
Jun 03 Javascript
修改layui的后台模板的左侧导航栏可以伸缩的方法
Sep 10 Javascript
JavaScript之Blob对象类型的具体使用方法
Nov 29 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
Nov 07 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
详解YII关联查询
2016/01/10 PHP
ThinkPHP框架里隐藏index.php
2016/04/12 PHP
PHP简单获取多个checkbox值的方法
2016/06/13 PHP
php工具型代码之印章抠图
2018/07/18 PHP
Yii框架的布局文件实例分析
2019/09/04 PHP
基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
2011/09/02 Javascript
jquery移动listbox的值原理及代码
2013/05/03 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
javascript简易画板开发
2020/04/12 Javascript
vue快捷键与基础指令详解
2017/06/01 Javascript
本地存储localStorage用法详解
2017/07/31 Javascript
Angularjs cookie 操作实例详解
2017/09/27 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
浅谈微信JS-SDK 微信分享接口开发(介绍版)
2018/08/15 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
2018/08/29 Javascript
jQuery实现点击旋转,再点击恢复初始状态动画效果示例
2018/12/11 jQuery
vue使用vuex实现首页导航切换不同路由的方法
2019/05/08 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
Python学习笔记之os模块使用总结
2014/11/03 Python
TensorFlow实现非线性支持向量机的实现方法
2018/04/28 Python
我喜欢你 抖音表白程序python版
2019/04/07 Python
python中列表的切片与修改知识点总结
2019/07/23 Python
python  logging日志打印过程解析
2019/10/22 Python
如何使用python传入不确定个数参数
2020/02/18 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
Django扫码抽奖平台的配置过程详解
2021/01/14 Python
I.T集团香港官方商城:ITeSHOP.com Hong Kong
2019/02/15 全球购物
《可爱的动物》教学反思
2014/02/22 职场文书
我们的节日春节活动方案
2014/08/22 职场文书
教师工作失职检讨书
2014/09/18 职场文书
父亲节寄语大全
2015/02/27 职场文书
2015初中团委工作总结
2015/07/28 职场文书
仅用几行Python代码就能复制她的U盘文件?
2021/06/26 Python
总结python多进程multiprocessing的相关知识
2021/06/29 Python
Nginx如何限制IP访问只允许特定域名访问
2022/07/23 Servers
SqlServer常用函数及时间处理小结
2023/05/08 SQL Server