zoukankan      html  css  js  c++  java
  • 下拉框插件开发 (二)

    今天有事出去了一趟,晚上加了下夜班,终于将它完成了,后续有bug,欢迎探讨。

    附上:github地址  https://github.com/mapletao/downdrop

    1,需求更新,完成自己想到的

    对js里面的需求及每个方法要做的内容简述的描述了下并将其实现。

     

    2.js编写

      1.立即执行函数,构造一个Downdrop函数,并注册该函数,同时进行安全处理,前面的;是为了执行出错的问题

    ;(function(){
        var Downdrop=function(opt){
            if(!(this instanceof Downdrop)){
                return new Downdrop(opt);    
            }
            this.init(opt);
        };
        window.Downdrop=Downdrop;
    })();

      2.初始化函数

        初始化函数主要是做5件事

      1:扩展默认配置  setOpt

      2: 处理默认配置  dealOpt 

      3: 插入下拉框组件 setHtml 

      4: 设置事件 setFun

      5: 解除配置信息 removeOpt 

     3:扩展默认配置

      对参数进行处理,并扩展,设置默认参数

      

    setOpt:function(opt){
                this.ulTemp=['<div class="downdrop">',
                                                '<div class="downdrop-header">请选择</div>',
                                                '<i class="angle"></i>',
                                                '<ul class="downdrop-con">',
                                                '</ul>',
                                            '</div>'].join('');
                this.setting = {
                    liTemp:'<li data-val="{{val}}">{{text}}</li>',
                    text:true,
                    isHide:true,
                };
                mapletao.extend(this.setting,opt);
            },

    4:处理默认配置

      处理列表项点击时该执行的事件,并将其保存在数组中,减少后面点击时的多重判断

      

    dealOpt:function(){
                var self=this;
                self.dealLiFns=[];
                if(self.setting.text){
                    self.dealLiFns.push(function(self){
                        self.headerDom.innerHTML = this.innerHTML;
                        self.headerDom.setAttribute("data-val",this.getAttribute("data-val"));
                    });
                }
                if(self.setting.isHide){
                    self.dealLiFns.push(function(self){
                        self.conDom.style.display = "none";
                    });
                }
                if(self.setting.cb){
                    self.dealLiFns.push(cb);
                }
            },

    5:插入下拉框组件

      将下拉框html结构,并处理数据,并将数据插入到列表容器中,并保存将要用到的元素,后面就不需再去页面找了

      

    setHtml:function(){
                var self = this;
                self.setting.ele.innerHTML=self.ulTemp;
                self.setEle();
                self.setList(self.setting.data);
            },
            setList:function(data){
                var self=this;
                self.lis='';
                data.forEach(function(obj){
                    self.lis += self.formateString(self.setting.liTemp,obj);
                });
                self.conDom.innerHTML = self.lis;
                this.headerDom.innerHTML = "请选择";
            },
            formateString:function(str,data){
                return str.replace(/{{(w+)}}/g,function(match,key){
                    return typeof data[key] === undefined? '' : data[key];
                });
            },
            setEle:function(){
                var ele=this.setting.ele;
                this.headerDom=ele.getElementsByClassName("downdrop-header")[0];
                this.conDoms=document.getElementsByClassName("downdrop-con");
                this.conDom=ele.getElementsByClassName("downdrop-con")[0];
            },

    6:事件设置

      主要对4个元素进行设置

      1:ele 下拉框插件容器 setEleClick 阻止冒泡,下拉框元素里面发生的事件不被外界获取,外界操作不影响里面的操作。

      2:下拉框头部 setHeaderClick   头部点击让列表显示,并将其它的隐藏

      3: 下拉列表容器 setConClick 代理模式,对下拉列表容器绑定点击事件,当列表项内容重新加载时正常使用,捕获li点击事件并处理

      4: document setDocClick 当点击其它地方时让所有下拉框列表内容的隐藏

    setFun:function(){
                this.setEleClick();
                this.setHeaderClick();
                this.setConClick();
                this.setDocClick();
            },
            setEleClick:function(){
                var self=this;
                eventUtil.bindEvent(this.setting.ele,"click",self.setDomBubble);
            },
            setDomBubble:function(e){
                eventUtil.stopPropagation(e);
            },
            setHeaderClick:function(){
                var self=this;
                self.dealHeaderFn=self.bindFn(self.dealHeaderFn,self);
                eventUtil.bindEvent(this.headerDom,"click",self.dealHeaderFn);
            },
            dealHeaderFn:function(e,self){
                self.hideDom(e,self);
                self.conDom.style.display = "block";
            },
            setConClick:function(){
                var self=this;
                self.dealLiFn=self.bindFn(self.dealLiFn,self);
                eventUtil.bindEvent(this.conDom,"click",self.dealLiFn);
            },
            dealLiFn:function(e,self){
                e = eventUtil.getEvent(e);
                var target = eventUtil.getEventSrc(e);
                if(target.tagName.toLowerCase() === "li"){
                    self.dealLiFns.forEach(function(obj){
                        obj.call(target,self);
                    });
                    target=null;
                }
            },
            bindFn:function(fn,args){
                return function(e){
                    fn.call(this,e,args);
                };
            },
            hideDom:function(e,self){
                for(var i=0;i<self.conDoms.length;i++){
                    self.conDoms[i].style.display = "none";
                }
            },
            setDocClick:function(){
                var self = this;
                Downdrop.prototype.hideDom=self.bindFn(self.hideDom,self);
                eventUtil.bindEvent(document,"click",self.hideDom);
            },

    7:解除配置信息 

      删除一些以后不会用到的属性

    removeOpt:function(){
                delete this.setting;
                delete this.lis;
                delete this.ulTemp;
            }

    8:测试

      单元测试,改变参数,看看执行结果

      

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <title>下拉框</title>
        <link rel="stylesheet" type="text/css" href="css/reset.css" />
        <link rel="stylesheet" type="text/css" href="css/downdrop.css" />
    </head>
    <body>
        <p>默认</p>
        <div style="200px;margin-left: 20px;margin-top:10px;" id="J_test1">
        </div>
        <p>不赋值</p>
        <div style="200px;margin-left: 20px;margin-top:10px;" id="J_test2">
        </div>
        <p>不隐藏</p>
        <div style="200px;margin-left: 20px;margin-top:10px;" id="J_test3">
        </div>
        <p>不赋值,不隐藏</p>
        <div style="200px;margin-left: 20px;margin-top:10px;" id="J_test4">
        </div>
        <script src="js/common.js"></script>
        <script src="js/downdrop.js"></script>
        
        <script type="text/javascript">
            var data=[{
                "val":1,
                "text":"语文"
            },{
                "val":2,
                "text":"数学"
            },{
                "val":3,
                "text":"英语"
            },{
                "val":4,
                "text":"历史"
            },{
                "val":5,
                "text":"化学"
            },{
                "val":6,
                "text":"生物"
            },{
                "val":7,
                "text":"物理"
            }];
            var test1={
                ele:document.getElementById("J_test1"),
                data:data
            };
            var obj=new Downdrop(test1);
            var test2={
                ele:document.getElementById("J_test2"),
                data:data,
                text:false
            }
            var obj2=Downdrop(test2);
            var test3={
                ele:document.getElementById("J_test3"),
                data:data,
                isHide:false
            }
            var obj3=new Downdrop(test3);
            var test4={
                ele:document.getElementById("J_test4"),
                data:data,
                isHide:false,
                text:false
            };
            var obj4=new Downdrop(test4);
        </script>
    </body>
    </html>

    9:测试结果

    完成!

    10:结语:

    首先说说在这个组件开发中遇到的坑,参数传递,事件绑定中,作用域指向会偏离,指向当前点击的事件源,可能不是你自己想要的,这里用了下参与者模式,将我需要的用参数的形式传递,还用到了call,将this指向改成我想要的。还有对事件的封装,增强了自己的代码逻辑能力。有不足的地方,还请多多见谅。后面也会不时的进行bug处理,以及优化及扩张。

  • 相关阅读:
    C# 1.0 到 C# 3.0 委托创建过程的发展
    C#禁用窗体最大化按钮
    TeamViewer 通过Internet进行远程访问和远程支持
    c# 匿名方法
    BeginInvoke会重新开一个线程
    c# 线程调用带参数的函数
    c# msdn 委托
    判断某张表是否存在在数据库中(access 2003 与sql server 2008)
    新浪微博自动发送微博 功能已实现(net)
    validateRequest="false" 在asp.net 4.0中失效的解决办法
  • 原文地址:https://www.cnblogs.com/mapletao/p/6127863.html
Copyright © 2011-2022 走看看