JavaScript DOM学习第四章 getElementByTagNames


Posted in Javascript onFebruary 19, 2010

getElementByTagNames(注意是复数的names)会获得一些tag的元素,然后按照他们的顺序保存在一个数组中。这非常的有用,比如在上一章的TOCScript中,就需要获得整个文章里面的所有的H3和H4。
我非常希望在node原型中加入这个功能,但是在IE和Safari里面不行。所以只能把他当做一个普通函数。

使用
getElementByTagNames有两个参数:
1、一个用逗号分隔的tag名称字符串。
2、一个可选的开始元素。如果存在则在该元素的子元素中查找这些tag,如果不存在则在整个文档中查找。
这个函数根据要求的tag名称返回一个数组(而不是节点列表),按照他们在源代码中的出现顺序排列。对于这个排序需要浏览器支持sourceIndex或者compareDocumentPosition。如果都不支持(Safari)那么就按照调用getElementByTagNames()函数时候的tag名称的顺序。
实例1

var headerList = getElementsByTagNames('h1,h2,h3,h4');

现在headerList就是文档里包含H1-H4的数组,按照他们出现的顺序排序。
实例2
var element = document.getElementById('test'); 
var formFieldList = getElementsByTagNames('input,select,textarea',element);

现在formFieldList就是包含在ID为test的元素下的所有子元素中的input,select,TEXTAREA的数组,并且按照他们出现的书序排列。
function getElementsByTagNames(list,obj) { 
    if (!obj) var obj = document; 
    var tagNames = list.split(','); 
    var resultArray = new Array(); 
    for (var i=0;i<tagNames.length;i++) { 
        var tags = obj.getElementsByTagName(tagNames[i]); 
        for (var j=0;j<tags.length;j++) { 
            resultArray.push(tags[j]); 
        } 
    } 
    var testNode = resultArray[0]; 
    if (!testNode) return []; 
    if (testNode.sourceIndex) { 
        resultArray.sort(function (a,b) { 
                return a.sourceIndex - b.sourceIndex; 
        }); 
    } 
    else if (testNode.compareDocumentPosition) { 
        resultArray.sort(function (a,b) { 
                return 3 - (a.compareDocumentPosition(b) & 6); 
        }); 
    } 
    return resultArray; 
}

解释
function getElementsByTagNames(list,obj) 
{ 
if (!obj)var obj = document;

首先定义开始元素obj,如果没有给出,那么默认就是document。
var tagNames = list.split(','); 
var resultArray = new Array();

将这些tag名称以逗号分割。用一个数组来保存结果。
for (var i=0;i<tagNames.length;i++) { 
var tags = obj.getElementsByTagName(tagNames[i]); 
for (var j=0;j<tags.length;j++) { 
resultArray.push(tags[j]); 
} 
}

现在我们遍历所有的tag名称,就用最简单的getElementByTagName()方法,然后把结果传入resultArray。这里的一个要点是,因为getElementByTagName返回的是节点列表,所以我就不能使用array.concat()来建立新的数组。把元素一个一个的压入是我能找到的最好的办法。

我们得到了一个所需的tag名称的元素的指针数组存储在resultArray中,但是这些元素还是按照我们所给的tag的顺序排列的。我们需要再排个序。

var testNode = resultArray[0];

现在我们开始排序。我们需要知道浏览器是否支持sourceIndex或者compareDocumentPosition,然后我们对于我们的得到的原始数据做一些检测
if (!testNode) return [];

如果这里没有第一个节点(也就是说结果里并没有我们需要的元素),就返回一个空数组。

背景:array.sort()
array.sort()方法有一个可选函数的参数。这个函数用来比较两个元素(通常称为a和b)。如果第一个应该在前那么这个函数就返回一个负数,如果第二个应该在前那么就返回一个正值。

sourceIndex
如果浏览器支持sourceIndex,我们就根据元素的sourceIndex来排序。sourceIndex是微软的一个非常有用的扩展,可以用来知道元素在源代码中的索引值。页面种的第一个元素(<HTML>)的索引值就是0,第二个(<head>)就是1,等等。sourceIndex也是getElementByTagName(*)中的元素的索引值。

if (testNode.sourceIndex) { 
resultArray.sort(function (a,b) { 
return a.sourceIndex - b.sourceIndex; 
}); 
}

我们用第一个元素的sourceIndex值减去第二个元素的sourceIndex,如果是负值,那么第一个元素就排在前面,如果是正值,那么第二个元素排在前面。这就是sort()需要的。现在resultArray中的元素就是根据他们在文档中的位置来排序的。

compareDocumentPosition
如果浏览器支持compareDocumentPosition,那么就用这个办法来排序。compareDocumentPosition是level3的核心方法,他可以比较两个节点在文档中的位置,然后返回一个值:

1 没有找到

2 在前

4 在后

8 包含

16 被包含

比如,如果一个标签被包含并且在另一个标签的后面,那么就返回16+4=20。

else if (testNode.compareDocumentPosition) { 
resultArray.sort(function (a,b) { 
return 3 - (a.compareDocumentPosition(b) & 6); 
}); 
}

我们只对compareDocumentPosition的值中的2、4感兴趣:在前或者在后。所以我们将结果和6进行与运算,这样结果就会是2或者4(当然结果不能是6,因为一个元素不能即在一个元素之前又在一个元素之后)

如果b在a之后则返回4,但是sort()需要一个负数。如果b在a之前则返回2,但是sort()需要一个正数。为了给sort()一个正确的结果我把他们用3来减。这样就得到1或者-1,这样sort()就能对元素进行正确的排序,resultArray中的元素也按照他们在文档种的出现顺序排列。

return resultArray; 
}

然后我们返回resultArray给调用它的函数。记住如果浏览器不支持sourceIndex或者compareDocumentPosition数组就没有排序。

翻译地址:http://www.quirksmode.org/dom/getElementsByTagNames.html
转载请保留以下信息
作者:北玉(tw:@rehawk)

Javascript 相关文章推荐
基于jquery完美拖拽,可返回拖动轨迹
Mar 29 Javascript
JavaScript字符串对象charAt方法入门实例(用于取得指定位置的字符)
Oct 17 Javascript
JavaScript操作select元素和option的实例代码
Jan 29 Javascript
JQuery ztree带筛选、异步加载实例讲解
Feb 25 Javascript
如何消除inline-block属性带来的标签间间隙
Mar 31 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
Jan 05 Javascript
JS字符串长度判断,超出进行自动截取的实例(支持中文)
Mar 06 Javascript
jQuery实现验证码功能
Mar 17 Javascript
JQuery实现图片轮播效果
May 08 jQuery
详解基于node的前端项目编译时内存溢出问题
Aug 01 Javascript
本地搭建微信小程序服务器的实现方法
Oct 27 Javascript
微信小程序实现tab左右切换效果
Nov 15 Javascript
JavaScript DOM 学习第三章 内容表格
Feb 19 #Javascript
JavaScript DOM 学习第二章 编辑文本
Feb 19 #Javascript
JavaScript DOM学习第一章 W3C DOM简介
Feb 19 #Javascript
JavaScript 题型问答有答案参考
Feb 17 #Javascript
JavaScript 学习技巧
Feb 17 #Javascript
JavaScript Timer实现代码
Feb 17 #Javascript
两个比较有用的Javascript工具函数代码
Feb 17 #Javascript
You might like
使用 eAccelerator加速PHP代码的目的
2007/03/16 PHP
php empty() 检查一个变量是否为空
2011/11/10 PHP
基于php split()函数的用法详解
2013/06/05 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
2021/03/09 PHP
实现web打印的各种方法介绍及实现代码
2013/01/09 Javascript
jQuery bxCarousel实现图片滚动切换效果示例代码
2013/05/15 Javascript
open 动态修改img的onclick事件示例代码
2013/11/13 Javascript
javascript ajax的5种状态介绍
2014/08/18 Javascript
JS+CSS实现实用的单击输入框弹出选择框的方法
2015/02/28 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
2016/05/27 Javascript
AngularJS下对数组的对比分析
2016/08/24 Javascript
AngularJS监听路由的变化示例代码
2016/09/23 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
JS实现的JSON数组去重算法示例
2018/04/11 Javascript
JS中Promise函数then的奥秘探究
2018/07/30 Javascript
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
JS散列表碰撞处理、开链法、HashTable散列示例
2019/02/08 Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
2019/03/28 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
vue项目中企业微信使用js-sdk时config和agentConfig配置方式详解
2020/12/15 Vue.js
[01:04:09]DOTA2-DPC中国联赛 正赛 iG vs VG BO3 第二场 2月2日
2021/03/11 DOTA
详解Python数据分析--Pandas知识点
2019/03/23 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
2019/06/18 Python
Python opencv相机标定实现原理及步骤详解
2020/04/09 Python
Python Matplotlib简易教程(小白教程)
2020/07/28 Python
TripAdvisor土耳其网站:全球知名旅行社区,真实旅客评论
2017/04/17 全球购物
周仰杰(JIMMY CHOO)英国官方网站:闻名世界的鞋子品牌
2018/10/28 全球购物
利用promise及参数解构封装ajax请求的方法
2021/03/24 Javascript
会计自荐书
2013/12/02 职场文书
少先队学雷锋活动月总结
2014/03/09 职场文书
2014广电局实施党的群众路线教育实践活动方案思想汇报
2014/09/22 职场文书
电工实训报告总结
2014/11/05 职场文书
交通事故案件代理词
2015/05/23 职场文书
教你怎么用Python处理excel实现自动化办公
2021/04/30 Python
vue3获取当前路由地址
2022/02/18 Vue.js
解决linux下redis数据库overcommit_memory问题
2022/02/24 Redis