javascript常用方法、属性集合及NodeList 和 HTMLCollection 的浏览器差异


Posted in Javascript onDecember 25, 2010
在您开始本文的阅读前,我强烈建议您可以先读一读此篇:http://w3help.org/zh-cn/causes/SD9004.

     
     HTMLCollection 接口定义

 

interface HTMLCollection
{
      readonly attribute unsigned long   length;
      Node               item(in unsigned long index);
      Node               namedItem(in DOMString name);
}

 


对于 HTMLCollection集合对象 必须要说一说的是 namedItem方法. 看看规范的解释.
原文:namedItem methodThis method retrieves a Node using a name. With [HTML 4.01] documents, it first searches for a Node with a matching id attribute. If it doesn't find one, it then searches for a Node with a matching name attribute, but only on those elements that are allowed a name attribute. With [XHTML 1.0] documents, this method only searches for Nodes with a matching id attribute. This method is case insensitive in HTML documents and case sensitive in XHTML documents. 翻译: namedItem 方法: 此方法获通过 "name"属性来获取节点. 在HTML4.01文档中,它首先搜索的是节点的ID属性的值. 如果没找到匹配节点,才去搜索name 属性与之匹配的节点. 即HTML4.01 DTD下,浏览器们应该优先通过ID来获取节点.其次才是name. 在XHTML 1.0文档中,则仅搜索ID与之匹配的节点. 对于节点(id or name)属性的值,此方法在HTML文档中忽略大小写区别,而在XHTML文档中.则要区别大小写.

 

上文中粗体部分很重要,没有这个作为指导的话.后面遇到的一些问题就很不好确定孰是孰非.因为众多浏览器的实现并不一样.

 


        
  NodeList 接口定义

interface NodeList {
  Node                     
item(in unsigned long index);
  readonly attribute  unsigned long       
length;
};


 微软MSDN上查到的 NodeList实现 ,虽然这些资料告诉我们 NodeList继承了 Microsoft.SpeechServer.Dom.Collections.Collection Class . 但是事实却并不如此. 事实上,ie浏览器的NodeList不具备 ICollection接口定义的 namedItem 和 tags 两个方法.  实现了他们的 只有HTMLCollection类型. 此文档是 Speech Server 2007 用的,所以应该仅供参考.只能说明IE浏览器中的NodeList 还是遵守标准的. public sealed class NodeList : Collection, INodeList, IEnumerable, IExpando, IReflect NodeList的继承链: System.Object       Microsoft.SpeechServer.Dom.Shim Microsoft.SpeechServer.Dom.DynamicShim  Microsoft.SpeechServer.Dom.Collections.Collection        Microsoft.SpeechServer.Dom.Collections.NodeList Collection 实现的ICollection接口定义的属性和方法表 public properties : item(msdn上说item是重载,我表示诧异...),length public methods    : item,namedItem,tags

ps:
1. 目前只有Opera的NodeList Class 是派生自 Collection Class 或HtmlCollection Class 的.所以此浏览器中NodeList集合对象也会具备 HTMLCollection接口实现的所有属性和方法.
2. MS 的ICollection 接口 定义了一个tags方法 用来根据tagName获取元素集合.其类型为 HTMLCollection 类型

 




 神秘的 StaticNodeList  

interface NodeSelector {
    Element   querySelector(in DOMString selectors);
    NodeList  querySelectorAll(in DOMString selectors);
  }

 

The NodeList object returned by the querySelectorAll() method must be static, not live ([DOM-LEVEL-3-CORE], section 1.1.1)


由于w3.org的[DOM-LEVEL-3-CORE]文档中,并没有StaticNodeList接口的定义. 只好在后面找出一份微软的代替之.


微软的一些相关:
基于 NodeList Class 是个密封类. 我们可以初步了解StaticNodeList 并不像最初我认为的那样,可能派生自NodeList. 而且规范说的明白. 这个集合是静态的.就是说它不会随着DOM树的变化而变化. 这种选择性去除基类能力的做法不符合继承的思想.所以只可能是另外的一个东东了.

Members Table

The following table lists the members exposed by the StaticNodeList object.

Attributes/Properties
Property Description
length Gets the number of characters in a TextNode object.
Methods
Method Description
item Retrieves an object from a childNodes or StaticNodeList collection.

Remarks

The collection will be empty if the querySelectorAll method returned no matches.

If the element tree is changed relative to the one or more original selectors used to generate the StaticNodeList collection, the collection (being static) will not be updated when the element tree changes.





测试:IE,     Firefox3.6,     Chrome10 Dev,     Opera 11,     Safari 5.02
测试主要针对nodeList 和 HTMLCollection, 并不涉及 xpath 以及namedNodeMap.等
关于namedNodeMap https://developer.mozilla.org/En/DOM/NamedNodeMap , http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1780488922
结果:

限定方 方法\浏览器 IE8 IE9 beta7930.16406 FireFox4.0 beta7 Chrome10.0 Dev Safari5.02 Opear11
W3C DOM2 getElementsByTagName HTMLCollection HTMLCollection HTMLCollection NodeList NodeList NodeList
WHATWG HTML5 getElementsByClassName HTMLCollection HTMLCollection HTMLCollection NodeList NodeList NodeList
W3C DOM1 getElementsByName HTMLCollection HTMLCollection HTMLCollection NodeList NodeList NodeList
W3c Selectors API 1 querySelectorAll StaticNodeList StaticNodeList NodeList(Static)(注0) NodeList(Static) NodeList(Static) NodeList(Static)
W3C DOM1 childNodes NodeList NodeList NodeList NodeList NodeList NodeList
MS children HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 document.links HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 document.images HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 document.anchors HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 document.forms HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 document.applets HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 formElement.elements HTMLFormElement HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 selectElement.options HTMLSelectElement HTMLSelectElement  HTMLOptionsCollection  HTMLOptionsCollection  HTMLOptionsCollection  HTMLOptionsCollection
w3c DOM1 tableElement.rows HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
w3c DOM1 rowElement.cells HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection HTMLCollection
MS document.all HTMLCollection HTMLCollection (S)-(注4) (Q)object HTML document.all class HTMLAllCollection(注1) HTMLAllCollection(注2) HTMLCollection(注3)


注0: 非IE 且支持 querySelectorAll 的浏览器返回的集合对象应该也叫StaticNodeList .但不知是否因规范中定义querySelectorAll方法返回类型为NodeList类型. 
       但规范中有注解这个NodeList 必须为静态的对象.即不随着DOM Tree的改变而改变, 其自身的改变也不应该影响到DOM Tree.那么他就不该再叫NodeList类型.


注1: Chrome中 直接打印document.all,会得到undefined . 但是并不影响我们对document.all的访问和使用.
       Chrome3-浏览器中 仅仅是HTMLCollection,从Chrome4开始才是HTMLAllCollection


注2: Safari4中并不叫HTMLAllCollection 而只是 HTMLCollection


注3:Opera、Safari等浏览器中.也可以直接访问document.all , 但是 typeof document.all =='undefined'  以及 if(document.all){//此处逻辑永远不会被执行.}.但可以直接打印document.all



注4:Freifox在非标准模式,才支持document.all 且是一个很奇怪的东西.其构造器是Object. 这东西从FireFox 0.8时代貌似就有了.一直到现在的4.0 beta8 ...


ps:
.ie6,7可以参考ie8,测试方式是 使用namedItem 或 tags 两个方法是否被实现来检查其是否为nodeList 还是 HTMLCollection.

 

.不要奇怪为什么列表中没有window.frames,因为实际上window.frames在ie6,ie7,ie8(ie9已修改,所以同其他浏览器一样.)以外的浏览器中,就是window对象,即window === window.frames. ie6,7,8中大概window.frames是window对象的一个浅表复制. 所以实际上,要获取一个iframe,我们只需要 window[index||name]即可.




总结:
虽然看起来NodeList 和HTMLCollection 的差别仅在于 一个 namedItem 方法. 但这个方法本身也仅仅是在当前集合中 找到name 或 id符合的元素第一个元素出来
为了方便记忆,方便查找.我们应该尽量统一使用索引器代替 item以及namedItem方法. 但应注意 IE,Firefox对NodeList没有实现name索引器.Opera 的nodeList索引器 则可能返回一个NodeList集合(childNodes接口).  考虑到大多数问题出在childNodes接口上.我们紧紧需要铭记.对childNodes接口避免使用索引器即可. 对于querySelectorAll接口,甚至Opera也不支持其返回的NodeList(Static)的name索引器了.那么querySelectorAll的选择器一次性找到符合节点即可. 或者避免使用name索引器,改用 Number Index 索引器来筛选.

关于['name']索引方式应该注意的几个问题是 :
1. IE 又返回一个HTMLCollection集合(IE大概认为如果查找的元素集合中有表单元素,且name可能会出现重复.那么返回值就应该是一个集合.而不是单一元素.),且非表单元素name会被无视.
2.FireFox 和 opera 浏览器会 无视document.compatMode ,无视id或name,无视是否为表单元素,仅找出第一个符合 id或name任意一个为索引或namedItem()参数的元素.
3.webkit浏览器则无视document.compatMode,无视id,无视name,无视是否为表单元素,而仅仅找出id符合的元素.
Javascript 相关文章推荐
js类型检查实现代码
Oct 29 Javascript
JS实现清除指定cookies的方法
Sep 20 Javascript
推荐5 个常用的JavaScript调试技巧
Jan 08 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
Jun 05 Javascript
jquery分析文本里url或邮件地址为真实链接的方法
Jun 20 Javascript
JavaScript三种绑定事件方式及相互之间的区别分析
Jan 10 Javascript
Angularjs中使用layDate日期控件示例
Jan 11 Javascript
创建简单的node服务器实例(分享)
Jun 23 Javascript
vue.js图片转Base64上传图片并预览的实现方法
Aug 02 Javascript
jQuery实现的中英文切换功能示例
Jan 11 jQuery
简单了解Vue + ElementUI后台管理模板
Apr 07 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
Jul 26 Javascript
javascript与webservice的通信实现代码
Dec 25 #Javascript
基于node.js的快速开发透明代理
Dec 25 #Javascript
用方法封装javascript的new操作符(一)
Dec 25 #Javascript
一些javascript一些题目的解析
Dec 25 #Javascript
javascript字符串拼接的效率问题
Dec 25 #Javascript
原生javascript获取元素样式属性值的方法
Dec 25 #Javascript
javascript中使用replaceAll()函数实现字符替换的方法
Dec 25 #Javascript
You might like
PHP中浮点数计算比较及取整不准确的解决方法
2015/01/09 PHP
PHP连接access数据库
2015/03/27 PHP
php  PATH_SEPARATOR判断当前服务器系统类型实例
2016/10/28 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
如何直接访问php实例对象中的private属性详解
2017/10/12 PHP
js中判断数字\字母\中文的正则表达式 (实例)
2012/06/29 Javascript
用json方式实现在 js 中建立一个map
2014/05/02 Javascript
js实现用户注册协议倒计时的方法
2015/01/21 Javascript
JavaScript对象参数的引用传递
2016/01/14 Javascript
Uploadify上传文件方法
2016/03/16 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
2016/03/25 Javascript
基于BootStrap的Metronic框架实现页面链接收藏夹功能按钮移动收藏记录(使用Sortable进行拖动排序)
2016/08/29 Javascript
JSON中key动态设置及JSON.parse和JSON.stringify()的区别
2016/12/29 Javascript
JavaScript中变量提升与函数提升经典实例分析
2018/07/26 Javascript
react native基于FlatList下拉刷新上拉加载实现代码示例
2018/09/30 Javascript
JS删除String里某个字符的方法
2021/01/06 Javascript
es6 super关键字的理解与应用实例分析
2020/02/15 Javascript
Vue管理系统前端之组件拆分封装详解
2020/08/23 Javascript
uniapp微信小程序:key失效的解决方法
2021/01/20 Javascript
[04:50]DOTA2亚洲邀请赛小组赛第四日 TOP10精彩集锦
2015/02/02 DOTA
Python关于excel和shp的使用在matplotlib
2019/01/03 Python
Python交互式图形编程的实现
2019/07/25 Python
Django MEDIA的配置及用法详解
2019/07/25 Python
PyCharm搭建Spark开发环境的实现步骤
2019/09/05 Python
python实现信号时域统计特征提取代码
2020/02/26 Python
python def 定义函数,调用函数方式
2020/06/02 Python
Python如何操作docker redis过程解析
2020/08/10 Python
让IE9以下版本的浏览器兼容HTML5的方法
2014/03/12 HTML / CSS
Timberland俄罗斯官方网上商店:全球领先的户外品牌
2020/03/15 全球购物
公司试用期员工自我评价
2014/09/17 职场文书
收款授权委托书
2014/10/02 职场文书
导游词之嵊泗列岛
2019/10/30 职场文书
PyTorch的Debug指南
2021/05/07 Python
python的变量和简单数字类型详解
2021/09/15 Python
详解Vue slot插槽
2021/11/20 Vue.js
一行Python命令实现批量加水印
2022/04/07 Python