读Ext之十三(Ext成分)

到头来越来越接近Ext的中坚了。那篇开首Ext.Element,那里说的Ext成分指的是Ext.Element类的实例。

 

任何前端库都会波及到对HTMLElement的操作,JQuery更是以其为骨干,三个$()函数调用后将DOM成分以索引方式存在 JQuery对象 中。

 

Ext则利用了3个誉为 Ext.Element 的类,如 Ext.get/Ext.fly
再次来到的都以此类的实例对象。许多操作如样式,添加风浪等都卷入到此类里。

 

Ext.Element的定义大概框架如下

Ext.Element = function(element, forceNew){
    var dom = typeof element == "string" ?
              DOC.getElementById(element) : element,
        id;

    if(!dom) return null;
    id = dom.id;
    if(!forceNew && id && Ext.elCache[id]){ // element object already exists
        return Ext.elCache[id].el;
    }
    this.dom = dom;
    this.id = id || Ext.id(dom);
};
var D = Ext.lib.Dom,
    DH = Ext.DomHelper,
    E = Ext.lib.Event,
    A = Ext.lib.Anim,
    El = Ext.Element,
    EC = Ext.elCache;

El.prototype = {
    ...
}

能够看出,采纳了的是很守旧的JS写类措施:构造器+原型 格局。构造器内执行大致如下

 

1,要是参数element是字符串则利用document.getElementById获取,不然直接回到element(日常是HTMLElement)。

2,给 变量 id赋值,来自dom.id

3,forceNew不传或传false情况下,优先从缓存中取。

4,给this挂上dom和id属性。

 

3处有点绕人,

 

return Ext.elCache[id].el;

 

大家通晓那是在概念3个类,使用new操作符。如

 

var ele = new Ext.Element(‘head’);

 

既然是new,里面怎么又return了吧?一般是函数调用(),里面有return。构造器里一般都以概念一些字段。其实当构造器中return的是目的类型时是同意的,假若return的是基本类型,又选用new调用函数则会油不过生非预期的机能。对于这一点感兴趣的事无巨细:签名函数的八种调用格局 系列

 

组织器内其实很少代码,比较简单。随后是概念了某个变量如D,DH,这么些大部分是在此以前篇幅中关系的。Ext采纳那种简易的设计方式:组合。Bruce埃克el在《Think in Java》中所言,制止滥用继承,多数场所下结合已能够。

 

跟着看挂在prototype上的首先个法子 set

set : function(o, useSet){
    var el = this.dom,
        attr,
        val,
        useSet = (useSet !== false) && !!el.setAttribute;

    for(attr in o){
        if (o.hasOwnProperty(attr)) {
            val = o[attr];
            if (attr == 'style') {
                DH.applyStyles(el, val);
            } else if (attr == 'cls') {
                el.className = val;
            } else if (useSet) {
                el.setAttribute(attr, val);
            } else {
                el[attr] = val;
            }
        }
    }
    return this;
},

该格局用来安装HTMLElement(如div)的属性如id、style、class等。第二个参数是个指标(Hash)如{id:’uname’},第③个参数布尔类型,顾名思义useSet为true尽管用setAttribute来设置属性。

 

至于哪些使用setAttribute,何时使用点操作符(.)给成分设置属性。这里 给出了详细的表明。

 

该方法内部选择for in来遍历对象,大家领略暗中同意情形下 for in
不会去遍历原形链的本性
 的。

 

目标的hasOwnProperty方法对继续于原形链的性格是 检查和测试不到 的,即重临false。因而这里hasOwnProperty(attr)
这么些判断完全是剩下的。

 

紧接着看,又是多少个if分支

 

style,调用DH.applyStyles。但DH.applyStyles方法有bug 。

cls,设置类名(class)

useSet为true,使用setAttribute设置

末段动用中括号操作符(等价于点操作符)

 

看下三个主意 is

is : function(simpleSelector){
    return Ext.DomQuery.is(this.dom, simpleSelector);
},

该办法用来检查和测试dom成分是不是享有给定的css选用器。

 

如对于<div id=”d1″
class=”container”></div>,Ext.get(‘d1’).is(‘.container’)重临的是true。注意字符串container前得有个点。因为是css类接纳器。

 

该形式内部调用Ext.DomQuery.is,暂不提。

 

接下去是 focus 方法,

focus : function(defer, /* private */ dom) {
    var me = this,
        dom = dom || me.dom;
    try{
        if(Number(defer)){
            me.focus.defer(defer, null, [null, dom]);
        }else{
            dom.focus();
        }
    }catch(e){}
    return me;
},

focus方法用来博取关节,defer为数字,即延迟函数调用的时间,单位是皮秒。

 

参数dom对于使用Ext库的客户端程序员来说是用不到的,仅提供给库内部使用,即递归调用。

me.focus.defer(defer, null, [null, dom]);

那句较难领会,即递归调用。me是this,this是Ext.Element对象自小编。在focus内部又调用本人。

 

me.focus.defer 中的 defer哪来的?
还记得第3篇 原型扩充
中关系的为Function.prototype扩大的defer方法吗?没错,便是它。

 

假使没有传defer,那么直接调用dom.focus。那里运用了try
catch,是因为某个景况下会出十分。

 

接下去是 blur 情势,异常的粗略就不说了。往下看 getValue 方法

getValue : function(asNumber){
    var val = this.dom.value;
    return asNumber ? parseInt(val, 10) : val;
},

获得成分的value,一般是form内成分如input,select,textarea等。这里很巧妙,假使asNumber为true则偷偷的将其 转换为数字类型 了。

 

接下去是 addListener /  removeListener / removeAllListeners /
purgeAllListeners
 ,它们中间使用的是Ext.伊夫ntManager。第九篇 提到了,不说了。

 

往下是 addUnits 方法,该办法是中间用的。暂不提。

 

接下去是 load 方法

load : function(url, params, cb){
    Ext.Ajax.request(Ext.apply({
        params: params,
        url: url.url || url,
        callback: cb,
        el: this.dom,
        indicatorText: url.indicatorText || ''
    }, Ext.isObject(url) ? url : {}));
    return this;
},

该办法把请求再次回到的html片段作为该因素的innerHTML填充。内部调用的是Ext.Ajax.request。

 

接着是isBorderBox 方法

isBorderBox : function(){
    return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
},

标准方式中对于有所border的要素如select会再次来到1,怪异形式中对此input,select,textarea成分重返1。若是还是不是那一个因素会直接重临Ext.isBorderBox。

isBorderBox = isIE && !isStrict,

 

接下去是 remove 方法,

remove : function(){
    var me = this,
        dom = me.dom;

    if (dom) {
        delete me.dom;
        Ext.removeNode(dom);
    }
},

该方法会删除该dom成分,包蕴dom文书档案中的,ext缓存中的,及dom元素上的事件handler。

 

往下是 hover 方法,

hover : function(overFn, outFn, scope, options){
    var me = this;
    me.on('mouseenter', overFn, scope || me.dom, options);
    me.on('mouseleave', outFn, scope || me.dom, options);
    return me;
},

意思及用法就不提了,内部使用me.on,on是addListener的简写。mouseenter和mouseleave
的落实在 第四篇Ajax, 提到
了。

 

接着是 contains 方法,

contains : function(el){
    return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
},

判定是不是包涵el成分,内部贯彻也在第5篇中涉嫌。

 

再看 getAttribute 方法,

getAttribute : Ext.isIE ? function(name, ns){
    var d = this.dom,
        type = typeof d[ns + ":" + name];

    if(['undefined', 'unknown'].indexOf(type) == -1){
        return d[ns + ":" + name];
    }
    return d[name];
} : function(name, ns){
    var d = this.dom;
    return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
},

该办法用来获取成分的属性值。能够看来对于IE和非IE有七个本子,IE中对undefined,unknow类型做了拍卖。其余浏览器则是正经的完结。

 

最后二个是 update 方法,

update : function(html) {
    if (this.dom) {
        this.dom.innerHTML = html;
    }
    return this;
}

该办法运用innerHTML来更新元素内容。

 

Element.js

 

相关文章