zoukankan      html  css  js  c++  java
  • 第四十四课:jQuery UI和jQuery easy UI

    jQuery UI是jQuery官方提供的功能效果和UI样式。作为官方出的东西,它一直没有被人们看重,一是它没有datagrid,tree等UI库必备的东西,二是它修改太过频繁,体积庞大。其实它所有以ui开头的插件都来自开源社区,为了统一它们的接口,jQuery花了很长的时间。在jQuery1.9中,它共有autocomplete,dialog,menu,tabs,slider,tooltip等十个UI。

    jQuery UI的开发模式跟jQuery插件化操作规范是一样的,第一次传参为对象,就进入配置模式,第二传参为方法名,就调用其方法,举个例子:

    初始化时,传一个对象:$(".selector").accordion({ heightStyle:"fill", {active :2 }});

    调用方法时,传一个方法名:$(".selector").accordion("option", "active");  //option为方法名,active是option方法的传参

    jQuery UI中的各个控件有不同的方法和属性,但由于都是同一个基类,因此有如下相同的操作:

    让控件不可用有两种方式:第一种,使用配置模式$(".selector").accordion("option", "disabled", true);

    第二种,直接传入disable方式 $(".selector").accordion("disable");

    让控件可用,也有两种方式:第一种,$(".selector").accordion("option", "disabled", false);第二种,$(".selector").accordion("enable");

    由于jQuery官方UI库不好用,于是人们开始设计自己的UI库。国外最顶尖的是jQuery tools,bootstrap等,国内的有easyUI,DWZ等。

    我们来说下,easyUI相比于jQuery UI的优势:智能加载和个性化制定

    大家都知道UI库通常很庞大,jQuery UI的插件少,但是你要使用它,需要加载很多东西,依赖关系也非常复杂。

    而easy UI有两种应用插件的方式,一种类似于EXT(这里不讲),一种类似于bootstrap。bootstrap的方式就是要求你按照文档的范本写HTML,里面有指定的类名,这些类名非常重要。easy UI只要求你引入核心库和parse.js文件,其中parse.js有一段代码在你domReady后,会扫描你的DOM树,把这些带有特定类名的元素全部找出来,并且根据这些类名来加载对应的UI插件的js文件,最后初始化它们,不像jQuery UI需要一次性加载很多东西。

    个性化制定。由于jQuery是集合操作,$(".selector")可能得到5个匹配的元素,而$(".selector").tabs(options)这样的操作,会对这5个元素应用相同的配置。但是,有时我们需要根据不同的元素进行不同的配置。easyUI就有这个东西,它会对元素的data-options的属性值弄成一个配置对象,同时还支持直接传入一个数组弄成一个配置对象,最后把这些配置对象都扩展到最终的配置对象中去,这样,如果元素想要不同的配置,可以在data-options中添加或者把配置值放在一个数组中传进去。比如:

    <div data-options="100px,height:100px" minDate="2015-1-11">ddd</div>

    $.parse.parseOptions(element , ["minDate", {isShowWeek:"boolean"}])

    针对每一个元素,它所得到的配置对象是:

    $.extend({}, defaults, $.parse.parseOptions(element , ["minDate", {isShowWeek:"boolean"}]) , options)

    其中options为统一配置项, $.parse.parseOptions(element , ["minDate", {isShowWeek:"boolean"}]) 为个性化配置项,defaults为默认配置项。

    接下来,我们来看下$.parse.parseOptions方法源码解析:

    $.parse.parseOptions = function(element, properties){

      var $ele = $(element), options={};

      var value = $.trim($ele.attr("data-options"));   //这里取到的值"100px,height:100px"

      if(value){

        var first = value.substr(0,1);

        var last = value.substr(value.length-1,1);

        if(first != "{"){

          value = "{" + value;      

        } 

        if(last != "}"){

          value = value + "}";     //value等于"{100px,height:100px}"

        }

        options = (new Function( "return " + value))();       //执行这个新建的方法,options = {100px,height:100px}

      }

      if(properties){   //如果传入了数组,这里是 ["minDate", {isShowWeek:"boolean"}]

        var opts = {};

        for(var i=0;i<properties.length;i++){

          var name = properties[i];

          if(typeof name == "string"){   //name = "minDate"

            opts[name] = $ele.attr(name);  //这里的opts={minDate:"2015-1-11"}

          }else{    //name = {isShowWeek:"boolean"}

            for(var key in name){

              var type = name[key];     //type = "boolean",key = isShowWeek

              if(type == "boolean"){

                opts[key] = $ele.attr(key) ? ($ele.attr(key) == "true") : undefined;  //如果元素上有isShowWeek的属性值,并且为true,那么opts = {minDate:"2015-1-11" , isShowWeek: true},这里的div元素上没有,所以opts = {minDate:"2015-1-11" , isShowWeek: undefined}

              }

            }

          }

        }

        $.extend(options, opts);   //   options =  {100px,height:100px,minDate:"2015-1-11" , isShowWeek: undefined}

      }

      return options;    

    }

    上面说的这两个特点,在jQuery1.3后也添加了。只是方法不一样,像jQuery1.43,它支持通过抽取元素上的data-*属性值来做配置对象。

    最后,我们来讲下操作UI实例的各种方式的比较:

    jQuery UI是直接传字符串的形式来调用UI实例的方法,比如前面讲的:$("div").dropdown({....}),实例化一个UI组件,如果想调用此组件的方法,那么,可以用$("div").dropdown(方法名, arg1,arg2....),其中的方法名就是传字符串的形式。

    jQuery tools是直接操作UI实例,比如:var tooltip = $("#input1").tooltip({api : true}); tooltip.show(),这里的tooltip就是UI实例。这显然比jQuery UI的方式好。

    我们来看下它的源码:

    $.fn.tooltip = function(options){

      var api = this.data("tooltip");

      if(api)  return api;   //如果元素已经实例化过了,那么就直接返回。这里返回的是一组元素的第一个UI实例

      options = $.extend(true, {} , defaults , options);

      this.each(function(){

        api = new Tooltip(this, options);   //给每个元素实例化一个UI对象Tooltip

        $(this).data("tooltip", api);

      });

      return options.api ? api : this;   //如果配置中的api属性为true,就返回最后一个UI实例,如果为false或者没有,就返回this(jQuery对象),进行链式操作

    }

    上面的问题,就是如果要调用一组元素的UI实例,我们只能得到最后一个UI实例,尽管我们可以每次只选择一个元素进行UI操作,但是这无法保证。

    有一种更好的方式,请看源码:

    $.fn.tooltip = function(options){

      var api = [];

      this.each(function(){

        api.push(new Tooltip(this, options));    //把UI实例存入到一个数组中api

      });

      return options.api ? $.ui.api(api) : this;   //当需要对UI实例进行操作时,返回$.ui.api(api),$.ui.api方法请看下面源码

    }

    (function($){

      $.ui = $.ui || {};

      $.ui.api = function(opts){     //这里的opts是[UI实例1 , UI实例2 , UI实例3......]

        var api = $(opts),first = opts[0];

        for(var name in first){   //遍历UI实例的每一个属性值

          (function(name){

            if(typeof first[name] === "function"){   //如果是实例Tooltip的方法

              api[name] = (/^get[^a-z]/.test(name))?

                function(){  return first[name].apply(first,arguments);   } :  //如果方法名是get开头的方法,那么方法中只执行第一个UI实例的同名方法。

                function(){       //如果不是get开头的方法,那么就执行所有UI实例的同名方法。

                  var arg = arguments;

                  api.each(function(idx){

                    var apix = api[idx];

                    apix[name].apply(apix, arg);

                  });

                }

            }

          })(name);

        }

        return api;    //返回的api对象,有UI实例的所有同名的方法

      }

    })(jQuery);

    var tooltip = $("#div1,#div2").tooltip( {api:true} );

    tooltip.show();   //会同时处理div1和div2两个元素。

    tooltip.getXXX();   //只会处理div1元素。

    这一课的东西,要理解还是需要一定的时间的,反复去看,就理解了。

    下一课,终于来到了MVVM模式的讲解。

    加油!

  • 相关阅读:
    SpringCloud(三):服务消费以及负载均衡(RestTemplate+Ribbon)
    SpringCloud(二):服务的注册与发现(Eureka)
    SpringCloud(一):了解SpringCloud
    SpringBoot(十二):SpringBoot整合Mybatis-Plus
    SpringBoot(十一):SpringBoot整合Redis
    idea使用maven中的tomcat插件开启服务出现java.net.BindException: Address already in use: JVM_Bind :8080错误原因
    SSM框架之SpringMVC(6)异常处理及拦截器
    SSM框架之SpringMVC(5)文件上传
    SSM框架之SpringMVC(4)返回值类型及响应数据类型
    SSM框架之SpringMVC(3)常用注解
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4220941.html
Copyright © 2011-2022 走看看