注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

那个啥

哥现在只在这摘新闻了,谢绝跨省追捕

 
 
 

日志

 
 

关于大型工程前端Javascript类库体系架构和通用性的一些思考  

2007-04-30 14:04:02|  分类: Web技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
目标:组建一个良好的Web前端行为类库体系架构,通用,灵活,科学

案例:最近学习仿造网易博客的一个简单页面

功能:模块拖动,选项卡

(代码应该执行不了,jQuery类库太长,贴不进来。。。大家可以考出去再下个jquery包测试下,实在不好意思。。。)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="utf-8"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>心飞的空间 - Lan天才的个人空间</title> <style type="text/css">}margin-left:15px;}margin-left:15px;} } body{ font-size:12px; font-family:Verdana,Arial,Helvetica,sans-serif,"宋体"; } /**************************** Color ****************************/ body{ background-color:#eee; color:#333; } a{ color:#666; } a:hover{ color:#999; } #holder{ background-color:#fff; background-color:#fff; } #nav{ background-color:#ddd; } #nav menu li a{ color:#333; background-color:#eee; background-color:#eee; background:#fff; background:#fff; filter:alpha(opacity=75); background:none; font-size:26px; background:url(nav_bg.jpg) repeat-x; } /*************************** Body & background:#e0e0e0;}background:#eee;border-bottom:1px solid #ddd;clear:both;}} #winLogin menu li.active{background:#fff;}} </style> <script language="javascript" type="text/javascript" ></script> <script language="javascript" type="text/javascript"> $(function(){ var modulesDrag=new UI.ModulesDrag({root:"#main",handleTag:"DT"}); var userLogin=new UI.OptionCard({root:$("#winLogin>dd"),isHover:true}); }); var Common={ } }; var UI={};String|jQObject>:根节点<"#id"|jQuery对象> @menuTag<String>:菜单组根标签名 @cardTag<String>:内容块组根标签名 @isHover<Boolean>:是否使用鼠标悬停触发事件[默认false] */ UI.OptionCard=function(args){ /* 变量定义,变量初始化 */ var THIS=this; //初始化选项卡对象 var root=$(args.root); //初始化菜单数组 var menus=root.find(">"+(args.menuTag||"MENU"||"*")+">*"); //初始化内容块数组 var cards=root.find(">"+(args.cardTag||"UL"||"*")+">*"); //是否使用鼠标悬停触发事件开关 var isHover=args.isHover||false; /* 成员函数 */ //寻找选项卡对应的菜单 //@card<Element|Number>:内容块对象或在内容块数组中的索引 this.getMenu=function(card){ if(!isNaN(card)){ return menus[card]; } if(card.menu){ return card.menu; } var index=-1; for(var i=0;i<cards.length;i++){ if(cards[i]==card){ index=i; break; } } return menus[index]; }; //寻找菜单对应的选项卡 //@menu<Element|Number>:菜单对象或在菜单数组中的索引 this.getCard=function(menu){ if(!isNaN(menu)){ return cards[menu]; } if(menu.card){ return menu.card; } var index=-1; for(var i=0;i<menus.length;i++){ if(menus[i]==menu){ index=i; break; } } return cards[index]; }; // //@menu<Element|Number>:菜单对象或在菜单数组中的索引 this.openCard=function(menu){ cards.hide(); menus.removeAttr("class"); if(!isNaN(menu)){ //menu=this.menus[menu]; $(menus[menu]).addClass("active"); $(cards[menu]).show(); } else{ $(menu).addClass("active"); $(this.getCard(menu)).show(); } }; /* 事件接口函数 */ //打开一个选项卡 var onMenu=function(e){ e=e||window.event; //var OptionCard=this.OptionCard; THIS.openCard(this); //alert(this.nodeName+":"+this.style.styleFloat);////////////////// }; /* 类对象初始化/构造 */ for(var i=0,l=menus.length;i<l;i++){ menus[i].card=cards[i]; cards[i].menu=menus[i]; menus[i].style.display="block"; menus[i].style.cssFloat="left"; menus[i].style.styleFloat="left"; //alert(this.menus[i].style.styleFloat); cards[i].style.display=i?"none":"block"; if(isHover){ menus[i].onmouseover=onMenu; } else{ menus[i].onclick=onMenu; } } };String|jQObject>:根节点<"#id"|jQuery对象> @columnTag<String>:列标签名<"DIV"> @moduleTag<String>:模块标签名<"DL"> @handleTag<String>:拖动作用条标签名<"DT"> */ UI.ModulesDrag=function(args){ /* 变量定义,变量初始化 */ // //document[args.root.split("#").join("")]=this; var THIS=this; //当前操作模块 this.module=null; //当前操作模块的临时副本 this.temp=document.createElement(args.moduleTag||$(args.root).find(">*>*")[0].tagName||"DL"); //所有列元素 this.columns=$(args.root).find(">"+(args.columnTag||"*")); //所有模块元素 this.modules=this.columns.find(">"+(args.moduleTag||"*")); //所有模块元素的句柄(拖动热区) this.handles=this.modules.find(">"+(args.handleTag||"DT")); /* 成员函数 */ //直接取得元素在文档中的绝对坐标 this.getAbsPos=function(obj){ var opos=obj.style.position; obj.style.position="absolute"; var ofloat=obj.style.styleFloat; obj.style.styleFloat="none"; var pos= obj.style.position=opos; obj.style.styleFloat=ofloat; return pos; }; //取得元素相对于父级元素的相对坐标 this.getRelPos=function(obj){ if(obj==document.body.parentNode){return} }; //根据相对坐标逐级计算出元素的绝对坐标 this.getAbsPosByRelPos=function(obj){ var pos={top:0,right:0,bottom:0,left:0}; for(var elem=obj;elem!=document.body;elem=elem.parentNode){ if(this.getRelPos(elem).top>0)pos.top+=this.getRelPos(elem).top; if(this.getRelPos(elem).left>0)pos.left+=this.getRelPos(elem).left; } pos.right=pos.left+obj.offsetWidth; pos.bottom=pos.top+obj.offsetHeight; return pos; }; /* 事件接口函数 */ //当开始拖动某一元素执行 this.startDrag=function(e){ /* 问题: 在绑定事件的函数中使用this指针,指向了触发事件的对象 解决: 在绑定事件的对象上增加一个属性来指向类对象原来的this指针 */ e=e||window.event; //var elem=e.target||e.srcElement; THIS.module=this.dragParent; document.ModulesDrag=THIS; document.onmousemove=THIS.onDrag; document.onmouseup=THIS.stopDrag; //$(document).mousemove(ModulesDrag.onDrag); //$(document).mouseup(ModulesDrag.stopDrag); document.onselectstart=function(){ document.selection.empty(); } //alert(this.onmousedown); THIS.module.parentNode.appendChild(THIS.temp); THIS.temp.innerHTML=THIS.module.innerHTML; THIS.temp.style.width=THIS.module.offsetWidth+"px"; THIS.temp.style.position="absolute"; THIS.temp.style.zIndex=Common.getNextHighestDepth(); THIS.temp.style.top=THIS.getAbsPos(THIS.module).top+"px"; THIS.temp.style.left=THIS.getAbsPos(THIS.module).left+"px"; THIS.temp.style.opacity="0.75"; THIS.temp.style.filter="alpha(opacity=75)"; THIS.temp.subLeft=THIS.getAbsPos(THIS.module).left-(e.clientX+document.body.parentNode.scrollLeft);//储存当前 坐标差值参数 THIS.temp.subTop=THIS.getAbsPos(THIS.module).top-(e.clientY+document.body.parentNode.scrollTop);//储存当前坐 标差值参数 THIS.module.style.visibility="hidden"; }; this.onDrag=function(e){ e=e||window.event; //alert(ModulesDrag.module.id); if(THIS.module==null){ return; } var _xmouse=e.clientX+document.body.parentNode.scrollLeft; var _ymouse=e.clientY+document.body.parentNode.scrollTop; THIS.temp.style.left=(THIS.temp.subLeft+e.clientX+document.body.parentNode.scrollLeft)+"px"; THIS.temp.style.top=(THIS.temp.subTop+e.clientY+document.body.parentNode.scrollTop)+"px"; for(var i=0;i<THIS.columns.length;i++){ if(THIS.columns[i].nodeType==1){ var cPos=THIS.getAbsPosByRelPos(THIS.columns[i]);//得到第i列的绝对位置对象 if(_xmouse>=cPos.left&&_xmouse<=cPos.right){//若鼠标坐标在列内 var columnModules=THIS.columns[i].childNodes; THIS.columns[i].appendChild(THIS.module); THIS.temp.style.width=THIS.module.offsetWidth+"px"; if(columnModules.length){ for(var j=0;j<columnModules.length;j++){ if(columnModules[j].nodeType==1){ if(columnModules[j]!=THIS.module){ var mPos=THIS.getAbsPosByRelPos(columnModules[j]); if(_ymouse>=mPos.top&&_ymouse<= (mPos.top+mPos.bottom)/2){ columnModules[j].parentNode.insertBefore (THIS.module,columnModules[j]); } else if(_ymouse>= (mPos.top+mPos.bottom)/2&&_ymouse<=mPos.bottom){ if(columnModules[j+1]&&columnModules [j+1].nodeType==1){ columnModules [j].parentNode.insertBefore(THIS.module,columnModules[j+1]); } } //if(_ymouse>=mPos.top&&_ymouse<=mPos.bottom) {columnModules[j].parentNode.insertBefore(ModulesDrag.module,columnModules[j]); break; } else continue; } } } break; } } } }; this.stopDrag=function(e){ e=e||window.event; if(THIS.module==null){ return; } THIS.module.style.visibility="visible"; THIS.temp.style.opacity="1"; THIS.temp.style.filter="alpha(opacity=100)"; THIS.temp.innerHTML=""; THIS.module=null; document.onmousemove=null; document.onmouseup=null; document.onselectstart=null; document.ModulesDrag=null; }; document.onselectstart=function(){ document.selection.empty(); }; for(var i=0;i<this.handles.length;i++){ this.handles[i].onmousedown=this.startDrag; this.handles[i].dragParent=this.handles[i].parentNode; this.handles[i].style.cursor="move"; } }; </script> </head> <body> <div > <div > <dl > <dt>用户帐号</dt> <dd> <menu> <li>登陆</li> <li>注册</li> </menu> <ul> <li> <p><label>用户名</label><input type="text" /></p> <p><label>密 码</label><input type="password" /></p> <p>提示信息</p> <p><input type="button" value="登陆" /></p> </li> <li> <p><label>用户名</label><input type="text" /></p> <p><label>密 码</label><input type="password" /></p> </li> </ul> </dd> </dl> </div> <!--头部,标题部分--> <div > <img alt="lvdaonet" src="userfile/default/default.jpg" /> <div > <button>绿岛门户</button> <button>登陆</button> <button>注册</button> <!-- </div> <div > <h1>空间标题</h1> <p>空间详细描述 - 用户xx的个性空间</p> </div> </div> <!--导航部分--> <div > <menu> <li><a href="#" >首页</a></li> <li><a href="#">档案</a></li> <li><a href="#">日志</a></li> <li><a href="#">相册</a></li> <li><a href="#">好友</a></li> <li><a href="#">消息</a></li> <li><a href="#">资源</a></li> </menu> </div> <textarea ></textarea> <!--主体部分--> <div ><!--class选择列显示模式--> <!--列1[,列2[,列3]]div >dl > <dt>模块标题名</dt> <dl>加载中....</dl> </dl> </div> --> <div > <dl > <dt>好友</dt> <dd> <ul> <li><a href="friend.htm">[群组]</a> <a href="blog.htm" target="_blank">绿岛网 络</a></li> <li><a href="friend.htm">[群组]</a> <a href="blog.htm" target="_blank">SCDA</a></li> <li><a href="friend.htm">[群组]</a> <a href="blog.htm" target="_blank">色友 </a></li> <li><a href="friend.htm">[好友]</a> <a href="blog.htm" target="_blank">123 </a></li> <li><a href="friend.htm">[好友]</a> <a href="blog.htm" target="_blank">weiloon</a></li> <li><a href="friend.htm">[好友]</a> <a href="blog.htm" target="_blank">踏云逐 风</a></li> <li><a href="friend.htm">[好友]</a> <a href="blog.htm" target="_blank">小叶桉 树</a></li> <li><a href="friend.htm">[好友]</a> <a href="blog.htm" target="_blank">流水落 花</a></li> </ul> </dd> </dl> </div> <div > <dl > <dt><span ></span><span ></span><a href="http://lvdaonet/weiloon/user/">个人信息</a></dt> <dd>加载中...</dd> </dl> </div> <div > <dl > <dt><a href="http://lvdaonet/weiloon/blog/">日志</a></dt> <dd> <p><a href="blog.htm">生活</a> <a href="blog.htm">技术</a> <a href="blog.htm">畅游 </a> <a href="blog.htm">言论</a></p> <ul > <li > <div >2006-8-2</div> <div ><a href="blogshow.htm">灵魂救赎</a></div> <div >灵魂救赎</div> <div >标签:<a href="blog.htm">生活</a></div> <div ><a href="home.htm" target="_blank">Lan天才</a>a href=";">Comments (0)</a> | <a href="#">Top^</a></div> <div >正在加载最新评论...</div> </li> <li > <div >2006-8-2</div> <div ><a href="blogshow.htm">从此黯淡</a></div> <div >从此黯淡</div> <div >标签:<a href="blog.htm">生活</a></div> <div >xxx/div> <div >正在加载最新评论...</div> </li> <li > <div >2006-8-2</div> <div ><a href="blogshow.htm">无聊的旅途</a></div> <div >无聊的旅途</div> <div >标签:<a href="blog.htm">生活</a></div> <div >xxx/div> <div >正在加载最新评论...</div> </li> <li > <div >2006-8-2</div> <div ><a href="blogshow.htm">灵魂救赎</a></div> <div >灵魂救赎</div> <div >标签:<a href="blog.htm">生活</a></div> <div >xxx</div> <div >正在加载最新评论...</div> </li> <li > <div >2006-8-2</div> <div ><a href="blogshow.htm">灵魂救赎</a></div> <div >灵魂救赎</div> <div >标签:<a href="blog.htm">生活</a></div> <div >Lan天才/div> <div >正在加载最新评论...</div> </li> </ul> </dd> </dl> </div> </div> <div >底部</div> </div> </body> </html>
 提示:您可以先修改部分代码再运行
 
  以前一直做的项目都不大,最多就十几个二十几个页面的,前端程序用的都不多,总的加起来就没几个js文件,有些表单验证的基本都写页面里面了,所以没有涉及到前端程序的架构问题。但随着Ajax思想的广泛使用,使得用户的浏览器能看到不仅是网页和链接,将会越来越多的是浏览器应用程序,或者说是网站和浏览器应用程序的综合体(我是这么理解的,希望有人能给出更好的定义)。同时随着用户需求的增长工程项目规模的不断扩大,开发者们思考的东西也必须越来越多,前端程序的合理组织架构也就越来越重要了。

  先从Javascript里的类写法开始说起。就我本人了解,js的类可以有以下两种写法:

[写法一]直接定义object类型变量

var oClass={
    oVar1:value1,
    oVar2:value2,
    oFun1:function(arguments){
        alert(arguments);
    }
    //...
};

[写法二]定义函数
因为Javascript里函数也是一种数据类型,故可以这样写

var oClass=function(args){
    var oVar1=value1;//私有变量
    this.oVar2=value2;//公有变量
    var oFun1=function(){
        //...
    };
    this.oFun2=function(){
        //...
    };
    function oFun3(){
        //...
    }
    //...
};

(或者说这样,也可以说是写法三)

function oClass(args){
    //内容同写法二
}

  可以简单的分析出这样的结论,通过方法一(即创建Object对象)得到的是一个已经储存在内存中的对象,不能通过这个对象再新建一个同样类型的对象,也可以称为静态的,而通过方法二(即函数定义)的是可以通过new来新建这个类型的对象的。在具体使用的时候就根据这个区别来定义不同的类和对象,作为不同的用途。

  我的想法是这样的,通过方法一建立静态类来组织包,而通过方法二在包内定义类。这样参照了java包的思想,组织起一棵树,结构清晰,方便开发人员调用。例如:

//namespace.js文件[必须导入]

var lvdao={//根节点,命名空间(包)

    Common:{}//常用方法变量包

    ,UI:{}//用户接口控件包

    //,...

}



// UI/OptionCard.js文件

/*
    Class:        选项卡类
    Date-Start:    2007-4-16
    Date-Last:    2007-4-20
    
    @root<String|jQObject>:根节点<"#id"|jQuery对象>
    @menuTag<String>:菜单组根标签名
    @cardTag<String>:内容块组根标签名
    @isHover<Boolean>:是否使用鼠标悬停触发事件[默认false]
*/
lvdao.UI.OptionCard=function(args){

    /*
        变量定义,变量初始化
     */
    
    var THIS=this;
    
    //初始化选项卡对象
    var root=$(args.root);
    
    //初始化菜单数组
    var menus=root.find(">"+(args.menuTag||"MENU"||"*")+">*");
    
    //初始化内容块数组
    var cards=root.find(">"+(args.cardTag||"UL"||"*")+">*");
    
    //是否使用鼠标悬停触发事件开关
    var isHover=args.isHover||false;
    
    
    
    /*
        成员函数
     */
    
    //寻找选项卡对应的菜单
    //@card<Element|Number>:内容块对象或在内容块数组中的索引
    this.getMenu=function(card){
        if(!isNaN(card)){
            return menus[card];
        }
        if(card.menu){
            return card.menu;
        }
        var index=-1;
        for(var i=0;i<cards.length;i++){
            if(cards[i]==card){
                index=i;
                break;
            }
        }
        return menus[index];
    };
    
    //寻找菜单对应的选项卡
    //@menu<Element|Number>:菜单对象或在菜单数组中的索引
    this.getCard=function(menu){
        if(!isNaN(menu)){
            return cards[menu];
        }
        if(menu.card){
            return menu.card;
        }
        var index=-1;
        for(var i=0;i<menus.length;i++){
            if(menus[i]==menu){
                index=i;
                break;
            }
        }
        return cards[index];
    };
    
    //打开选项卡
    //@menu<Element|Number>:菜单对象或在菜单数组中的索引
    this.openCard=function(menu){
        cards.hide();
        menus.removeAttr("class");
        if(!isNaN(menu)){
            //menu=this.menus[menu];
            $(menus[menu]).addClass("active");
            $(cards[menu]).show();
        }
        else{
            $(menu).addClass("active");
            $(this.getCard(menu)).show();
        }
    };
    
    
    
    /*
        事件接口函数
     */
    
    //打开一个选项卡
    var onMenu=function(e){
        e=e||window.event;
        THIS.openCard(this);
    };
    
    
    
    /*
        类对象初始化/构造
     */
    
    
    
    for(var i=0,l=menus.length;i<l;i++){
        menus[i].card=cards[i];
        cards[i].menu=menus[i];
        
        menus[i].style.display="block";
        menus[i].style.cssFloat="left";
        menus[i].style.styleFloat="left";
        //alert(this.menus[i].style.styleFloat);
        cards[i].style.display=i?"none":"block";
        
        if(isHover){
            menus[i].onmouseover=onMenu;
        }
        else{
            menus[i].onclick=onMenu;
        }
    }
    
};






/*
    Class:        模块拖动类
    Date-Start:    2007-4-2
    Date-Last:    2007-4-16
    
    @root<String|jQObject>:根节点<"#id"|jQuery对象>
    @columnTag<String>:列标签名<"DIV">
    @moduleTag<String>:模块标签名<"DL">
    @handleTag<String>:拖动作用条标签名<"DT">
*/    
lvdao.UI.ModulesDrag=function(args){

    /*
        变量定义,变量初始化
     */
    
    //
    //document[args.root.split("#").join("")]=this;
    var THIS=this;
    
    //当前操作模块
    this.module=null;
    
    //当前操作模块的临时副本
    this.temp=document.createElement(args.moduleTag||$(args.root).find(">*>*")[0].tagName||"DL");
    
    //所有列元素
    this.columns=$(args.root).find(">"+(args.columnTag||"*"));
    
    //所有模块元素
    this.modules=this.columns.find(">"+(args.moduleTag||"*"));
    
    //所有模块元素的句柄(拖动热区)
    this.handles=this.modules.find(">"+(args.handleTag||"DT"));
    
    
    
    /*
        成员函数
     */
    
    //直接取得元素在文档中的绝对坐标
    this.getAbsPos=function(obj){
        var opos=obj.style.position;
        obj.style.position="absolute";
        var ofloat=obj.style.styleFloat;
        obj.style.styleFloat="none";
        var pos=

{top:obj.offsetTop,right:obj.offsetLeft+obj.offsetWidth,bottom:obj.offsetTop+obj.offsetHeight,left:obj.offsetLeft};
        obj.style.position=opos;
        obj.style.styleFloat=ofloat;
        return pos;
    };
    
    //取得元素相对于父级元素的相对坐标
    this.getRelPos=function(obj){
        if(obj==document.body.parentNode){return}
        return
    };
    
    //根据相对坐标逐级计算出元素的绝对坐标
    this.getAbsPosByRelPos=function(obj){
        var pos={top:0,right:0,bottom:0,left:0};
        for(var elem=obj;elem!=document.body;elem=elem.parentNode){
            if(this.getRelPos(elem).top>0)pos.top+=this.getRelPos(elem).top;
            if(this.getRelPos(elem).left>0)pos.left+=this.getRelPos(elem).left;
        }
        pos.right=pos.left+obj.offsetWidth;
        pos.bottom=pos.top+obj.offsetHeight;
        return pos;
    };
    
    
    
    /*
        事件接口函数
     */
    
    //当开始拖动某一元素执行
    this.startDrag=function(e){
        /*
            问题: 在绑定事件的函数中使用this指针,指向了触发事件的对象
            解决: 在绑定事件的对象上增加一个属性来指向类对象原来的this指针
        */
        e=e||window.event;
        //var elem=e.target||e.srcElement;
        
        THIS.module=this.dragParent;
        
        document.ModulesDrag=THIS;
        document.onmousemove=THIS.onDrag;
        document.onmouseup=THIS.stopDrag;
        
        document.onselectstart=function(){
            document.selection.empty();
        }
        THIS.module.parentNode.appendChild(THIS.temp);
        
        THIS.temp.innerHTML=THIS.module.innerHTML;
        
        THIS.temp.style.width=THIS.module.offsetWidth+"px";
        THIS.temp.style.position="absolute";
        THIS.temp.style.zIndex=Common.getNextHighestDepth();
        THIS.temp.style.top=THIS.getAbsPos(THIS.module).top+"px";
        THIS.temp.style.left=THIS.getAbsPos(THIS.module).left+"px";
        
        THIS.temp.style.opacity="0.75";
        THIS.temp.style.filter="alpha(opacity=75)";
        
        THIS.temp.subLeft=THIS.getAbsPos(THIS.module).left-(e.clientX+document.body.parentNode.scrollLeft);//储存当前

坐标差值参数
        THIS.temp.subTop=THIS.getAbsPos(THIS.module).top-(e.clientY+document.body.parentNode.scrollTop);//储存当前坐

标差值参数
        
        THIS.module.style.visibility="hidden";
        
    };
    
    this.onDrag=function(e){
        e=e||window.event;
        if(THIS.module==null){
            return;
        }
        
        var _xmouse=e.clientX+document.body.parentNode.scrollLeft;
        var _ymouse=e.clientY+document.body.parentNode.scrollTop;
        THIS.temp.style.left=(THIS.temp.subLeft+e.clientX+document.body.parentNode.scrollLeft)+"px";
        THIS.temp.style.top=(THIS.temp.subTop+e.clientY+document.body.parentNode.scrollTop)+"px";
        
        for(var i=0;i<THIS.columns.length;i++){
            if(THIS.columns[i].nodeType==1){
                var cPos=THIS.getAbsPosByRelPos(THIS.columns[i]);//得到第i列的绝对位置对象
                if(_xmouse>=cPos.left&&_xmouse<=cPos.right){//若鼠标坐标在列内
                    var columnModules=THIS.columns[i].childNodes;
                    THIS.columns[i].appendChild(THIS.module);
                    THIS.temp.style.width=THIS.module.offsetWidth+"px";
                    if(columnModules.length){
                        for(var j=0;j<columnModules.length;j++){
                            if(columnModules[j].nodeType==1){
                                if(columnModules[j]!=THIS.module){
                                    var mPos=THIS.getAbsPosByRelPos(columnModules[j]);
                                    if(_ymouse>=mPos.top&&_ymouse<=

(mPos.top+mPos.bottom)/2){
                                        columnModules[j].parentNode.insertBefore

(THIS.module,columnModules[j]);
                                    }
                                    else if(_ymouse>=

(mPos.top+mPos.bottom)/2&&_ymouse<=mPos.bottom){
                                        if(columnModules[j+1]&&columnModules

[j+1].nodeType==1){
                                            columnModules

[j].parentNode.insertBefore(THIS.module,columnModules[j+1]);
                                        }
                                    }
                                    //if(_ymouse>=mPos.top&&_ymouse<=mPos.bottom)

{columnModules[j].parentNode.insertBefore(ModulesDrag.module,columnModules[j]);
                                    break;
                                }
                                else continue;
                            }
                        }
                    }
                    break;
                }
            }
        }
    };
    
    this.stopDrag=function(e){
        e=e||window.event;
        
        if(THIS.module==null){
            return;
        }
        
        THIS.module.style.visibility="visible";
        
        THIS.temp.style.opacity="1";
        THIS.temp.style.filter="alpha(opacity=100)";
        THIS.temp.innerHTML="";
        
        THIS.module=null;
        document.onmousemove=null;
        document.onmouseup=null;
        document.onselectstart=null;
        document.ModulesDrag=null;
    };
    
    
    
    document.onselectstart=function(){
        document.selection.empty();
    };
    
    
    
    for(var i=0;i<this.handles.length;i++){
        this.handles[i].onmousedown=this.startDrag;
        this.handles[i].dragParent=this.handles[i].parentNode;
        this.handles[i].style.cursor="move";
    }

};

以此类推,根据不同的用途定义包,再细化到类,就可以根据工程需求组建一个方便灵活的类库,尤其是常用工具和UI控件等,可以在多个项目之间灵活移植。文件夹结构如下:

behavior/                     前端程序文件夹
(behavior/jquery.js              jquery基础操作类库)
behavior/namespace.js              命名空间(必须)
behavior/Common/              常用包
behavior/Common/...js              常用包中的类
behavior/UI/                     UI包
behavior/UI/OptionCard.js       包的选项卡类
behavior/UI/ModulesDrag.js       模块拖动类

使用的时候首先导入命名空间文件,其他类就按需要导入,要注意的是按代码执行的先后顺序导入,然后在html文档加载完毕后执行类的实例化即可使用。例:

$(function(){//jQuery中onload的写法
    var modulesDrag=new UI.ModulesDrag({root:"#main",handleTag:"DT"});//新建模块拖动对象
    var userLogin=new UI.OptionCard({root:$("#winLogin>dd"),isHover:true});//新建选项卡对象
});

  但是,这样的写法受到很大的限制,我在开发时遇到几个问题,正好也向各位请教。
       1. 类定义的代码必须有一定的顺序,变量定义-函数定义-事件接口定义-构造初始化,由于类本身是一个函数,函数内部的代码
执行顺序,错误的顺序会使代码找不到还没有定义的变量或函数,包括将要挂载在事件上的函数入口;
       2. 要挂载在事件上的函数入口在挂载以后里面的this不再指向类对象,而指向了事件相关的对象,造成了一点小麻烦,可以通过在
量定义阶段定义一个指向类对象this的变量,在事件函数中调用可以解决(还没有更好的解决方案);
  评论这张
 
阅读(198)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018