引用 extJs 2.0學習筆記(Element.js篇)

Element.js這個文件包含了整個extjs框架中最爲核心的部分,它對DOM元素進行超強的封裝。源文件就有3054行,儘管這中間有好多是註釋,但是,在個把月前,我不敢想像我會要拿着幾千行的js文件來研究。呵呵。

  就我目前而得知的情報,Ext.Element類至少包含如下功能:

  一、爲許多DOM動作創建Animation(動畫),例如setWidth,它提供一個可選項來獲得動畫效果

  二、提供一個偉大的load方法,可以直接ele.load({url:xxxxx}的方式來異步加載數據。超爽、超酷啊。

  其他功能我目前不知,這是看了別人的教程有了這樣一個大概的映像。如果要對它獲得一個大概映像,點此處訪問相關資源!通過這個資源,幾乎就可以動手寫程序了。

  廢話就不多講了,還是來研究研究源代碼。

  一、Ext.Element的緩存機制

Ext.Element = function(element, forceNew){
    var dom = typeof element == "string" ?
            document.getElementById(element) : element;
    if(!dom){ // invalid id/element
        return null;
    }
    var id = dom.id;
    if(forceNew !== true && id && Ext.Element.cache[id]){ // element object already exists
        return Ext.Element.cache[id];
    }

    this.dom = dom;

    this.id = id || Ext.id(dom);
};

  Ext.Element提供了緩存機制,作用:提高性能;原理:讓構造過Ext.Element存放在json對象中,如果要再次獲得這個對象就不用再次構造,只需從緩存中取出即可。原理很簡單。

  上面函數是Ext.Element的構造函數,其中forceNew表示是否強制創建一個新對象,不管緩存中是否已存在。這個構造函數還強制爲元素生成id。

  緩存定義在哪?在代碼的最後面有一行代碼:El.cache = {};可見,緩存是全局的。這是必然。再看看大夥平常用得最多的函數。Ext.Element.get。這個函數都有四十幾行的代碼,因爲整個函數考慮到可能傳入參數的類型有好幾種的情況,情況多起來,所以有點多。

  二、Ext.fly倒底有什麼用?

  Ext.Element有一靜態成員fly。它也是獲得一個Ext.Flyweight對象的實例。當然,它也是對元素的包裝,請見代碼:

  var flyFn = function(){};
  flyFn.prototype = El.prototype;
  var _cls = new flyFn();

  // dom is optional
  El.Flyweight = function(dom){
   this.dom = dom;
  };

  El.Flyweight.prototype = _cls;
  El.Flyweight.prototype.isFlyweight = true;

  看清代碼了吧?可以說,Flyweight是繼承自Element的。不過,正如其名,它是輕量級的。爲什麼這麼說呢?見fly的代碼:

El.fly = function(el, named){
    named = named || '_global';
    el = Ext.getDom(el);
    if(!el){
        return null;
    }
    if(!El._flyweights[named]){
        El._flyweights[named] = new El.Flyweight();
    }
    El._flyweights[named].dom = el;
    return El._flyweights[named];
};

  這個代碼的關鍵是,它總是會取得同一個Flyweight對象,用fly取的時候,只要沒有傳named,所有取的對象都同一個,換的只是dom罷了。

  有人問這有什麼好處?好處大了,如果有1000個元素,要調用它們的hide隱藏,如果用Ext.get的話,就會創建1000個Element對象,如果用fly,那隻會創建一個對象。這對性能帶來巨的提升。所以,在有一些批量式的操作時,用fly要好一些。

  三、對Element.findParent、Element.findParentNode的質疑!!

  原來如此,本來以爲它是尋找的對象不包括自己,我總以爲沒有得到結果,原來,這兩個函數是從自己找起的,如果一個元素是div,如果它用findParent找div祖先的話,那找的總是自己。

  這個問題是解決了,不過,我對findParent的代碼有疑問,它裏面用Ext.getDom(maxDepth)來獲得最極限層次的那個節點,事實上,我把getDom傳數字的話只會返回數字本身,根本不會返回元素。這個問題我一直想不通。不過,這並不會影響表面上的功能。只是設maxDepth相當於白設了。

  四、Element的動畫支持

  Element要使用動畫有三大類方法。

  1. 直接調用Ext.Element的animate函數,它建立於Ext.lib.Anim類的基礎之上,而Ext.lib.Anim是Adapter裏面的類。
  2. 在調用Ext.Element的一些設置大小、位置、範圍、透時度時,那些函數往往有一個參數,anim,設一設它,也能獲得動畫效果。
  3. 調用從Ext.Fx類中繼承過來的方法,如果頁面包含了Ext.Fx,那麼就可以用所有在Ext.Fx中定義過的函數了。

  一般多用後面兩種方法。出人意料的是,Ext.Element繼承了Ext.Fx。代碼上反應在哪裏呢,在Ext.Fx的最後面,有這樣一行代碼:Ext.apply(Ext.Element.prototype, Ext.Fx);這樣一來,在Element中就可放心地使用特效了。關於對Element使用動畫,這個現在不是研究重點,這個Ext.Fx要研究的內容。在此一筆帶過,實在急於這個問題的,可以點此處閱讀相關參考資料

  五、設置位置、大小、絕對位置、相對位置等等於關定位、範圍的函數

  這是個大問題,事實上,前一週我重點就在搞這個問題,例如:

  1. 如何取得相對於定位容器的座標
  2. 如可取得相對於頁面文檔的座標
  3. 如何取得元素的大小,包括邊框、內邊距、實際內容
  4. 如何取得相對於元素的座標(偏移量)
  5. 如何取得視口大小
  6. 如何取得當前文檔水平滾動、垂直滾動的距離
  7. 如何取得當前元素相對於視口左上角的座標

  問題多吧。這些問題在平常計算時多要用到這些量,然而這些量與瀏覽器類型嚴重相關。不同瀏覽器取法不一樣。麻煩、頭痛啦。還好,這個問題Ext.Element都對此進行了封裝。不用我們煩心了。當然,上面還僅僅是取得,還有設置這些量的問題,這就至少十五、六個函數了。Ext.Element又是英文文檔,給我們的理解造成了困難吶。下面來把這些東西找出來。到了這裏,我再次想起asp.net ajax,這個東西現在與extJs比起來屁都不是啊。在asp.net ajax中,就封裝一丁點的東西,它裏面的DomElement相當於Element了,只是功能完全不能比,就只有create、addClass、removeClass、toggleClass,關於我上面提出的七個問題,一個都沒有解決。這個框架有跟沒有一樣。如果有兄弟正在用asp.net ajax,最好還是換一換,換誰都不要用asp.net ajax啊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章