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 页面输出值
Nov 30 Javascript
safari,opera嵌入iframe页面cookie读取问题解决方法
Jun 23 Javascript
javascript下string.format函数补充
Aug 24 Javascript
JavaScript入门之对象与JSON详解
Oct 21 Javascript
checkbox勾选判断代码分析
Jun 11 Javascript
用javascript读取xml文件读取节点数据
Aug 12 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
Jun 18 Javascript
基于JQuery及AJAX实现名人名言随机生成器
Feb 10 Javascript
简单的vue-resourse获取json并应用到模板示例
Feb 10 Javascript
简述vue中的config配置
Jan 23 Javascript
如何使用proxy实现一个简单完整的MVVM库的示例代码
Sep 17 Javascript
解决echarts中横坐标值显示不全(自动隐藏)问题
Jul 20 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 和 XML: 使用expat函数(三)
2006/10/09 PHP
用php实现像JSP,ASP里Application那样的全局变量
2007/01/12 PHP
dedecms模板标签代码官方参考
2007/03/17 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
PHP二维数组的去重问题解析
2011/07/17 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
2014/10/14 PHP
thinkphp模板的包含与渲染实例分析
2014/11/26 PHP
得到form下的所有的input的js代码
2013/11/07 Javascript
JavaScript中对JSON对象的基本操作示例
2016/05/21 Javascript
Ext JS 实现建议词模糊动态搜索功能
2017/05/13 Javascript
详解如何在vue中使用sass
2017/06/21 Javascript
使用JavaScript生成罗马字符的实例代码
2018/06/08 Javascript
Vuex 快速入门(简单易懂)
2018/09/20 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
Vue+Django项目部署详解
2019/05/30 Javascript
vue实现Input输入框模糊查询方法
2021/01/29 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
详解JavaScript匿名函数和闭包
2020/07/10 Javascript
JS实现斐波那契数列的五种方式(小结)
2020/09/09 Javascript
关于angular 8.1使用过程中的一些记录
2020/11/25 Javascript
[01:45]绝对公平!DOTA2队长征召模式详解
2014/04/25 DOTA
python遍历 truple list dictionary的几种方法总结
2016/09/11 Python
Python时间的精准正则匹配方法分析
2017/08/17 Python
Python2实现的LED大数字显示效果示例
2017/09/04 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
python 采用paramiko 远程执行命令及报错解决
2019/10/21 Python
Python ADF 单位根检验 如何查看结果的实现
2020/06/03 Python
25个CSS3动画按钮和菜单教程分享
2012/10/03 HTML / CSS
La Redoute英国官网:法国时尚品牌
2017/04/27 全球购物
沙特阿拉伯电子产品和家用电器购物网站:Black Box
2019/07/24 全球购物
澳大利亚在线消费电子产品商店:TobyDeals
2020/01/05 全球购物
2014年幼儿园元旦活动方案
2014/02/13 职场文书
超市开业庆典策划方案
2014/05/14 职场文书
公司授权委托书样本
2014/09/15 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
如何理解python接口自动化之logging日志模块
2021/06/15 Python