有思俱乐部学习园地

uform前端框架-前端编码注意事项


开发时打开错误开关:

   
    原因:
        因部署时不允许显示错误信息,所以屏蔽了window.onerror,开发时需要注释此选项。
    操作方法:
        全屏搜索window.onerror = U.MD.D.error。  把此语句注释掉
                

不能污染document的所有事件:

   
    示例:
        document.onmousemove=function(){}  这些会覆盖document.onmousemove原本的事件。
    建议:
        1、onmousemove不写在document里面,建立一个div元素,把onmousemove写在div上面。
        2、建议用document的事件绑定。可参考以下源代码
        * 注册函数事件 Internet Explorer 8 及更早IE版本不支持 addEventListener() 方法,,Opera 7.0 及 Opera 更早版本也不支持。 但是,对于这些不支持该函数的浏览器,你可以使用 attachEvent() 方法来添加事件句柄 
        ** @param  {string} 事件名称
        * @param  {element} 添加事件的元素
        * @param  {function} 事件触发后调用的函数
        * @param  {string} 指定事件是否在捕获或冒泡阶段执行
        U.UF.EV.addElementEvent = function (str1, el, fun, isbubble) {
            if (el.addEventListener) { //非IE使用
                el.addEventListener(el, fun, isbubble || false);
            }
            else if (el.attachEvent) { //IE
                el.attachEvent("on" + str1, fun);
            }
            else {//兼容ie6以下
                el["on" + str1] = function () {
                    el["on" + str1]();
                    fun();
                }
            }
        }             
                

事件赋予空值的方法:

   
        示例:
        最严格的写法,兼容所有浏览器 document.onclick=function(){} 
        不兼容ie6,ie7 document.onclick=null;
        不兼容ie系列 document.onclick=false;
                

event、keycode等event下的兼容不用考虑,uform已自带兼容:

   
        注意:兼容文件在Usetudio.Manage的js/uform/compatible.js下,如有疑问可在该文件中查看源码.
未引ufrom时
    示例: 
        document.onkeydown=function(e){
            var event = window.event || arguments.callee.caller.arguments[0] || e;  //兼容性处理
            var keyCode = e.keyCode || e.which || e.charCode; //兼容性处理
            var target = event.target || event.srcElement;    //兼容性处理  
        } 

引ufrom后
    示例:
        兼容所有浏览器 
        document.onkeydown=function(e){
            var event = window.event;  //已经过框架兼容处理
            var keyCode = e.keyCode    //已经过框架兼容处理
            var target = event.srcElement;//已经过框架兼容处理
        } 
                

添加html代码到js时规范

   
一般做控件时都需要动态添加html代码;
但最好不用document.body.innerHTML += 添加html代码。
为什么不能用 document.body.innerHTML += ? 
举个例子:
    html:
    <button id="btn">我是按钮</button>
    js:
    var _btn = $("#btn")[0];
    _btn.onclick = function(){
        alert('由于下面写了document.body.innerHTML += 因此本次函数不会再执行');
    }
    document.body.innerHTML += '111';
    这时按钮的onclick 事件无效;
    原因:
    document.body.innerHTML += '111' 相当于 document.body.innerHTML = document.body.innerHTML + '111' 
    意思就是说之前的html被重新刷新了一遍,因此变量_btn 不再等于 $("#btn")[0];
    
解决办法:     
    创建一个div,在appendChild到document.body
示例:
    html:
    <button id="btn">我是按钮</button>  
    js:
    var _btn = $("#btn")[0];
    _btn.onclick = function(){
        alert('由于_box 这次_btn 没有刷新,因此此处函数会执行');
    }
    var _box = $$("div",{id:'box'},document.body);
    _box.innerHTML += '111';
                

滚轮事件、冒泡、捕获鼠标事件等事件已全部兼容:

   
        注意:兼容文件在Usetudio.Manage的js/uform/compatible.js下,如有疑问可在该文件中查看源码.

捕获鼠标事件

详细:捕获鼠标事件
未引uform时
    示例:
        document.onmouseover=function(){
            if (!window.captureEvents) {        //兼容判断
                this.setCapture();              //区别
                console.log("捕获成功");        
            }else {
                this.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);  //区别
                console.log("捕获成功");
            }
        }

引ufrom后
    示例:
        document.onmouseover=function(
            this.setCapture();              //区别 省去window.captureEvents的兼容判断
            console.log("捕获成功")
        }

滚轮事件兼容

详细:滚轮事件兼容
未引uform时
    示例:
        var scrollFunc = function(e){
            console.log(e);
        }
        if (document.addEventListener) {    
            document.addEventListener('DOMMouseScroll', scrollFunc, false); 
        }//Firefox 
        window.onmousewheel = document.onmousewheel = scrollFunc; //IE/Opera/Chrome/Safari  

引ufrom后
    示例:
        window.onmousewheel = function (e) {        //直接省去Firefox兼容 已经过框架兼容处理
            console.log(e);
        }   

冒泡事件兼容

详细:冒泡事件兼容
未引uform时
    示例:
        document.onclick = function(e){
            var e=arguments.callee.caller.arguments[0]||event; //若省略此句,下面的e改为event,IE运行可以,但是其他浏览器就不兼容
            if (e && e.stopPropagation) {                   /*        
                // this code is for Mozilla and Opera           兼容处理
                e.stopPropagation();
            } else if (window.event) {
                // this code is for IE
                window.event.cancelBubble = true;           */
            }
        }

引ufrom后
    示例:
        document.onclick = function(e){
            U.UF.EV.stopBubble(e);                          //已经过框架兼容处理
        }

阻止浏览器默认事件兼容

详细:阻止浏览器默认事件兼容
未引uform时
    示例:
        document.onclick = function(e){
            if(e.prevenDefault){
                e.preventDefault();         //兼容主流浏览器
            }else{
                e.returnValue = false;      //兼容ie
            }
        }

引ufrom后
    示例:
        document.onclick = function(e){
           U.UF.EV.stopDefault(e);                          //已经过框架兼容处理
        }

注册/监听 函数事件兼容

详细:注册/监听 函数事件兼容

未引uform时
    示例:(比如注册一个点击事件) PS:也可以是其他事件 只要将'click'改成其他的事件名称即可
        if(element.addEventListener){                       //这里及以下的element 指的是需要添加点击事件的元素
            element.addEventListener('click',function(){    //此处兼容主流浏览器     
                alert("函数内容!");
            },false);
        }else if(element.attachEvent){                      
            element.attachEvent('on' + 'click',function(){  //此处兼容ie浏览器
                alert("函数内容!");
            });
        }
    
引ufrom后
    示例:
    U.UF.EV.addElementEvent("click",element,function(){
        alert("函数内容!");         //已经过框架兼容处理
    },false)
    这里的false 可填可不填, 默认为false 指的是 事件是否在捕获或冒泡阶段执行
    一般情况下都用false, 如果需要在冒泡阶段执行,则用 true
取消/删除 函数事件兼容

详细:取消/删除 函数事件兼容

未引uform时
    示例:(比如删除一个点击事件) PS:也可以是其他事件 只要将'click'改成其他的事件名称即可
        if(element.removeEventListener){                            
            element.removeEventListener('click',callback,false);    //兼容主流浏览器 的取消函数事件
        }else{
            element.detachEvent('on' + 'click', callback);          //兼容ie浏览器的 取消函数事件
        }

引ufrom后
    示例:
    U.UF.EV.delElementEvent('click',element,callback);  //已经过框架兼容处理

  注意: 这里的参数 callback 指的不是 删除掉函数后 所要做的回调,而是指注册函数时回调函数的名字,
        因此 注册函数事件时如若考虑要删除该事件则记住给该监听事件的回调函数添加名字!
                

函数的内部不允许直接定义函数:

  
错误示例:
    function a(){
        function b(){
            alert("错误示例!");
        }
        b();
    }
正确示例:
    function a(){
        b();
    }
    function b(){
        alert("正确示例!");
    }

注意:只有一种情况可以出现函数,那就是函数内部进行简单的回调
示例:
    function test(){
        var callback = function(){
            alert("只有回调可以这样做,其余情况请分按上面的写法写!")
        }
        document.addEventListener('click',callback, false); 
    }
                

函数注释:

  
PS:在函数头部 打上 /** 然后 按enter键 则会自动弹出注释模板(大部分编辑器都支持)
错误示例:     
    function a(name,age){   //弹出一个 带有名字和年龄的 alert框
        alert("名字是" + name +  ",年龄是:" + age);
    }
正确示例:
    /**
     * 弹出一个 带有名字和年龄的 alert框
     * @param  {[string]} name [名字]
     * @param  {[int]} age  [年龄]
     */             
    function a(name,age){
        alert("名字是" + name +  ",年龄是:" + age);
    }

注意:必须带有参数 和对 整个函数的 注释
                

css样式名不要用 - 命名,统一用 _ 命名:

  

错误示例:
    <div class="U-MD-UI-test"></div>          //注意看class的名字区别

正确示例:                
    <div class="U_MD_UI_test"></div>          //注意看class的名字区别

原因: 用ide的时候不好选择 
比如尝试鼠标双击 U-MD-UI-test 这段样式名时,会发现无法全部选中
再尝试鼠标双击 U_MD_UI_test 时 则可以全部选中 
PS:ide 就是编辑器 例如vs phpstorm webstorm等等
                

做控件时的规范:

  
1.引入命名空间
    注意:这里命名空间规范 可以查看 命名空间
    示例:
    比如电脑的音乐控件:Namespace.register("U.MD.UI.music");
    比如电脑的日历控件:Namespace.register("U.MD.UI.calendar");
    比如手机的音乐控件:Namespace.register("U.MT.UI.music");

2.html代码需要放在js的变量里
    PS:这里的html代码转成js字符串方法: 
    1.准备好phpstorm 或 webstorm等这样的编辑器 个别编辑器不能自动转义
    2.变量 = ' html代码 '  //记住用单引号括起来 
示例:
    U.MD.UI.test.html = '<div id="U_MD_UI_test_controlBox" style="width:200px;height:200px;position:absolute;background:red;">
        <div class="U_MD_UI_test_title">
            这里是控件标题
        </div>
    </div>';    //html代码
       
3.思考所做的控件(html代码)是否是需要添加多个(结合应用场景)
(1)控件只存在一个时: 不建议用new写控件
    比如做的是日历控件时,一个页面 存在 两个需要用到该控件的 input表单(开始时间,结束时间) 但这并不代表
    日历控件就要添加两个,而解决办法是将控件的位置 显示 到 需要用的另外一个input表单下就行.
    详细可参考:日历控件
示例:
    U.MD.UI.calendar.control = function(){  //最后需要调用的函数
        U.MD.UI.calendar.create(); //添加html代码
        U.MD.UI.calendar.init();    //函数初始化
    }
    U.MD.UI.calendar.init = function(){
       U.MD.UI.calendar.addEvent();    //注册函数事件等等
    };     
这里为什么不建议用new的原因是:
    由于控件html元素只有一个,只需通过id就可以查找到元素,因此查看代码
    时比较简单明了.
(2)控件存在多时,建议用new写控件:
    比如做的是窗体控件时,可能一个页面会存在多个窗体页面.
示例:
    U.UF.UI.form = function(){
        this.create();
    }
    U.UF.UI.form.prototype = {
        create:function(){
            this.addEvent();    //注册函数事件等等
        }
    }
这里为什么建议用new的原因是:
    以窗体控件为例,每次new一次就生成1个窗体控件,但是
    每个窗体控件都是独立的相对于自己的,比如要最小化或
    关闭窗体时,只需要将要需要关闭的html元素 写为this的
    变量就好. 
    而如果不用new的话 则每一次的关闭与缩小等操作都要通过窗体的
    元素id来寻找到该元素,这样子就不如new里的this好用了.                 
       
4.调用控件的时候一定是动态添加的
调用方法示例:
U.UF.DL.asynLoadJs({ type: "text/javascript", src: "http://www.1473.cn/js/Controls/U.MD.UI.test.js" }, function () {    //引入js
    new U.MD.UI.test.control();                                                                                         //回调
}); 
U.UF.DL.asynLoadCss({ "href": "http://www.1473.cn/css/Controls/U.MD.UI.test.css", type: "text/css", rel: "stylesheet" });   //引入css
注意:注意修改路径 与 回调
详细可看日历控件的调用方法.

5.控件不能随意将事件类型定死

比如做一个音乐控件:
错误示例:
    控件js代码:
    var U.MD.UI.Music.Control = function(btnId){ //btnId 为按钮id;
        $("#btnId")[0].onclick = funciton(){
            alert('打开音乐控件')
        }
    }

    用户调用:
    html:
    <button id="btn">打开控件</button>
    js:
    U.MD.UI.Music.Control('btn');            //调用方法

这里为什么是错误示例?
原因是因为 只能通过点击元素才能打开音乐控件,有可能用户需求是 按键盘,鼠标移入移出等事件打开音乐控件,因此事件类型不能定死.
PS:除了强制需求要添加指定事件类型的控件,否则都不能将触发控件的事件类型定死.

正确示例:
    控件js代码:
    var U.MD.UI.Music.Control = function(){ //btnId 为按钮id;
        alert('打开音乐控件')
    }
    用户调用:
    html:
    <button id="btn">打开控件</button>
    js:
    $("btn")[0].onmouseover = function(){
        U.MD.UI.Music.Control('btn');            //调用方法
    }
注意:可能这样做会存在函数重复调用,因此需要在控件里添加判断.
6.有变量需要获取html元素的时候 直接通过id获取 不准多层级赋值
例: html: <div id="box"></div>
错误示例:    var a = {
                "box":$("#box");
             }
             var _b = a.box;
正确示例:
    var _b = $("#box");
7.命名空间即是 控件的调用函数名
错误示例:
    Namespace.register("U.MT.UI.Music");
    调用函数声明:
    例1:
    var U.MT.UI.Music.Control = function(){
    }
    例2:
    var U.MT.UI.music = function(){     //大小写即使不一样也是错的
    }
正确示例:
    Namespace.register("U.MT.UI.Music");
    调用函数声明:
    var U.MT.UI.Music = function(){
    }
8.调用控件的函数参数不准大于4个
错误示例:
    var U.MT.UI.Music = function(a,b,c,d,e,f,g){
    }
正确示例:
    var U.MT.UI.Music = function(a,b,c,d){
    }
9.写控件时,要条理分明,不准将所有函数写在同一层作用域下
错误示例:
    var U.MT.UI.Music = function(a,b,c,d){
        var a = function(){     //a功能
        }
        var b = function(){     //b功能
        }
        var c = function(){     //c功能
        }
        a();
    }
正确示例:
    var U.MT.UI.Music = function(a,b,c,d){
        U.MT.UI.Music.a();
    }
    U.MT.UI.Music.a = function(){     //a功能
    }
    U.MT.UI.Music.b = function(){     //b功能
    }
    U.MT.UI.Music.c = function(){     //c功能
    }

                

工作人员

 
作者:黄伟艺
信息录入:黄伟艺