编程模式

命名空间

为了减少命名冲突,最好的办法是定义一个全局变量,并将其他变量和方法定义为该全局变量的属性。

var MYAPP = MYAPP || {};



MYAPP.event = {

    addListener:function(el,type,fn){

        // .. do the thing 

    }

    removeListener:function(el,type,fn){

        // ...

    }

    // ... other methods or properties

};

我们也可以在命名空间中使用构造函数,一般使用大写开头表示构造函数:

MYAPP.dom = {}

//创建元素节点

MYAPP.dom.Element = function(type, prop){

    var tmp = document.createElement(type);

    for(var i in prop){

        tmp.setAttribute(i,prop[i]);

    }

    return tmp;

}

//创建文本节点

MYAPP.dom.Text = function(txt){

    return document.createTextNode(txt);

}

下面使用构造函数来创建一个链接:

//Element对象

var el1 = new MYAPP.dom.Element('a',{href:'http://phpied.com'});

//Text对象

var el2 = new MYAPP.dom.Text('click me');



el1.appendChild(el2);

document.body.appendChild(el1);

初始化分支

不同的浏览器对于相同或相似的方法可能有不同的实现。这时,需要依据当前的浏览器版本来选择对应的执行分支。我们可以在加载脚本是,在模块初始化的过程中就将部分代码进行分支处理。

//先声明事件处理方法

var MYAPP={};

MYAPP.event={

    addListener:null,

    removeListener:null

};



//模块初始化进行定义,它们将根据具体的浏览器特性探测的结果,被赋予不同的实现

if(typeof window.addEventListener === 'function'){

    MYAPP.event.addListener = function(el, type, fn){

        el.addEventLIstener(type, fn ,false);

    }

    MYAPP.event.removeListener = function(el, type, fn){

        el.removeEventListener(type, fn, false);

    }

}else if(typeof document.attachEvent === 'function'){//IE

    MYAPP.event.addListener = function(el, type, fn){

        el.attachEvent('on'+type,fn);

    }

    MYAPP.event.removeListener = function(el, type, fn){

        el.detachEvent('on'+type,fn);

    }

}else{//older browsers

    MYAPP.event.addListener = function(el,  type,  fn){

        el['on' + type] = fn;

    }

    MYAPP.event.removeListener = function(el, type, fn){

        el['on' + type]=null

    }

}

一旦上述脚本被执行,我们就定义了与浏览器特性相关的addListener()和removeListener()方法。如此,当它们再次被调用时,就不需要在探测浏览器特性了,脚本会执行得更快。

延迟定义

延迟定义模式与初始化分支模式很相似。不同之处在于,该模式下的分支只有在相关函数第一次被调用时才会发生,即只有函数被调用时,它才会以最佳实现改写自己。下面的addListener()方法将以泛型的方式来实现,即在它第一次被调用时,首先会检查浏览器支持的功能,然后为自己选择最合适的实现,最后调用自身以完成事件添加。

var MYAPP={};

MYAPP.myevent={

    addListener:function(){

        if(typeof el.addEventListener === 'function'){

            MYAPP.myevent.addListener = function(el, type, fn){

                el.addEventListener(type, fn, false);

            };

        }else if(typeof el.attachEvent === 'function'){

            MYAPP.myevent.addListener = function(el, type, fn){

                el.attchEvent('on' + type, fn);

            };

        }else{

            MYAPP.myevent.addListener = function(el, type, fn){

                el['on' + type]=fn;

            };

        }

        MYAPP.myevent.addListener(el,type,fn);

    }

}

配置对象

下面,假设我们要设计一个Button构造器,将其用于创建输入性按钮。它的参数包括一段文本,即按钮显示的内容和一个可缺省的type参数:

var MYAPP={};

MYAPP.dom={};

MYAPP.dom.Button=function(text,type){

    var b = document.createElement('input');

    b.type = type || 'submit';

    b.value = text;

    return b;

}

该构造器很简单,只需传递给它一个字符串,然后就可以把新创建的按钮加入文档:

document.body.appendChild(new MYAPP.dom.Button('puuush'));

但是接下来,我们需要为按钮设置更多的属性,例如颜色和字体。结果,这个构造器的定义最终就可能变成这样:

MYAPP.dom.Button = function(text, type, color, border, font){

    // ....

}

这显然就不太方便了,比如当我们可能只想设置第三个和第五个参数,就必须这样:

new MYAPP.dom.Button('puuush',null,'white',null,'Arial, Verdana, sans-serif');

这个时候,更好的选中就是用一个可配置的对象参数来代替所有的参数配置:

MYAPP.dom.Button = function(text, conf){

    var type = conf.type || 'submit';

    var font = conf.font || 'Verdaba';

    // ...

}
var config = {

    font:'Arial, Verdana, sans-serif',

    color:'white'

};

new MYAPP.dom.Button('puuush',config);

链式调用

var MYAPP={};

MYAPP.dom=(function(){

    var _setStyle = function(el, prop, value){

        el.setAttribute(prop,value);return this;

    }

    var _getStyle = function(el, prop){

        console.log('getStyle');

    }

    return {

        setStyle:_setStyle,

        getStyle:_getStyle

    };

})();

//创建元素节点

MYAPP.dom.Element = function(type, prop){

    var tmp = document.createElement(type);

    for(var i in prop){

        tmp.setAttribute(i,prop[i]);

    }

    return tmp;

}



var obj = new MYAPP.dom.Element('span');

总所周知,构造器返回的是新建对象的this指针。通过让setStyle()方法返回this,这样,我们就可以直接用这些方法所返回的实例来调用其他方法,这就是所谓的链式调用:

编程模式

JSON

JSON本身实际上是一种轻量级的数据交换格式,由对象和数组标记的数据构成。

{

    'name':'Stoyan',

    'family':'Stefanov',

    'books':['phpBB2','phpBB UG','PEAR']

}

假设服务器返回该JSON字符串,它保存在resp变量中,然后,我们调用eval()将该字符串转换为JavaScript对象:

var obj = eval('('+resp+')');

接着,我们就可以通过obj的属性来访问这些数据了:

alert(obj.name);

alert(obj.books[2])

 

你可能感兴趣的:(编程)