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 相关文章推荐
Windows Live的@live.com域名注册漏洞 利用代码
Dec 27 Javascript
JS DOM 操作实现代码
Aug 01 Javascript
在网站上应该用的30个jQuery插件整理
Nov 03 Javascript
JQuery.closest(),parent(),parents()寻找父结点
Feb 17 Javascript
js实现上传图片之上传前预览图片
Mar 25 Javascript
Jquery中CSS选择器用法分析
Feb 10 Javascript
JS组件Bootstrap实现弹出框和提示框效果代码
Dec 08 Javascript
探究JavaScript函数式编程的乐趣
Dec 14 Javascript
JavaScript 中调用 Kotlin 方法实例详解
Jun 09 Javascript
angular $watch 一个变量的变化(实例讲解)
Aug 02 Javascript
jQuery Easyui Treegrid实现显示checkbox功能
Aug 08 jQuery
详解Node.js如何处理ES6模块
May 15 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中的一个中文字符串截取函数
2007/02/14 PHP
探讨:如何通过stats命令分析Memcached的内部状态
2013/06/14 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
PHP针对中英文混合字符串长度判断及截取方法示例
2017/03/31 PHP
jquery 年会抽奖程序
2011/12/22 Javascript
如何使Chrome控制台支持多行js模式——意外发现
2013/06/13 Javascript
Javascript核心读书有感之表达式和运算符
2015/02/11 Javascript
jQuery实现带延迟的二级tab切换下拉列表效果
2015/09/01 Javascript
JS实现自动固定顶部的悬浮菜单栏效果
2015/09/16 Javascript
[原创]JQuery 在表单提交之前修改 提交的值
2016/04/14 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
vue2.0 常用的 UI 库实例讲解
2017/12/12 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
[01:11:15]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[00:56]跨越时空加入战场 全新祈求者身心“失落奇艺侍祭”展示
2019/07/20 DOTA
python实现随机密码字典生成器示例
2014/04/09 Python
Python对list列表结构中的值进行去重的方法总结
2016/05/07 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
python如何使用unittest测试接口
2018/04/04 Python
Linux下python制作名片示例
2018/07/20 Python
python networkx 根据图的权重画图实现
2019/07/10 Python
Python多继承以及MRO顺序的使用
2019/11/11 Python
python 循环数据赋值实例
2019/12/02 Python
python绘制趋势图的示例
2020/09/17 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
美国在线购买空气净化器、除湿器、加湿器网站:AllergyBuyersClub
2021/03/16 全球购物
人力资源行政经理自我评价
2013/10/23 职场文书
个人自荐书
2013/12/20 职场文书
大学生毕业自我鉴定范文
2014/02/03 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
中层领导干部群众路线对照检查材料思想汇报
2014/10/02 职场文书
运动会加油稿
2015/07/22 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
Python如何把不同类型数据的json序列化
2021/04/30 Python