title: 犀利开发—jQuery内核详解与实践-8_高效开发和使用插件
date: 2018.1.18

toc_fold: unfold

第 1 章 jQ起步

第 2 章 jQ解密技术

第 3 章 高效选择的技巧与原理

第 4 章 文档对象的操作及高效实践

第 5 章 事件封装机制与解析

第 6 章 动画效果设计及其高效实践

第 7 章 Ajax异步通信高效实践

7.1 Ajax应用的准备

7.2 Ajax应用的第一个示例

7.3 从JS角度分析XMLHttpRequest对象

7.4 从jQ角度分析XMLHttpRequest对象

2018.1.18 星期四 23:36 P308

第 8 章 高效开发和使用插件

8.1 创建jQ插件

1 jQ插件的类型

  1. jQ方法
  2. 全局函数
  3. 选择器

    2 解析jQ插件机制

    jQuery.extend() jQuery.fn.extend()
    jQuery.extend({
    minValue:function(a,b){return a<b?a:b}
    
    })
    // 2 jQuery.extend 还可以扩展对象;常见参数
    function fn(options){
    var options=jQuery.extend({name1:value1,name2:value2},options)
    
    }

3 创建jQ全局函数

和上一节 extend方法不同
jQuery.minValue=function(a,b){return a<b?a:b}
为避免自己插件和第三方插件名冲突,自己的封装在一个对象上。而且建议jQuery,非$
jQuery.css8={
    minValue:function(){},
    maxValue:function(){},
}

4 使用jQ.fn对象创建jQ插件

jQuery.fn.test=function(){
    return this.each(function(){//返回迭代的jQuery对象
        alert(this.nodeName)
    })
}

5 使用extend()方法创建jQ插件

jQuery.fn.extend({
    test:function(){  }
})

6 创建自定义选择器

//自定义小于等于
jQuery.expr[":"].le=function(elem,i,match){
    return i<match[3]-0||i==match[3]-0
}

// TODO:jQ选择器的艺术,基于正则的表达式 P317

7 优化jQ默认选择器

// TODO:jQ选择器的艺术,基于正则的表达式

8 封装jQ插件

(function($){
    $.extend($.fn,{
        color:function(options){
            var options=$.extend({bcolor:"moren",fcolor:"moren"},options)
            return this.each(function(){
                $(this).css('backgroundColor',options.bcolor)
            })
        }
    })
})(jQuery)

9 优化jQ插件——开放公共参数

(function($){
    $.extend($.fn,{
        color:function(options){
            // diff
            var options=$.extend({},$.fn.color.default,options)
            return this.each(function(){
                $(this).css('backgroundColor',options.bcolor)
            })
        }
    })
    // add
    $.fn.color.defaults={bcolor:"white","fcolor":"black"}
})(jQuery)
// 用户不再需要重复定义参数 (见#### 0 调用部分,和上面对比)

0 优化jQ插件——开放部分功能

(function($){
    $.extend($.fn,{
        color:function(options){
            // #### 1 调用隐私方法验证参数
            if(!filter.options) return this
            var options=$.extend({},$.fn.color.default,options)
            return this.each(function(){
                $(this).css('color',options.fcolor)
                $(this).css('backgroundColor',options.bcolor)
                // #### 0 add
                var _html=$(this).html()
                _html=$.fn.color.format(_html)
                $(this).html(_html)
            })
        }
    })
    $.fn.color.defaults={bcolor:"white","fcolor":"black"}
    // #### 0 add 开放的功能函数
    $.fn.color.format=function(str){
        return str
    }
    // #### 1 定义隐私函数
    function filter(options){
        return !options||(options&&typeof options==="Object")?true:false
    }

})(jQuery)

//用户传递自己的功能设置,以覆盖插件的默认功能,方便其他用户以当前插件为基础进一步去扩写插件
$(function(){
    $.fn.color.defaults={bcolor:"#eee",color:"#222"}
    $.fn.color.format=function(str){return "<strong>"+str+"</strong>"}

    $("h1").color()
    $("p").color({bcolor:"#f00"})

    $.fn.color.format=function(str){return "<span style='font-size:20px'>"+str+"</span>"}
    $("div").color()
})

1 优化jQ插件——保留插件隐私

(function($){
    $.extend($.fn,{
        parent:function(options){
            var arr=[]
            $.each(this,function(index,value){
                arr.push(value.parentNode)
            })
            arr=$.unique(arr) //临时数组中过滤重复的元素
            // or
            //return this.setArray(arr) //把变量打包为数组返回
            // update
            return this.pushStack(arr)//返回新建的jQuery对象,而不是修改后的当前
        }
    })
})(jQuery)

$(function(){
    var $p=$("p")
    $p.parent().css("border","solid 1px red")
    $p.hide()//$p已被修改,div隐藏,而不是p
    //改进后
    $p.parent().css("border","solid 1px red").end().hide()
        // end()能够恢复被破坏的jQuery对象;  即又回到原来的p
})

1.0版本,与children()之类的DOM遍历方法都有破坏性;1.1后 修正

2 优化jQ插件——非破坏性操作

3 优化jQ插件——添加事件日志

// 1st
jQuery.log=function(msg){
    var html=jQuery('<div class="log"></div>').text(msg)
    jQuery(".logbox").append(html)
}
// 2nd
(function($){
    $.extend($.fn,{
        log:function(msg){
            var html=jQuery('<div class="log"></div>').text(msg)
            return this.each(function(){
                jQuery(".logbox").append(html)
            })
        }
    })
})(jQuery)
// 3rd 自动搜索最近显示信息的日志信息的元素
(function($){
    $.extend($.fn,{
        log:function(msg){
            // 4th 
            if(typeof msg=="object"){
                var str="{ "
                $.each(msg,function(name,value){
                    str+=name+":"+value+","
                })
                str=str.substring(0,str.length-2)//清除最后一个成员的逗号
                str+=" }"
                msg=str
            }
            // 4th end
            return this.each(function(){
                var $this=$(this)
                while($this.length){
                    var $logbox=$this.find(".logbox")//在当前元素内搜索是否存在日志元素
                    if($logbox.length){
                        var html=jQuery('<div class="log"></div>').text(msg)
                        $logbox.append(html)
                        break;//跳出检索
                    }
                    $this=$this.parent()//检索上一级匹配元素
                }
            })
        }
    })
})(jQuery)
// 4th 参数的处理机制

//调用
$(function(){
    $("h1").mouseout(function(event){
        $(this).log({
            nodeName:this.nodeName.toLowerCase(),
            eventType:event.type
        })
    })
    $("p").click(function(event){
        var e=event.type
        $(this).log(this.nodeName.toLowerCase()+"."+e)
    })
})

4 jQ插件应该注意的问题

  1. 命名规则
    jquery.plug-in_name.js
  2. 基本思想
    方法jQuery.fn,功能jQuery
  3. 方法内的this关键字
    插件方法-jQuery对象;jQuery方法,该函数上下文
  4. 迭代匹配元素
    this.ecah() this–>当前匹配的DOM元素
  5. 方法返回值
    除特定,都jQuery对象。或返回创建新的jQuery对象
  6. 方便压缩
    末尾必须加上分号
  7. jQuery和$有区别

// TODO:非常值得思考;写自己的插件,基于或者没有jQuery

2018.1.19 星期五 0:42 P337

2018.1.20 星期六 17:42

8.2 创建jQ插件实战

1 简化式插件设计

$.extend($.fn,{
    showIn:function(speed,fn){
        return this.animate({
            height:"show",
            opacity:"show"
        },speed,fn)
    },
    hideOut:function(){}
})

ajax()–>get(),load(),getJSON(),bind(),click(),mouseover()

2 定宽输出插件

(function($){
    $.extend($,{
        fixedWidth:function(str,length,char){
            str=str.toString()
            if(!char) char="..."
            var num=length-lengthB(str)
            if(num<0){
                str=substringB(str,length-lengthB(char))
            }
            return str
            function substringB(str,length){
                var num=0,len=str.length,lenp=""
                if(len){
                    for(var i=0;i<len;i++){
                        if(num>length) break
                        if(str.charCodeAt(i)>255){
                            num+=2
                            tenp+=str.charAt(i)
                        }else{
                            num++
                            tenp+=str.charAt(i)
                        }
                    }
                    return tenp
                }else{
                    return null
                }
            }
            function lengthB(str){
                var num=0,len=str.length
                if(len){
                    for(var i=0;i<len;i++){
                        if(str.charCodeAt(i)>255){
                            num+=2
                        }else{
                            num++
                        }
                    }
                    return
                }else{
                    return 0
                }
            }
        }
    })
})(jQuery)

3 Tab选项卡插件

(function($){
    var isShow=false
    $.fn.tab=function(options){//类型构造函数
        this.opts=$.extend({},$.fn.tab.defaults,options)
        this._init()
    }
    $.fn.tab.prototype={
        _init:function(){
            var _this=this
            if()

        },
        setDisable:function(index){
            var 
        },
        setEnable:function(index){},
        triggleTab:function(index){},

    }
    $.fn.ta.defaults={

    }
    function showContent(index,opts){

    }
})(jQuery)

8.3 jQ UI插件应用

http://plugins.jquery.com
Ajax,animattion and Effects,Browser Tweaks,…

1 如何使用外部插件

2 认识UI插件

User Interface http://jqueryui.com
交互、部件、效果
demos,docs,themes,ui,external
可自定义选择 下载

3 调整大小

4 日期选择器

18:36

// TODO:第二节,fixedWidth和tab插件的定义,值得学习。包括简化式插件思想
// 自己写写

第 9 章 jQ辅助工具

9.1 检测浏览器

9.2 字符串处理

9.3 数组处理

9.4 多库共存

9.5 数据缓存

9.6 数据队列

9.7 内核工具

第 10 章 使用jQ打造Ajax异步交互式动态网站

2018.1. 星期 P