zoukankan      html  css  js  c++  java
  • 标签交互与创建jquery组件

    通过原生html+css就可以写出基本的组件,比如select,很简单就可以写一个符合标准的组件

            <select name="name" class="form-control">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
            </select>

    我做了很长时间java程序猿,配合jsp中的jstl,很简单的创建原生的html,再加上原生的事件,一个页面直接手工

    但如果抛开后端生成html的能力,由js生成html,情况产生了微妙的变化

            <select id="name" class="form-control">
            </select>
            <script type="text/javascript">
                var data=[{
                    text:1,
                    value:1
                },{
                    text:2,
                    value:2
                },{
                    text:3,
                    value:3
                },{
                    text:4,
                    value:4
                }];
                for(var i=0;i<data.length;i++){
                    $("#name").append(" <option value='"+data[i].value+"'>"+data[i].text+"</option>")
                }
            </script>

    js只赋予html交互的能力,并没有对html进行增强,他对html标签的增强仅限于此,出于复用的方式,我们需要对js组件化(如果设计到select,table,html这些标签,我更愿意叫脚本化标签)

    出于复用的目的,写一个简单的jquery插件

            <select id="name" class="form-control">
            </select>
            <script type="text/javascript">
                
            $("#name").combobox({
                data:data
            })
            
        //丢到    <script src="">中
        (function($){
            function creatr(jq,data){
                for(var i=0;i<data.length;i++){
                   jq.append(" <option value='"+data[i].value+"'>"+data[i].text+"</option>")
                }
            }
            //只处理单个jq,多个jq需要包裹一层jq.each
            $.fn.combobox=function(options){
                creatr(options.data)
            }
        })($)
            
            </script>

    这样用起来就简单多了,他现在还很脆弱,任何一个小需求都能整死他,至少他缺少事件的能力,从对象角度看标签完全具有属性,方法和事件,我们的小组件也缺乏这三样基本能力

    属性能力

    传递过去的参数及其展示的参数的保存位置,有很多地方可以去保存,最简单的就是直接赋值给组件,没有被复用的属性将会极大的消耗性能,至少目前都会选择使用数据存储的方式对组件的属性进行保存,而非直接赋值(对属性的处理,算是js比较特殊的地方),jquery的数据存储方式也是比较流行的方式(这有两种实现,这些实现也都是为了解决组件属性存放问题的解决方案)

            //这是一种最为粗暴的方式,原因参考数据存储
            $.fn.combobox=function(options){
                this.options=options;
            }
            
            //jquery的解决方案,需要的时候    $(this).data("options")
            $.fn.combobox=function(options){
                $(this).data("options",options);
            }

    方法能力

    必须至于原形之中,用于方法的共享,如果使用原形,就得注意内部使用new创建,$().combobox()后,可以直接使用方法

        (function($){
    
             function Combobox(options){
                 //除了简单必要的属性至于this中,大多数属性还丢到其相关标签的$().data中
                 this.options=options;
                 this.create(options.data)
             }
            
            Combobox.prototype.getValue=function(){
                    return     this.options;
            }
            
            Combobox.prototype.create(data){
                for(var i=0;i<data.length;i++){
                   jq.append(" <option value='"+data[i].value+"'>"+data[i].text+"</option>")
                }
            }
            $.fn.combobox=function(options){
                //流行的无new创建组件
                return new Combobox(options);
            }
              $.fn.combobox.Constructor = Combobox
            
        })($)

    当然也可以将方法直接负载构造方法上,而后提供一个统一的入口(一般就是构造方法),进行方法的调用,这种方式没有new,看似也没有原形,使用了js中一切都是对象,一切都可以赋值的特性,除了重写$.fn.combobox比较麻烦外(你会把method给干掉),完全无死角

        (function($){
            function create(jq,data){
                for(var i=0;i<data.length;i++){
                   jq.append(" <option value='"+data[i].value+"'>"+data[i].text+"</option>")
                }
            }
    
        
            $.fn.combobox=function(options){
                if(typeof options === "string"){
                    $(this).data("options",options);
                    return     create(this.options)
                }
                var method=$.fn.combobox.method[options]
                method||method()
            }
            
            $.fn.combobox.method={
                getOptions:function(jq){
                    return     $(this).data("options");
                }
            }
        })($)

    事件能力

    事件能力必须依赖于构建对象时的绑定,他是一个方法,只是绑到了原生方法中,会由系统调用,并传递参数,仅此而已(可以的话我想说,这就是实现了一个系统级的接口,你可以调用,但你无法保证参数的质量)

        (function($){
            function create(jq,data){
                for(var i=0;i<data.length;i++){
                   jq.append(" <option value='"+data[i].value+"'>"+data[i].text+"</option>")
                }
            }
            
            function bind(jq,options){
                if(options.onSelect){
                    options.onBeforeSelect(jq);
                    jq.on("select",options.onSelect);
                    options.onAfterSelect(jq);
                }
                
            }
        
            $.fn.combobox=function(options){
                if(typeof options === "string"){
                    $(this).data("options",options);
                         create(this.options)
                         bind(this,options)
                         return
                }
                var method=$.fn.combobox.method[options]
                method||method()
            }
            
            $.fn.combobox.method={
                getOptions:function(jq){
                    return     $(this).data("options");
                }
            }
        })($)

    好了,将它们实现,我们第一个jquery组件也就诞生了,回头在看一下实现,这个组件只是对select这个html标签,脚本化,我们可以使用js动态且方便的生成原生的html标签,优势在于原生,缺点在于没有增强,需要checkbox的需求就能搞死你(我一直认为checkbox+select完全无意义,浪费cpu),再来一个select+tree,估计得疯掉一票...这个时候就不得不对这个组件进行增强,比如这里,我们在其内部可能会使用div甚至ul进行实现,而非传统的select(这正好也解释了为什么是combobox而非select)

    使用增强的方式可以实现更多的酷炫功能,遗憾的是每个组件实现的思路完全不一致,这会限制组件的结构,这种结构也会反过来影响css,原生的标签很容易替换css,而增强过的标签很难更换一个皮肤,除非你很熟悉这种组件结构

    可以的话,我只想将标准的标签进行脚本化(放在html上纯原生,即只做标签的交互),以方便我应付不同的UI,否则,即使组件化的封装减化了功能实现,超蛋疼的皮肤修改也会让人菊紧一整天

  • 相关阅读:
    xshell不能输入中文,显示为??
    ansible-2.1.0.0_module
    ansible
    解决ssh连接问题2
    Java Socket网络编程Server端详解
    Java Socket网络编程Client端详解
    Spring4.* 中整合 Hibernate
    自定义规则,对List<Map<String,Object>> List<Object>进行排序
    自定义注解和注解的相关使用
    枚举类型的相关解析
  • 原文地址:https://www.cnblogs.com/liuCy/p/4621544.html
Copyright © 2011-2022 走看看