<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> |