锋利的jquery 学习笔记 二

Menu

第6章 jQuery与Ajax的应用

  • 6.5jQuery中的Ajax
  • 6.6序列化元素
  • 6.7jQuery中的Ajax全局事件

第7章 jQuery插件的使用和写法

  • 7.1jQuery表单验证插件—Validation
  • 7.2jQuery表单插件—Form
  • 7.4管理Cookie的插件—Cookie
  • 7.6编写jQuery插件

第11章 jQuery性能优化和技巧

  • 11.1jQuery性能优化

第6章 jQuery与Ajax的应用

跨域请求
  • 第一步:配置Php 后台允许跨域
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
//主要为跨域CORS配置的两大基本信息,Origin和headers
  • 第二步:配置Apache web服务器跨域(httpd.conf中)
  • 原始代码
<Directory />
    AllowOverride none
    Require all denied
</Directory>
  • 改为以下代码
<Directory />
    Options FollowSymLinks
    AllowOverride none
    Order deny,allow
    Allow from all
</Directory>
  • 6.5jQuery中的Ajax
  • jQuery ajax - load() 方法
  • 语法:$.load(url,data,function(response,status,xhr))
<button>提交</button>
<script type="text/javascript">
 $("button").click(function () {
     $("#resText").load("http://localhost/hello.php",   // return的内容给id为restext的div
         function (data, status, xhr) {    // 检测状态,如果状态为success,就打印载入成功
             if(status=="success"){
                 alert("loaded...")
             }
         })
 })

  • 6.5.2 $.get()方法和$.post()方法
  • 如果需要传递一些参数给服务器中的页面,那么可以使用 $.get()或者 $.post()方法(或者是后面要讲解的$.ajax()方法)。
  1. $.get()方法
  • get() 方法通过远程 HTTP GET 请求载入信息。
  • 这是一个简单的 GET 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。
  • $.get()方法使用GET方式来进行异步请求。
    语法:$(selector).get(url,data,callback(response,status,xhr),dataType)
$(function(){
    $("#send").click(function(){
        $.get("http://localhost/get1.php", {
            username:$("#username").val() ,
            content:$("#content").val()
        }, function (data, status){
            $("#resText").html(data)
        });
    })
})
  • get()方法返回XML文档数据
  • 由于服务器端返回的数据格式是XML文档,因此需要对返回的数据进行处理,前面的章节已经介绍过jQuery强大的DOM处理能力,处理XML文档与处理HTML文档一样,也可以使用常规的attr()、find()、filter()以及其他方法。jQuery代码如下:
// html代码同上;
$(function(){
    $("#send").click(function(){
        $.get("http://localhost/get2.php", {
            username :  $("#username").val() ,
            content :  $("#content").val()
        }, function (data, textStatus){
            var username = $(data).find("comment").attr("username");
            var content = $(data).find("comment content").text();
            var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
            alert(txtHtml); // 把返回的数据添加到页面上
        });
    })
})
  • get()方法返回JSON文件
  • 由于服务器端返回的数据格式是JSON文件,因此需要对返回的数据进行处理之后,才可以将新的HTML数据添加到主页面中。jQuery代码如下:
//HTML代码同上
$(function(){
    $("#send").click(function(){
        $.get("http://localhost/get3.php", {
            username :  $("#username").val() ,
            content :  $("#content").val()
        }, function (data, textStatus){
            jsondata = JSON.parse(data)  //返回的是js字符串, 需要转换为json对象;
            var username = jsondata.username;
            var content = jsondata.content;
            var txtHtml = "<div class='comment'><h6>"
                +username+":</h6><p class='para'>"
                +content+"</p></div>";
            $("#resText").html(txtHtml);
        },"json");
    })
})
  • 在上面的代码中,将$.get()方法的第4个参数(type)设置为“json”来代表期待服务器端返回的数据格式。
  1. $.post()方法
  • 它与$.get()方法的结构和使用方式都相同,不过它们之间仍然有以下区别。
    • GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器。当然,在Ajax请求中,这种区别对用户是不可见的。
    • GET方式对传输的数据有大小限制(通常不能大于2KB),而使用POST方式传递的数据量要比GET方式大得多(理论上不受限制)。
    • GET 方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全性问题,而POST方式相对来说就可以避免这些问题。
    • GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以用$_GET[]获取,而 POST 方式可以用$_POST[]获取。两种方式都可以用$_REQUEST[]来获取。因此只需要改变jQuery函数,就可以将程序在GET请求和POST请求之间切换。

  • 6.5.3 $.getScript()方法和 $.getJson()方法
  1. $.getScript()
  • 有时候,在页面初次加载时就取得所需的全部JavaScript文件是完全没有必要的。虽然可以在需要哪个JavaScript文件时,动态地创建<script>标签,jQuery代码如下:
$(document.createElement("script")).attr("src","test.js").appendTo("head");
// 或者
$("<script type='text/javascript' src='test.js'/>").appendTo("head");
  • jQuery 提供了$.getScript()方法来直接加载.js文件,与加载一个HTML片段一样简单方便,并且不需要对JavaScript文件进行处理,JavaScript文件会自动执行。
$(function () {
    $("button").click(function () {
        $.getScript("alert.js", function (data, status) {
            $("div").html(data);
            if (status=="success"){
                alert("called..")
            }
        })
    })
})

  1. $.getJSON()
  • $.getJSON()方法用于加载JSON文件
$("button").click(function () {
    $.getJSON("getjson.json", function (data) {   // JSONParse载入的json文件,
        $.each(data,function (key, value) {         // 遍历data的key 和 value
            alert(key + " " + value)
        })
    })
})

  • 6.5.4 $.ajax()方法
  • $.ajax()方法是jQuery最底层的Ajax实现。
  • 参数以key/value的形式存在,所有参数都是可选的。
$("button").click(function () {
     $.ajax({
         type:"GET",                                  // 传递数据方式;
         url:"http://localhost/get1.php",            // 文件要放在服务器里才会返回数据;
         data:{name:"Bob", age:"17"},                // 也可以直接写字符串"&name=Bob&age=17"
         dataType:"html",
         success:function (data,status) {
             alert(data);
            $("div").html(data);
            if(status=="success"){
                alert("return data success!")
            }
         },
         error:function (xhr,status,thrown) {
             alert(status+thrown)
         }
     })
 })

  • 6.6序列化元素
  1. serialize()方法
  • serialize()方法也是作用于一个jQuery对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求。
  • serialize()方法,它会自动编码。
    -因为serialize()方法作用于jQuery对象,所以不光只有表单能使用它,其他选择器选取的元素也都能使用它,:$(":checkbox,:radio").serialize();
$("button").click(function () {
    $.ajax({
        type:"GET",
        url:"http://localhost/get1.php",
        data:$("#myForm").serialize(),           // get所有form里面的input的val,name是变量;
        dataType:"html",
        success:function (data,status) {
            alert(data);
            $("div").html(data);
            if(status=="success"){
                alert("return data success!")
            }
        },
        error:function (xhr,status,thrown) {
            alert(status+thrown)
        }
    })
})

  1. serializeArray()方法
  • serializeArray将DOM元素序列化后,返回JSON格式的数据。
  • var fields = $(":checkbox,:radio").serializeArray();
<form>
    <input type="text" name="check1" id="check1">你喜欢夏天吗1?        <!--input 必须要有name属性。name会作为变量名传递-->
    <input type="text" name="check2" id="check2">你喜欢夏天吗2?
    <input type="text" name="check3" id="check3">你喜欢夏天吗3?
    <input type="text" name="check4" id="check4">你喜欢夏天吗4?
</form>
<button>提交</button>
<script>
    $(function () {
        $("button").click(function () {
            var re = $("input").serializeArray();
            $.each(re, function (i, item) {
                alert(i + item.value)                           // 键值对一组。通过item.value获取值
            })
        })
    })
</script>

  1. $.param()方法
  • 它是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。
var obj = $.param({name:"bob",age:17});
document.write(obj)       // name=bob&age=17 

  • 6.7jQuery中的Ajax全局事件

  • jQuery简化Ajax操作不仅体现在调用Ajax方法和处理响应方面,而且还体现在对调用Ajax方法的过程中的HTTP请求的控制。通过jQuery提供的一些自定义全局函数,能够为各种与Ajax相关的事件注册回调函数。例如当 Ajax 请求开始时,会触发 ajaxStart()方法的回调函数;当 Ajax请求结束时,会触发 ajaxStop()方法的回调函数。这些方法都是全局的方法,因此无论创建它们的代码位于何处,只要有Ajax请求发生时,就会触发它们。在前面例子中,远程读取Flickr.com网站的图片速度可能会比较慢,如果在加载的过程中,不给用户提供一些提示和反馈信息,很容易让用户误认为按钮单击无用,使用户对网站失去信心。

  • 此时,就需要为网页添加一个提示信息,常用的提示信息是“加载中...”,代码如下:

<div id="loading">加载中…</div>

然后用CSS控制元素隐藏,当Ajax请求开始的时候,将此元素显示,用来提示用户Ajax请求正在进行。当Ajax请求结束后,将此元素隐藏。代码如下:

$("#loading").ajaxStart(function(){
    $(this).show();
});
$("#loading").ajaxStop(function(){
    $(this).hide();
}); //也可以使用链式写法
  • 其它Ajax全局事件
    • $.ajaxComplete() // 针对每一个请求
    • $.ajaxError() // 当请求发生错误时执行的函数,捕捉到的错误可以作为最后一个参数传递;
    • $.ajaxSend() // 在请求发送前执行的函数;
    • $.ajaxSuccess() // 在请求成功时触发;
    • ajaxStart(),ajaxStop() // 是针对文本中所有的ajax请求的,当第一个ajax请求发送时触发ajaxStart()事件,当最后一个ajax请求完成时,触发ajaxStop()事件,不同的是,ajaxSend()和ajaxComplete是针对文本中每一次的ajax请求的。所以如果你在文本中一次使用了3个请求,ajaxStart()会在第一个请求发起时触发,ajaxStop()会在最后一个请求结束时触发,所以它们常常组合用于显示loading等待框等。因为他们处理的是一群ajax请求,所以它们的回调函数中没有任何参数;

第7章 jQuery插件的使用和写法

  • 7.1jQuery表单验证插件—Validation

  • 最常使用JavaScript的场合就是表单的验证,而jQuery作为一个优秀的JavaScript库,也提供了一个优秀的表单验证插件—Validation。 Validation拥有如下特点。

    • 内置验证规则:拥有必填、数字、E-Mail、URL和信用卡号码等19类内置验证规则。
    • 自定义验证规则:可以很方便地自定义验证规则。
    • 简单强大的验证信息提示:默认了验证信息提示,并提供自定义覆盖默认提示信息的功能。
    • 实时验证:可以通过keyup或blur事件触发验证,而不仅仅在表单提交的时候验证。
  • 引入Validation查件

 // 下载地址:https://github.com/jquery-validation/jquery-validation/releases
<script src="./js/jquery.validate.js" type="text/javascript"></script>   // 插件本身
<script src="./js/jquery-validation/dist/localization/messages_zh.js" type="text/javascript"></script> // 中文补丁
  • 7.1.5 验证信息 and 7.1.6 自定义验证规则
<form class="cmxform" id="commentForm" method="get" action="#">
    <fieldset>
        <legend>一个简单的验证带验证提示的评论例子</legend>
        <p>
            <label for="cusername">姓名</label><em>*</em>
            <input id="cusername" name="username"
                   size="25"  />
        </p>
        <p>
            <label for="cemail">电子邮件</label><em>*</em>
            <input id="cemail" name="email"
                   size="25"  />
        </p>
        <p>
            <label for="curl">网址</label><em>&nbsp;</em>
            <input id="curl" name="url"
                   size="25"  value="" />
        </p>
        <p>
            <label for="ccomment">你的评论</label><em>*</em>
            <textarea id="ccomment" name="comment"
                      cols="22"></textarea>
        </p>
        <p>
            <label for="cvalcode">验证码</label>
            <input id="cvalcode" name="valcode" size="25"  value="" />=7+9
        </p>
        <p>
            <input class="submit" type="submit" value="提交"/>
        </p>
    </fieldset>
</form>
<script>
    $.validator.addMethod(                  // 创建**自定义规则**的方法
        "formula",                 // define验证规则的名称
        function(value, element, param) {   //怎么验证的function;value==input里的value,element==input name的值入,param==规则的值;
            return value == eval(param)      //  是否符合规则 true false
        }, "wrong number");                   //  错误提示信息

    $("#commentForm").validate({            // 调用规则验证指定元素里相应的name元素是否符合规则
        rules: {                               //
            username: {required: true, minlength: 2},      // name属性是username的元素 用该规则验证;
            email: {required: true, email: true},
            url:"url",
            comment: "required",
            valcode: {formula: "7+9"}                       //  name属性是valcode的元素用formula的自定义规则来验证,"7+9"传給param
        },
        messages: {                                         //   自定义设置错误提示信息
            username: "用户名是必填项目",
            email: {
                required: "邮箱是必填项目",
                email:"邮箱格式不正确"
            },
            url:"网址错拉",
            comment: "必填"
        }
    })
</script>

  • 7.2jQuery表单插件—Form

  • jQuery Form插件是一个优秀的Ajax表单插件,可以非常容易地、无侵入地升级HTML表单以支持Ajax。jQuery Form有两个核心方法—ajaxForm()和ajaxSubmit(),它们集合了从控制表单元素到决定如何管理提交进程的功能。另外,插件还包括其他的一些方法:formToArray()、formSerialize()、fieldSerialize()、fieldValue()、clearForm()、clearFields()和resetForm()等。

  • 下载地址:http://jquery.malsup.com/form/#download

<body>
<form id="myForm" action="http://localhost/get1.php" method="GET">
    名称: <input type="text" name="name" /> <br/>
    地址: <input type="text" name="address" /><br/>
    自我介绍: <textarea name="comment"></textarea> <br/>
    <input type="submit" id="test" value="提交" /> <br/>
    <div id="output1" style="display:none">提交成功!欢迎下次再来</div>
</form>
<div  class='comment'>已有评论:</div>
<div id="resText" >
</div>
</body>
<script>
    $(document).ready(function() {
        var options = {
            target:        '#resText',   // target element(s) to be updated with server response
            beforeSubmit:  showRequest,  // pre-submit callback
            success:       showResponse,  // post-submit callback

            // other available options:
            // url: "http://localhost/demo.php"         // override for form's 'action' attribute
            //type:      type        // 'get' or 'post', override for form's 'method' attribute
            //dataType:  null        // 'xml', 'script', or 'json' (expected server response type)
            //clearForm: true        // clear all form fields after successful submit
            //resetForm: true        // reset the form after successful submit

            // $.ajax options can be used here too, for example:
            //timeout:   3000
        }

        $('#myForm').submit(function() {
            $(this).ajaxSubmit(options);
            return false;
        });
    })
        // 提交前的回调函数;
        // 在里面进行表单验证,利用validate插件来进行验证;
        function showRequest(formData, jqForm, options) {
            $("#myForm").validate({            // 调用规则验证指定元素里相应的name元素是否符合规则
                rules: {                               //
                    name: {required: true, minlength: 2},      // name属性是username的元素 用该规则验证;
                    address: {required: true, minlength: 6},
                    comment: "required"
                }
            })
            var p = $("#myForm").valid()     // 如果验证通过为true再提交;提交就是return true
            if (String(p) == "true"){        // validate的valid方法会返回true or false
                alert("in if true;")
                var queryString = $.param(formData);
                alert('aaaaaaAbout to submit: \n\n' + queryString);
                return true;
            }
            else{
                alert("in else false;")       // 没通过则不提交;
                return false
            }
    }
  // 提交后的回调函数。得到返回的数据和状态等;
    function showResponse(responseText, statusText, xhr, $form)  { 
        alert('status: ' + statusText + '\n\nresponseText: \n' + responseText +
            '\n\nThe output div should have already been updated with the responseText.');
    }
</script>

  • 7.4管理Cookie的插件—Cookie
  • 插件描述:jquery.cookie.js是一个强大的用来操作 Cookie 的插件,本文讲述如何对cookie进行写入,删除,修改等操作。
    下载地址:插件描述:jquery.cookie.js是一个强大的用来操作 Cookie 的插件,本文讲述如何对cookie进行写入,删除,修改等操作。
<head>
    <script src="./js/jquery.cookie.js" type="text/javascript"></script>
</head>
<body>
用户名:<input type="text" name="username" id="username"/> <br/>
<input type="checkbox" name="check" id="check"/>记住用户名
</body>
<script>
    $(function() {
        var COOKIE_NAME = 'username';
        // 判断cookie里是否有“username”的cookie,如有就自动把cookie里的值填进去;
        if( $.cookie(COOKIE_NAME) ){
            $("#username").val($.cookie(COOKIE_NAME));
            }
        $("#check").click(function(){
            if(this.checked){
                // 如果checked,那就把现在的username里的值覆盖掉原来cookie里的值,
                // path: 定义cookie的有效路径。默认情况下,该参数的值为创建 cookie 的网页所在路径 。
                // 如果你想在整个网站中访问这个cookie需要这样设置有效路径:path: '/'。
                $.cookie(COOKIE_NAME, $("#username").val() , {
                    // 可选参数:
                    path: '/',
                    expires: 10,
                    domain:"example.com",
                    secure:true,
                });
            }else{
                // 如果你想删除一个定义 了有效路径的 cookie,你需要在调用函数时包含这个路径:$.cookie('the_cookie', null,{ path: '/' });。
                $.cookie(COOKIE_NAME, '', { path: '/' });
            }
        });
    });
</script>
  • expires:(Number|Date)有效期。可以设置一个整数作为有效期(单位:天),也可以直接设置一个日期对象作为Cookie的过期日期。如果指定日期为负数,例如已经过去的日子,那么此 Cookie 将被删除;如果不设置或者设置为null,那么此 Cookie 将被当作 Session Cookie处理,并且在浏览器关闭后删除。
  • path:(String)cookie的路径属性。默认是创建该Cookie的页面路径。
  • domain:(String)cookie的域名属性。默认是创建该Cookie的页面域名。
  • secure:(Boolean)如果设为true,那么此 Cookie的传输会要求一个安全协议,例如HTTPS。

  • 7.6编写jQuery插件

  • 7.6.2 插件的基本要点

    • jQuery插件的文件名推荐命名为jquery.[插件名].js,以免和其他JavaScript库插件混淆。例如命名为jquery.color.js。
    • 所有的对象方法都应当附加到jQuery.fn对象上,而所有的全局函数都应当附加到jQuery对象本身上。
    • 在插件内部,this指向的是当前通过选择器获取的jQuery对象,而不像一般的方法那样,例如click()方法,内部的this指向的是DOM元素。
    • 可以通过this.each来遍历所有元素。
    • 所有的方法或函数插件,都应当以分号结尾,否则压缩的时候可能出现问题。为了更稳妥些,甚至可以在插件头部先加上一个分号,以免他人的不规范代码给插件带来影响。具体方法可以参考后面的代码。
    • 插件应该返回一个jQuery对象,以保证插件的可链式操作。除非插件需要返回的是一些需要获取的量,例如字符串或者数组等。
    • 避免在插件内部使用作为jQuery对象的别名,而应使用完整的jQuery来表示。这样可以避免冲突。当然,也可以利用闭包这种技巧来回避这个问题,使插件内部继续使用作为jQuery的别名。很多插件都是这么做的,本书也会利用这种形式。
  • 7.6.3 插件中的闭包

// 可以在插件头尾都加上一个分号,以免他人的不规范代码给插件带来影响。
;(function test($) {             
    var name = "Bob";
    var func = function(){
      alert(name)
    };
    $.func = func    // 让匿名函数内部的函数func()可在全局范围内访问;
})(jQuery)

$.func()    // 调用匿名函数内部的func函数;func函数可调用到匿名函数内部的其它局部变量;

  • 7.6.4 jQuery插件的机制
  • jQuery提供了两个用于扩展jQuery功能的方法,即jQuery.fn.extend()方法和jQuery.extend()方法。
// $.extend 扩展对象
function options(obj1, obj2){
    target = {
        name: "name",
        age: "0",
        job: null
    }
    // 用后面的对象数据合并到第一个target对象
    jQuery.extend(target, obj1, obj2)   
    return options
}
newOptions = options({name:"Bob"},{age:1})
    // 遍历对象的item
$.each(newOptions,function (k,v) { 
    alert(k + v)
})

  • 7.6.5 编写jQuery插件
  • 插件编写:
;(function ($) {
    $.fn.extend({
        "color":function (colorName) {
            if(!colorName){
                return this.css("color")
            }else{
                return this.css("color",colorName)
            }
        }})
})(jQuery);
  • 插件使用
<head>
    <script src="./js/jquery.color.js" type="text/javascript"></script>
</head>
<body>
<div id="mydiv" style="color:red">div test</div>
</body>
<script>
    alert($("#mydiv").color()) // get color
    alert($("#mydiv").color("cyan")) // set color
  • 表格隔行变色插件
// html
<head>
<style>
        .odd{
            background-color:orange;
        }

        .selected{
            background-color:cyan;
        }
</style>
    <script src="./js/jquery.alterBgColor.js" type="text/javascript"></script>
</head>
<body>
<table id="table1">
    <thead><tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr></thead>
    <tbody>
    <tr>
        <td><input type="checkbox" name="choice" value=""/></td>
        <td>张山</td>
        <td>男</td>
        <td>浙江宁波</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>李四</td>
        <td>女</td>
        <td>浙江杭州</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
        <td>王五</td>
        <td>男</td>
        <td>湖南长沙</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>找六</td>
        <td>男</td>
        <td>浙江温州</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>Rain</td>
        <td>男</td>
        <td>浙江杭州</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
        <td>MAXMAN</td>
        <td>女</td>
        <td>浙江杭州</td>
    </tr>
    </tbody>
</table>


<br /><br />


<table id="table2">
    <thead><tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr></thead>
    <tbody>
    <tr>
        <td><input type="checkbox" name="choice" value=""/></td>
        <td>张山</td>
        <td>男</td>
        <td>浙江宁波</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>李四</td>
        <td>女</td>
        <td>浙江杭州</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" checked="checked" /></td>
        <td>王五</td>
        <td>男</td>
        <td>湖南长沙</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>找六</td>
        <td>男</td>
        <td>浙江温州</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="choice" value="" /></td>
        <td>Rain</td>
        <td>男</td>
        <td>浙江杭州</td>
    </tr>
    <tr id="mytrr">
        <td><input type="checkbox" name="choice" value="aaa" checked="" /></td>
        <td>MAXMAN</td>
        <td>女</td>
        <td>浙江杭州</td>
    </tr>
    </tbody>
</table>

</body>
<script>
    $("#table2").alterBgColor()
</script>

//插件代码

;(function($){
    $.fn.extend({
            "alterBgColor": function(options){
                var option = {
                    odd:"odd",
                    even:"even",
                    selected:"selected"
                };
                var newOptions = $.extend(option, options);   // 扩展参数对象
                $("tbody>tr:odd", this).addClass(newOptions.odd);  // 给偶数行加上odd class
                $("tbody>tr:even", this).addClass(newOptions.even);
                $("tbody>tr", this).click(function () {           // 给选中的table的tr加上click事件
                    var hasSelected = $(this).hasClass(newOptions.selected);  //判断单击选中的tr是否有class selected
                    // 如果选中的tr已经有class selected 则去掉, 没有则加上;再找到单选框子元素,做同步勾选或取消勾选操作;
                    $(this)[hasSelected? "removeClass": "addClass"](newOptions.selected).find(':checkbox').attr('checked',!hasSelected);
                })
                //如果单选框默认情况下是选择的,则自动加上class selected, 即高色显示
                $('tbody>tr:has(:checked)',this).addClass(newOptions.selected);
                return this  //返回jQuery对象
            }
    })
})(jQuery)

  1. 封装全局函数的插件
//html代码
<head>
    <script src="./js/jquery.trim.js" type="text/javascript"></script>
</head>
<body>
    <input id="input" value="    aabb  "/>
    <input id="in">
</body>
<script>
    text = $("input").val();
    ntext = $.trim(text);
    $("#in").val(ntext)
</script>
// 插件代码
;(function ($) {
        $.extend({"ltrim":function(text){                  // 去除左空格的全局函数
                return (text||"").replace(/^\s+/g, "");    //用正则表达式去掉左空格
            },
            "rtrim":function(text) {
                return (text||"").replace(/\s+$/g, "")
            }
        })
    })(jQuery);
  • (text || "")部分是用于防止传递进来的text这个字符串变量处于未定义之类的特殊状态。如果text是undefined,则返回字符串"",否则返回字符串text。这个处理是为了保证接下来的字符串替换方法replace()方法不会出错。
  • $.fn.extend 和 $.extend 的区别
    • $.extend 是扩展的jQuery这个类本身的方法, 例如$.functionName()
    • $.fn.extend 拓展的是jQuery对象(原型的)的方法, 例如$("#abc").functionName(), 用在jQuery对象上面。

  1. 自定义选择器
  • jQuery 提供了一套方法让用户可以通过制作选择器插件来使用自定义选择器,从而使 jQuery的选择器功能更加完善。
  • 基本格式:
$.expr[':'].test = function(obj, index, meta, stack) {
    /* obj   - is a current DOM element 当前DOM元素
       index - the current loop index in stack 当前元素在stack中的索引,
       meta  - meta data about your selector !!! 用来存参数值,详见带参数的自定义选择器。
       stack - stack of all elements to loop 选择器所选中的元素集。
   
       Return true to include current element 返回 true 就包含当前元素
       Return false to explude current element 返回 false 就抛弃当前元素
    */
};
  • 调用方法:
$('.someClasses:test').doSomething();
  • 创建带参数的自定义选择器,通过meta来实现.
$('.someClasses:test(argument)').doSomething();
  • meta 就会得到如下格式的数组:
[
    ':test(argument)', // full selector 整个自定义选择器
    'test',            // only selector 自定义选择器名称
    '',                // quotes used   使用了什么引号(很明显这里没有)
    'argument'         // parameters    参数
]
  • 例如调用:
$('.someClasses:test("arg1, arg2")').doSomething();
  • meta 就会得到如下格式的数组:
[
    ':test("arg1, arg2")', // full selector 整个自定义选择器
    'test',                // only selector 自定义选择器名称
    '"',                   // quotes used   使用了什么引号(这里用的是双引号)
    'arg1, arg2'           // parameters    参数
]
  • 例子:
$.expr[':'].withAttr = function(obj, index, meta, stack){
    return ($(obj).attr(meta[3]) != '');
};
  • 调用:
$('a:withAttr(rel)').css('background-color', 'yellow');

第11章 jQuery性能优化和技巧

  • 11.1jQuery性能优化
    1. 使用最新版本的jQuery类库
  • 2.使用合适的选择器
    • 选择器性能从高到低:
    • $("#id")
    • ("p"),("div"),$("input")
    • $(".class")
    • $("[attribute=value]")
    • $(":hidden")
  • 注意:
    • 1.尽量使用ID选择器
    • 2.尽量给选择器指定上下文
    • 3.缓存对象
  • 如果你打算在其他函数中使用jQuery对象,那么你可以把它们缓存到全局环境中。如下代码所示:
//在全局范围定义一个对象 (例如: window对象)
window.$my = {
    head : $("head"),
    traffic_light : $("#traffic_light"),
    traffic_button : $("#traffic_button")
};
function do_something(){
// 现在你可以引用存储的结果并操作它们
    var script = document.createElement("script");
$my.head.append(script);
// 当你在函数内部操作是, 可以继续将查询存入全局对象中去.
    $my.cool_results = $("#some_ul li");
$my.other_results = $("#some_table td");
// 将全局函数作为一个普通的jquery对象去使用.
    $my.other_results.css("border-color", "red");
$my.traffic_light.css("border-color", "green");
}
//你也可以在其他函数中使用它
//记住,永远不要让相同的选择器在你的代码里出现多次。
  • 4.循环时的DOM操作
  • 使用jQuery可以很方便的添加,删除或者修改DOM节点,但是在一些循环,例如for(),while()或者$.each()中处理节点时,下面有个实例值得大家注意,代码如下:
var top_100_list = [...], // 假设这里是100个独一无二的字符串
    $mylist = $("#mylist"); // jQuery选择到 <ul> 元素
for (var i=0, l=top_100_list.length; i<l; i++){
    $mylist.append("<li>" + top_100_list[i] + "</li>");
}
  • 以上代码中,我们将每一个新添加的标签元素都作为一个节点添加容器ID中,实际上jQuery操作消耗的性能也不低,所以更好的方式是尽可能的减少DOM操作,这里应该将整个元素字符串在插入DOM之前全部创建好,修改代码如下:
var top_100_list = [...] , $mylist = $("#mylist"),
    top_100_li = ""; // 这个变量将用来存储我们的列表元素
for (var i=0, l=top_100_list.length; i<l; i++){
    top_100_li += "<li>" + top_100_list[i] + "</li>";
}
$mylist.html(top_100_li);
  • 5.数组方式使用jQuery对象
  • 在性能方面,建议使用简单for或者while循环来处理,而不是$.each(),这样能使你的代码更快。
$.each(array, function (i) {
    array[i] = i;
});
//使用for代替each()方法,代码如下:
var array = new Array();
for (var i=0; i< array.length; i++) {
        array[i] = i;
    }
  • 6.事件代理
  • 每一个 JavaScript 事件(例如:click,mouseover 等)都会冒泡到父级节点。当我们需要给多个元素调用同个函数时这点会很有用。比如, 我们要为一个表格绑定这样的行为:点击td后,把背景色设置为红色,代码如下:
$('#myTable td').click(function(){
    $(this).css('background', 'red');
});
  • 假设有100个td元素,在使用以上方式的时候,你绑定了100个事件,这将带来很负面的性能影响。那么有什么更好的方式呢?
    代替这种效率很差的多元素事件监听的方法就是,你只需向它们的父节点绑定一次事件,然后通过event.target获取到点击的当前元素,代码如下:
$('#myTable').click(function(e) {
    var $clicked = $(e.target);  // e.target 捕捉到触发的目标元素
    $clicked.css('background', 'red');
});
  • 同时,在jQuery 1.7中提供了一个新的方式on(),来帮助你将整个事件监听封装到一个便利方法中,如下所示:
$('#myTable').on('click','td',function() {
    $(this).css('background', 'red');
});
  • 7.将你的代码转化成jQuery插件
  • 8.使用join()来拼接字符串
  • 也许你之前一直使用"+"来拼接长字符串,现在你可以改改了。虽然它可能会有点奇怪,但它确实有助于优化性能,尤其是长字符串处理的时候。首先创建一个数组,然后循环,最后使用join()把数组转化为字符串,代码如下:
var array = [];
for(var i=0;i<=10000;i++) {
    array[i] = '<li>'+i+'</li>';
}
$('#list').html(array.join(''));
  • 9.合理利用HTML5的Data属性
  • HTML 5的data属性可以帮助我们插入数据,特别是前后端的数据交换。jQuery的data()方法,有效的利用HTML5的属性,来自动得到数据。下面是个例子:
<div id="d1" data-role="page" data-last-value="43" data-options='{"name":"John"}'></div>
//为了读取数据,你需要使用如下代码:
$("#d1").data("role");                  // "page"
$("#d1").data("lastValue");         //  43
$("#d1").data("options").name; // "John";
  • 10.尽量使用原生的JavaScript方法
  • 11.压缩JavaScript




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,601评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,367评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,249评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,539评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,967评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,929评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,098评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,825评论 0 207
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,609评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,796评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,282评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,603评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,277评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,159评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,959评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,079评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,874评论 2 277