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 对象中的类数组操作
Apr 27 Javascript
跟我学习javascript的prototype使用注意事项
Nov 17 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
Jan 26 Javascript
基于JavaScript实现瀑布流布局(二)
Jan 26 Javascript
jQuery 如何给Carousel插件添加新的功能
Apr 18 Javascript
手机Web APP如何实现分享多平台功能
Aug 19 Javascript
轻松理解JavaScript闭包
Mar 14 Javascript
Vue路由跳转问题记录详解
Jun 15 Javascript
JS原生轮播图的简单实现(推荐)
Jul 22 Javascript
JavaScript实现百度搜索框效果
Mar 26 Javascript
原生js+canvas实现验证码
Nov 29 Javascript
JS闭包原理及其使用场景解析
Dec 03 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
preg_match_all使用心得分享
2014/01/31 PHP
php通过记录IP来防止表单重复提交方法分析
2014/12/16 PHP
ThinkPHP使用Ueditor的方法详解
2016/05/20 PHP
php 使用html5实现多文件上传实例
2016/10/24 PHP
详解php中的implements 使用
2017/06/13 PHP
Javascript注入技巧
2007/06/22 Javascript
Prototype Number对象 学习
2009/07/19 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
2012/02/17 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
JS+CSS实现自动改变切换方向图片幻灯切换效果的方法
2015/03/02 Javascript
jQuery定义插件的方法
2015/12/18 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
Web打印解决方案之普通报表打印功能
2016/08/29 Javascript
jQuery中 bind的用法简单介绍
2017/02/13 Javascript
浅析javaScript中的浅拷贝和深拷贝
2017/02/15 Javascript
Angularjs中的ui-bootstrap的使用教程
2017/02/19 Javascript
使用angular帮你实现拖拽的示例
2017/07/05 Javascript
深入理解基于vue-cli的vuex配置
2017/07/24 Javascript
vue路由嵌套的SPA实现步骤
2017/11/06 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
JavaScript switch语句使用方法简介
2019/12/30 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
python实现得到一个给定类的虚函数
2014/09/28 Python
尝试用最短的Python代码来实现服务器和代理服务器
2016/06/23 Python
Python中防止sql注入的方法详解
2017/02/25 Python
python的Crypto模块实现AES加密实例代码
2018/01/22 Python
python 获取字符串MD5值方法
2018/05/29 Python
Python基于Hypothesis测试库生成测试数据
2020/04/29 Python
JSF面试题:Jsf中导航的标签是什么
2013/04/20 面试题
构造方法和其他方法的区别
2016/04/26 面试题
合作协议书模板2014
2014/09/26 职场文书
小学生校园广播稿
2014/09/28 职场文书
2015教师节通讯稿
2015/07/20 职场文书
总经理年会致辞
2015/07/29 职场文书
大学生党课心得体会
2016/01/07 职场文书
python通过函数名调用函数的几种方法总结
2021/06/07 Python