亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

prototype Element學(xué)習(xí)筆記(篇一)

 更新時(shí)間:2008年10月26日 00:39:46   作者:  
Element,哈哈哈。遇到正主了,到現(xiàn)在為止才遇到讓我高興的玩意。當(dāng)初Ext.Element可是花三千余行代碼專門來(lái)封裝啊。我倒要看一看它的代碼了。事實(shí)上prototype中我最想研究的只有兩個(gè)內(nèi)容:Element、Selector。這兩個(gè)東西是精華。
先說(shuō)一下Element對(duì)DOM擴(kuò)展的技術(shù)思路,我也是看了一天的代碼,這才有了點(diǎn)心得。
使用prototype,我們最常用的莫過(guò)于$('div1')之類的代碼。從而獲得擴(kuò)展后的element對(duì)象,然后,我們就可以用它的各種擴(kuò)展出來(lái)的方法了,如:
$('div1').addClassName('loading').show();
所以,我們研究Element的擴(kuò)展正應(yīng)當(dāng)以此為入口。
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($(arguments[i]));
return elements;
}
if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
這個(gè)函數(shù)一個(gè)巧妙的遞歸就可以處理多個(gè)參數(shù)的情況,實(shí)在令我贊嘆啊。代碼中的關(guān)鍵是:Element.extend(element),在extend之前,element還僅僅是一個(gè)普通的DOM對(duì)象,extend之后就被擴(kuò)展了,可見,秘密就在extend之中。
既然是Element.extend(element),那么,我們當(dāng)然不能單獨(dú)去研究extend,還是得先了解一下Element是何物。
(function() {
   var element = this.Element;
   this.Element = function(tagName, attributes) {
     attributes = attributes || { };
     tagName = tagName.toLowerCase();
     var cache = Element.cache;
     if (Prototype.Browser.IE && attributes.name) {
       tagName = ' <' + tagName + ' name="' + attributes.name + '">';
       delete attributes.name;
       return Element.writeAttribute(document.createElement(tagName), attributes);
     }
     if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
     return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
   };
   Object.extend(this.Element, element || { });
}).call(window);
這種代碼比較有個(gè)性,基本結(jié)構(gòu)是:(function(){……}).call(window);所以,看到這個(gè)結(jié)構(gòu),就要曉得,省略號(hào)部分出現(xiàn)的this都是指向window的。
var element=this.Element;這行不難理解,但是,關(guān)鍵是this.Element這時(shí)還沒(méi)有被定義。后面則是定義一個(gè)類:window.Element類,它有兩個(gè)參數(shù):tagName、attributes。它的作用就是創(chuàng)建一個(gè)元素,并把一個(gè)純潔的指定標(biāo)簽對(duì)應(yīng)的DOM對(duì)象放入緩存。創(chuàng)建元素后,并且寫入指定的屬性值。這兒要提醒一下:
writeAttribute、readAttribute這兩個(gè)函數(shù)功能顯然,讀、寫屬性,但是,它的代碼并不簡(jiǎn)單啊,它的復(fù)雜性主要源于不同的瀏覽器中,讀、寫屬性的方法的不同。
這是Element類的構(gòu)造函數(shù)的定義,它之后的Element.cache = { };緩存,什么的緩存,不大好描述,各種標(biāo)簽的純潔版DOM元素對(duì)象的緩存?這話說(shuō)得太惡心了。后面緊跟著就是一個(gè):Element.Methods={……},在這里,幾乎定義了所有的擴(kuò)展方法。這里的擴(kuò)展方法都有一個(gè)特征,代碼中沒(méi)有一個(gè)用this的,都是老老實(shí)實(shí)傳進(jìn)去一個(gè)element引用。這是一個(gè)伏筆,為什么要定義成這樣,是有原因的。且容后交待。
現(xiàn)在Element大概說(shuō)了一下,就得講一講Element.extend了。
Element.extend = (function() {
   if (Prototype.BrowserFeatures.SpecificElementExtensions)
     return Prototype.K;
  var Methods = { }, ByTag = Element.Methods.ByTag;
  var extend = Object.extend(function(element) {
     if (!element || element._extendedByPrototype ||
     element.nodeType != 1 || element == window) return element;
    var methods = Object.clone(Methods),
     tagName = element.tagName, property, value;
    // extend methods for specific tags
     if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
    for (property in methods) {
       value = methods[property];
       if (Object.isFunction(value) && !(property in element))
         element[property] = value.methodize();
     }
    element._extendedByPrototype = Prototype.emptyFunction;
     return element;
  }, {
      refresh: function() {
       // extend methods for all tags (Safari doesn't need this)
       if (!Prototype.BrowserFeatures.ElementExtensions) {
         Object.extend(Methods, Element.Methods);
         Object.extend(Methods, Element.Methods.Simulated);
       }
     }
   });
  extend.refresh();
   return extend;
})();
第一行的原理我不大肯定,不說(shuō),下面的代碼看似復(fù)雜,待我抽出它的大概結(jié)構(gòu)來(lái):
var extend=Object.extend(function(element){……},{refresh:function(){……}});
extend內(nèi),第一個(gè)函數(shù)作用是從XXXX.Methods中獲取方法,并復(fù)制到本element中。這兒主要基于這樣的考慮:
一、元素如果是一個(gè)Form,就得從Form.Methods取方法
二、元素如果是表單內(nèi)的可輸入元素,就得從Form.Element中取方法
三、所有元素都應(yīng)當(dāng)從Element.Methods中取得通用方法(后面的refresh所考慮的)。
也就是說(shuō),這兒要考慮多種情況,本來(lái)應(yīng)當(dāng)是個(gè)if語(yǔ)句的事,但是,這兒巧妙地設(shè)計(jì)了一個(gè)Element.Methods.ByTag。從而解決了這個(gè)問(wèn)題。
if (Object.isFunction(value) && !(property in element))
element[property] = value.methodize();
如果Methods中的成員不是函數(shù)或者函數(shù)在element中已存在,則不會(huì)覆蓋。這兒到了關(guān)鍵了,那個(gè)value.methodize(),這時(shí),前面的伏筆生效了,methodize的作用就是把當(dāng)前調(diào)用者傳遞進(jìn)方法。且作為第一個(gè)參數(shù)傳入。它的使用方法一般是:
obj.methodname=functionname.methodize();
這樣,調(diào)用時(shí),obj對(duì)象就會(huì)作為第一個(gè)參數(shù)傳入functionsname這個(gè)函數(shù)。
到此為止,這個(gè)extend函數(shù)中的大概思路應(yīng)當(dāng)清晰了,現(xiàn)在還有一個(gè)問(wèn)題沒(méi)有清楚:根據(jù)元素的tagName來(lái)獲得應(yīng)當(dāng)從哪個(gè)Methods獲得擴(kuò)展,那么,我們有必要了解一下ByTag的詳情,查找一下,找到了:
Object.extend(Element.Methods.ByTag, {
"FORM": Object.clone(Form.Methods),
"INPUT": Object.clone(Form.Element.Methods),
"SELECT": Object.clone(Form.Element.Methods),
"TEXTAREA": Object.clone(Form.Element.Methods)
});
ok,差不多就這樣了。

相關(guān)文章

最新評(píng)論