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方法简洁实现隔行换色及toggleClass的使用
Mar 15 Javascript
javascript实现点击商品列表checkbox实时统计金额的方法
May 15 Javascript
jQuery中JSONP的两种实现方式详解
Sep 26 Javascript
jQuery利用sort对DOM元素进行排序操作
Nov 07 Javascript
Bootstrap常用组件学习(整理)
Mar 24 Javascript
ES6新特性三: Generator(生成器)函数详解
Apr 21 Javascript
zTree获取当前节点的下一级子节点数实例
Sep 05 Javascript
Vue-cli创建项目从单页面到多页面的方法
Sep 20 Javascript
深入浅析vue组件间事件传递
Dec 29 Javascript
浅谈angular表单提交中ng-submit的默认使用方法
Sep 30 Javascript
javascript实现简易聊天室
Jul 12 Javascript
Node.js API详解之 dns模块用法实例分析
May 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
PHP环形链表实现方法示例
2017/09/15 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
javascript获取当前ip的代码
2009/05/10 Javascript
基于jquery实现的一个选择中国大学的弹框 (数据、步骤、代码)
2012/07/26 Javascript
nodejs教程之入门
2014/11/21 NodeJs
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
2016/11/04 Javascript
Bootstrap Table使用整理(四)之工具栏
2017/06/09 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
JavaScript仿微信(电话)联系人列表滑动字母索引实例讲解(推荐)
2017/08/16 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
vue 实现数字滚动增加效果的实例代码
2018/07/06 Javascript
详解js获取video任意时间的画面截图
2019/04/17 Javascript
[54:56]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第三局
2016/03/06 DOTA
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Python标准库之循环器(itertools)介绍
2014/11/25 Python
Python简单实现Base64编码和解码的方法
2017/04/29 Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
2017/12/20 Python
对numpy中轴与维度的理解
2018/04/18 Python
Python中的函数作用域
2018/05/07 Python
对Python3之进程池与回调函数的实例详解
2019/01/22 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
python时间time模块处理大全
2020/10/25 Python
一款利用纯css3实现的win8加载动画的实例分析
2014/12/11 HTML / CSS
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
微软俄罗斯官方网站:Microsoft俄罗斯
2016/09/18 全球购物
澳大利亚新奇小玩意网站:Yellow Octopus
2017/12/28 全球购物
电大毕业生自我鉴定
2013/11/10 职场文书
求职简历中个人的自我评价
2013/12/01 职场文书
党员岗位承诺书
2014/03/25 职场文书
合唱兴趣小组活动总结
2014/07/10 职场文书
2015年见习期工作总结
2014/12/12 职场文书