频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

3.11 融合HTML DOM支持的完美通用对象迭代器模型设计之each

作者: 夏天 出处:电子工业出版社博文视点  2008-04-16 09:36    砖    好    评论   进入论坛
阅读提示:《JavaScript高级应用与实践 》第3章重点讲了Object扩展和性能及Web应用之神兵利器,本节将要为大家展示的是融合HTML DOM支持的完美通用对象迭代器模型设计之each,以及示意图。

3.11  融合HTML DOM支持的完美通用对象迭代器模型设计之each
这就是Web项目中通神的绝技,它与后面的XPath珠联璧合为B/S【browser/Server】项目中的天工神器。
许多JavaScript开源框架都做了迭代器,笔者认为始终有些难以尽如人意。它们不是只能给它们自定义的对象进行迭代,就是只能对Array对象进行迭代。笔者这里所讲的迭代器就是要打破这个常规,无论是你自己定义的对象也好,function也好、Object也好、Array也好、String也好、HTML DOM对象也好,都力求支持,并且只要你将下面代码引入,你的这些对象不需要任何改动就可以使用迭代的功能了。
不过要声明的是,这里支持的顺序是:Array、Function或者Object和自定义对象、HTML DOM对象,最后才是String对象。
从此以后,你要对arguments等对象进行迭代,无须用_A来转换就可以直接用each进行迭代了,具体设计请见下面的代码。

    <html>
<head><meta http-equiv=content-type content="text/html; charset=utf-8">
<title>测试“通用对象迭代器模型设计之each”</title>
</head>
<body>
<div>第一个Div
<div>p1.1个
<div>最深的Div</div>
</div></div>
<div>第二个Div</div>
<div>第三个Div</div>
<script type="text/javascript" language="JavaScript"
src="/jcore/resource /javascript/Jcore.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
// 由于下面的弹出结果比较多,因此我每个只给出第一个的图

// 初始化,给任何JavaScript对象赋予length的属性
Object.prototype.length = 0;

// 功能描述:获取当前元素个数
// 返回信息:元素的个数
// 使用指南:[].size(); // 等于0
// 应用范围:各种Web客户端和服务端开发
Object.prototype.size = function()
{
return this.length = (this.obj || this).length
};

// 功能描述:获取指定下标的元素,下标从0开始
// 返回信息:返回获取的元素
// 使用指南:[554].get(0); // 等于554
// 应用范围:各种Web客户端和服务端开发
Object.prototype.get = function(n)
{
return this[n];
};

// 功能描述:对象迭代器,支持能用[0 ~ n]方式访问,并有length属性的各种对象
// 如果需要深层迭代,则在最后一个参数传入true,默认是false
// 设计中支持N个迭代器
// 这里出现后我们用它来替换Jcore.js里的Array.prototype.each
// 返回信息:返回当前对象,因此你可以连续多次each
// 使用指南:
// [213,234].each(function(a){alert(a)}).each(function(a)
// {alert(a)}).each(function(a){alert(a)});
// 应用范围:各种Web客户端和服务端开发
// 功能描述:根据一个名称或id返回一个对象数组,
// 第8章讲解内容,这里先提到Jcore里去
// 返回信息:返回取到的数组
// 使用指南:fnGetObjs('myid')
// fnGetObjs('myInputName'),fnGetObjs('dto(aac009)')
// fnGetObjs('input');// 返回所有的input对象
// 应用范围:各种Web客户端和服务端开发
var fnGetObjs = Object.prototype.fnGetObjs = function(s)
{
// 支持从外面指定当前的window对象,我们往往需要在弹出窗口中获取
// 父窗口里的对象
var oWin = this.win || window, o = this.obj || oWin.document, oRst = [], oBjs;
oBjs = oWin.document.getElementsByName(s);
if(0 < oBjs.length)
return _A(oBjs).each(function()
{
// 如果不支持包含contains这个方法的判断或者已经包含
if(!o.contains || o.contains(this))
oRst.push(this)
}), oRst;
oBjs = oWin.document.getElementById(s);
if(!oBjs)
{
// 如果有o.getElementsByTagName为真才执行后面的表达式,
// 并返回其结果
return o.getElementsByTagName && _A(o.getElementsByTagName(s)). each(function()
{
if(!o['contains'] || o['contains'](this))oRst.push(this)
}), oRst;
return [];
}
return [oBjs];
};


// 这里提供给HTML DOM对象迭代的简化写法
// 原本写({obj:oMyHtmlDom}).each(...)的,现在写J(oMyHtmlDom).each(...)就可以了
// 这里出现后将移进Jcore.js里,以后使用的地方将不再说明
// 使用举例
/*
// 'myTestDiv'.XPath()[0]其实也可以直接用'myTestDiv'就可以了
J('myTestDiv'.XPath()[0]).each(function()
{
// 如果有属性value就赋予其值, 注意,后面的( )是必需的,因为逻辑运算符号优先于赋值符号
'value' in this && (this.value = 'good');
}, true);
*/
var J = Object.prototype.J = function(o)
{
// 直接传递一个函数参数,就认为是要在页面加载完后执行它
if("function" == typeof o)
{
fnAddEvent(window, "onload", o);
return this;
}

// 如果你希望传入回调函数的方式来非阻塞处理XPath的结果,
// 可以在第二个参数传入回调函数,
// 回调函数的入口参数、上下文this就是XPath选择的结果
if(1 < arguments.length && Function == arguments[1].constructor)
{
var oCbkFunc = arguments[1];
// fnRegCbkFun参见“第7章7.4节”
fnRegCbkFun(function()
{
var a = J(o);
oCbkFunc.call(a, a);
delete a;
}, arguments[2] || 13);
return [];
}
var nCount = 0, szT;
// new XPath(o)的形式兼容传入id,tagName或Xpath的情况
o = String == o.constructor ? new XPath(o) : _A(o);
// 支持动态行为的设计的好处是功能强大,不随浏览器的升级而不支持
// 缺点是每次都需要对每个对象进行for in处理,效率会受到影响
// 所以笔者以IE为标准,以53个事件为最大范围动态生成53个动态绑定事件的方法
// 如果你把下面注释的代码注释打开,那么就支持上面描述的功能
// 如果你不打开,我们已经在本代码的后面部分用静态的方式支持事件绑定函数
return o/*.each(function()
{
// 动态支持绑定N个事件的设计,即使是浏览器升级后有新的事件类型也支持
for(var k in this)
if(0 == k.indexOf("on"))
{
   if(nCount >= 53)throw {message:"避免性能问题",jname:"J"};
   szT = k.substr(2);
   // !!!就是将变量转换为Boolean,判断它是否 “不”为真
   if(!o[szT])
   {
     nCount++;if('click' == szT)alert("J: " + szT)
     // 这样就支持J('myTest')['click'](function(){}) ... J('myTest')['change'](function(){})这样的方法了
     o[szT] = (function(func)
     {
        // 这里提取出来的目的是下面的迭代器里将要用到它
        var szTp = this.type;
        // 迭代所有元素,都绑定func行为响应函数
        return this._this.each(function(a,i)
        {
          fnAddEvent(this, szTp, func);
        });
        delete szTp;
     // 这里将当前的对象和HTML对象以及绑定行为的事件名一起bind进去,好便于操作
     }).bind({_this:o, obj:this, type:k});
   }
}
})*/;
};

// 下面演示Array的迭代,并且使用两个迭代器,实际上支持传入N个迭代器
[10, 11, [234, 99],12, 13].each(function()
{
alert("Array: 第一个迭代器:" + this);
},
function()
{
alert("Array: 第二个迭代器:" + (this + 33));
}
//  ,true // 如果想打开深层迭代,请去除行首的两个“/”,
// 同时也请读者朋友留意代码这样布局的好处
);

// 效果参见图3-11
// 这里演示String对象的迭代
"风说,我来自我去的地方……".each(function()
{
// 不过请注意,双字节的符号、汉字、其他语言字符,当做一个迭代对象
alert("String: " + this);
});

// String的迭代,效果参见图3-12
// 下面演示的是Object和HTML DOM的迭代
// {}表示创建一个匿名Object对象,({})是必须的,
// 否则JavaScript语法检查器不会认为你调用这个临时对象的方法
// 下面两种写法功能完全相同
// ({obj:document.body}).each(function()
J(document.body).each(function()
{
// 依次正确弹出,由于这里结果比较多,所以就不再一一给出图示
// 不过请注意
alert("Object和HTML DOM:\nnodeType = " + this.nodeType + "\n\nnodeValue = " + this.nodeValue + "\n" + this.innerHTML);
// 这里可以写你自己的迭代处理,比如设置属性等操作
},
true // 深度迭代,这在我们对HTML对象进行迭代筛选的时候非常有用
);
// HTML对象的迭代,请参见图3-13
// 下面演示function的迭代,其实function也是一个特殊的Object对象
function fnTestFunctionEach()
{
try{
// 使用fnCatch(e)的前提条件
fnTestFunctionEach.name = "fnTestFunctionEach";
this.length = 0;
// 这里前面已经说过,它等于this[0] = 45, …this[2] = 20070809;
// 不过下面的写法更加精妙罢了
[].push.apply(this, [45, 123, 20070809]);
}catch(e){fnCatch(e)}
}
// 效果请参见图3-14
new fnTestFunctionEach().each(function(){
// 不过请注意,双字节的符号、汉字、其他语言字符,当做一个迭代对象
alert("fnTestFunctionEach(" + arguments[1] + "): " + this);
});

-->
</script>
</body>
</html>

 
图3-11  Array迭代
 
图3-12  String的迭代
 
图3-13  HTML对象的迭代
 
图3-14  一般对象的迭代
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节
专题
C和指针
思科全球CEO钱伯斯第七次访华
应试捷径—典型考题解析与考点贯通( 系统分析师考试)
软件安全:使安全成为软件开发必需的部分
Linux系统管理技术手册(中文第二版)
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
思科全球CEO钱伯斯第七次访华
思科全球CEO钱伯斯第七次访华
北漂技术人90天求职纪实
北漂技术人90天求职纪实
2007年互联网大会
2007年互联网大会
· 2007年互联网大会
· 龙芯要做中国的“奔腾”
· IPv6协议--拓展网络无..
· 国际文档格式标准开战
· 微软出价446亿美元收购..
· 贝恩资本携手华为22亿..
· Linux——从菜鸟到高手
· SOA 面向服务架构
· 2008年4月全国计算机等..
· 微软Forefront企业安全..
· 华为员工自杀频频拷问..
· 技术人求职简历完备手册
· 勇闯IT培训黑色围城
· 隐私保护技术探讨
· Windows Server 2008专..
· NAC安全访问控制
ARP攻击防范与解决方案
ARP攻击防范与解决方案
iSCSI应用与发展
iSCSI应用与发展
SQL Server 2008/2005全解
SQL Server 2008/2005全解
· SQL Server 2008/2005..
· SOA 面向服务架构
· SQL Server 2008/2005..
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 中间件应用技术专题
· SQL Server入门到精通
· 病毒查杀专题
· 国际文档格式标准开战
· 路由器设置与口令恢复
· Linux防火墙
· 打造安全服务器
· SOA 面向服务架构
· PHP开发应用手册
· ADSL应用面面俱到
· 入侵防护系统(IPS)初探
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
iSCSI应用与发展
iSCSI应用与发展
· iSCSI应用与发展
· 中间件应用技术专题
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 病毒查杀专题
· 路由器设置与口令恢复
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· ADSL应用面面俱到
· ADSL应用面面俱到
· 反垃圾邮件技术应用
· PHP开发应用手册
· 中间件应用技术专题