java里ext_[Java教程]读Ext之十四(Ext元素)

[Java教程]读Ext之十四(Ext元素)

0 2012-05-16 08:00:05

上篇读了Ext.Element的部分方法,这篇继续。El.addMethods方法,var ep = El.prototype;El.addMethods = function(o){ Ext.apply(ep, o);};

El是Ext.Element类的简写,addMethods可认为是该类的静态方法。无须new使用类名直接调用。其内部调用的是Ext.apply,该方法会将o上的所有属性方法拷贝到ep上。

使用该方法为Ext.Element类的原型上添加属性,方法。如Ext中队样式的操作、动画、位置等都是通过该方法扩展。

Ext.apply在 读Ext之一(实用方法)中介绍了。

接着看El.get(该类的静态方法),El.get = function(el){ var ex, elm, id; if(!el){ return null; } if (typeof el == "string") { // element id // 先使用document.getElementById获取,如果不存在直接返回null if (!(elm = DOC.getElementById(el))) { return null; } if (EC[el] && EC[el].el) { ex = EC[el].el; ex.dom = elm; } else { ex = El.addToCache(new El(elm)); } return ex; } else if (el.tagName) { // dom element if(!(id = el.id)){ id = Ext.id(el); } if (EC[id] && EC[id].el) {// 先从缓存(Ext.elCache)中取 ex = EC[id].el; ex.dom = el; } else { ex = El.addToCache(new El(el));// new一个Ext.Element再将其放入缓存中(Ext.elCache) } return ex; } else if (el instanceof El) { if(el != docEl){ el.dom = DOC.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid, // catch case where it hasn't been appended } return el; } else if(el.isComposite) { return el; } else if(Ext.isArray(el)) { return El.select(el); } else if(el == DOC) { // create a bogus element object representing the document object if(!docEl){ var f = function(){}; f.prototype = El.prototype; docEl = new f(); docEl.dom = DOC; } return docEl; } return null;};

该方法是Ext中很重要的方法,用来获取Ext元素(Ext.Element)而不是HTMLElement。想获取对应的HTMLElement,可以这么使用Ext.get('id').dom;Ext.get是该方法的别名。通常直接使用Ext.get而不是Ext.Element.get。该方法内部实现如下,分支1,传id

先使用document.getElementById获取,如果不存在直接返回null。存在的话,先从缓存(Ext.elCache)中取,否则new一个Ext.Element再将其置入缓存中(Ext.elCache)分支2,传HTMLElement对象

与传id类似,取到id后先从缓存中去,没有则创建Ext.Element再将其置入缓存后返回。

分支3,传Ext.Element对象

如果不是docEl(一个临时类),则修改所传参数的dom属性(更新dom)然后返回。分支4,传Ext.CompositeElementLite对象

Ext.CompositeElementLite 在后续会介绍,这个类用来操作批量的Ext.Element。

分支5,传数组

使用El.select返回,El.select后续介绍。分支6,传document

如果docEl不存在则创建。因为document是唯一的,因此该对象只创建一次。后续直接返回即可。可以看到docEl与普通Ext.Element不同之处在于其dom属性一个是document,一个则不是。

分支1中用到了Ext.addToCache,El.addToCache = function(el, id){ id = id || el.id; EC[id] = { el: el, data: {}, events: {} }; return el;};

可以看到即把Ext.Element元素以id为key存放到Ext.elCache中。

存放的改对象有三个属性,el是Ext.Element的实例对象,data用来存储数据(El.data用到),events用来存放事件。再往下是El.data方法,该方法是供库内部使用的,它即是setter也是getter。El.data = function(el, key, value){ el = El.get(el); if (!el) { return null; } var c = EC[el.id].data; if(arguments.length == 2){ return c[key]; }else{ return (c[key] = value); }};

可以这么测试,var p1 = document.getElementById('p1');Ext.Element.data(p1,'name','jack'); // setterExt.Element.data(p1,'name'); // getter

经常使用jQuery的人会想到 $.data ,接口于此类似。当然jQuery还有$().data。接下来是garbageCollect函数,function garbageCollect(){ if(!Ext.enableGarbageCollector){ clearInterval(El.collectorThreadId); } else { var eid, el, d, o; for(eid in EC){ o = EC[eid]; if(o.skipGC){ continue; } el = o.el; d = el.dom; if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){ if(Ext.enableListenerCollection){ Ext.EventManager.removeAll(d); } delete EC[eid]; } } // Cleanup IE Object leaks if (Ext.isIE) { var t = {}; for (eid in EC) { t[eid] = EC[eid]; } EC = Ext.elCache = t; } }}El.collectorThreadId = setInterval(garbageCollect, 30000);

可以看到,每隔30秒会进行一次垃圾回收。即遍历Ext.elCache。取Ext元素的dom属性,如果存在以下条件则清空(包括其上的所有事件handler)

1,dom不存在

2,dom的父元素不存在

3,页面上获取不到该dom元素接下来是Ext.fly,该方法实际上是Ext.Element.fly的别名,客户端程序员多数时候使用Ext.fly而非Ext.Element.fly。var flyFn = function(){};flyFn.prototype = El.prototype;El.Flyweight = function(dom){ this.dom = dom;};El.Flyweight.prototype = new flyFn();El.Flyweight.prototype.isFlyweight = true;El._flyweights = {};El.fly = function(el, named){ var ret = null; named = named || '_global'; if (el = Ext.getDom(el)) { (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el; ret = El._flyweights[named]; } return ret;};

依次定义了flyFn,El.Flyweight。flyFn的原型是Ext.Element.prototype,El.Flyweight的原型是flyFn的实例对象。

即El.Flyweight类继承了Ext.Element类原型上的所有属性,方法。El.Flyweight.prototype.isFlyweight = true;该句通过isFlyweight标示对象是否为Ext.Element.Flyweight类型对象。El._flyweights暂存该类型对象,为一个hash。El.fly 每次调用都会去创建一个Ext.Element.Flyweight对象,存在El._flyweights后返回。示意图如下:

bc91bb04e6e9c61e24c974e4440db8f2.gif

注意:El.fly(即Ext.fly)并未将创建的对象缓存,每次调用都将覆盖之前的(除非每次所传的第二个参数named不同)。

这是Ext.fly不同于Ext.get的地方。这种设计模式称为享元模式(Flyweight),它通过颗粒化将属性分为内部及外部以达到共享从而节省内存。享元模式的实现通常需用到工厂模式。

再往下是Ext.EventManager.on(window, 'unload', function(){ delete EC; delete El._flyweights;});

在页面卸载的最后时刻会清空所有的缓存。

Element.js 本文网址:http://www.shaoqun.com/a/30395.html

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:admin@shaoqun.com。

0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值