jQuery伐木指南(下)

手握jQuery,横扫DOM树。

介绍Ajax、插件与性能。

注意:本文所用jQuery版本为3.2.1
本文demo的GitHub地址:https://github.com/yrq110/jquery-travel

Ajax

核心概念

  1. GET vs POST
    • GET
      • 非破坏性操作,仅从服务端获得数据,不会改变服务端的数据参数写入url中
      • 会被浏览器缓存
      • 通常将要发送的数据全部写入查询字符串
    • POST
      • 非破坏性操作,
      • 不会被浏览器缓存
      • URL中包含部分查询字符串,数据会被作为post data分开发送
  2. 数据类型
    • text - 传递简短字符串
    • html - 传递在页面中放置的HTML代码块
    • script - 在页面中添加一段脚本
    • json - 传递JSON格式的数据,可以包含字符串、数组和对象。
    • jsonp - 跨域传送JSON数据
    • xml - 使用自定义XML格式传递数据
  3. 异步
    由于默认Ajax是异步的调用,并不能立即获得响应,需要在回调函数中捕获响应。

    1
    2
    3
    4
    5
    var response;
    $.get("http://yrq110.me",function (r) {
    response = r;
    })
    console.log(response); // undefined

    上面这样做得不到reponse数据,改成如下试试

    1
    2
    3
    $.get("http://yrq110.me",function (r) {
    console.log("response: " + r);
    });
  4. 同源安全与JSONP

    • 默认情况下,AJAX请求限制在相同协议、相同端口与相同页面。
      IE10之前的版本不支持跨域的AJAX请求。
    • JSONP服务会将请求的数据包裹在一个<script>标签中,传递给页面加载,这样就能突破同源限制,在这段脚本的所提供的回调函数中会包含请求的数据。

jQuery中的Ajax相关方法

  1. .ajax()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $.ajax({
    url: "http://yrq110.me",
    type: "GET",
    // dataType: "json"
    })
    // 成功后调用的函数,参数为响应信息
    .done(function (r) {
    // console.log(r);
    })
    // 失败后调用的函数,参数为原始请求与状态码
    .fail(function (xhr,status,error) {
    // console.log(e);
    })
    // 不管成功还是失败后都会调用的函数,参数为请求与状态码
    .always(function (xhr,status) {
    // console.log("xhr: " + xhr);
    console.log("status: " + status);
    // alert("the request is complete");
    })
  2. .ajax()设置
    .ajax()函数有很多可以设置的参数,下面是经常使用的一些设置:

    • async - 默认为true,若想发送同步请求可以设为false
    • cache - 可用时会缓存响应,默认对于除了”script”和”jsonp”之外的dataType均为true
    • done - 请求成功时执行的回调函数。包含响应数据、原始请求对象与请求状态描述
    • fail - 请求失败时执行的回调函数。包含原始请求对象与请请求状态描述
    • always - 不管请求是否完成、是否成功或失败,都会执行的回调函数。包含原始请求对象与请求状态描述
    • context - 表示回调函数所运行的域,比如说this指的是回调函数内的对象
    • data - 发送给服务器的数据,可以是一个对象也可以是一个查询字符串,name=yrq&sex=male
    • dataType - 期望从服务器所得到的数据类型
    • jsonp - JSONP请求中查询字符串中的回调名,默认为”callback”
    • timeout - 判断请求失败的等待时间
    • type - 请求类型,”POST”或”GET”,默认为”GET”,也可以使用比如”DLETE”与”PUT”等方法,不过有些浏览器可能不支持
    • url - 请求的URL,是.ajax()中唯一一个必须的参数,其它属性都是可选的
  3. 便捷方法
    若你不需要.ajax()的扩展功能,也不关心错误处理的话,就可以使用其它一些便捷的方法进行AJAX请求。

    • $.get - 提供的URL上执行GET请求
    • $.post - 提供的URL上执行POST请求
    • $.getScript - 在页面中插入一段脚本
    • $.getJSON - 执行GET请求并期望得到JSON格式的响应数据
      1
      2
      3
      $.getScript("test.js",function () {
      hello();
      })

    每种方法都接受如下参数:

    • url - 请求的URL,必须。
    • data - 发送给服务器的数据,可选。对于$.getScript不可用。
    • success callback - 请求成功后的回调函数,可选。
    • data type - 期望从服务器得到的数据类型,可选。
  4. $.fn.load()
    .load()方法从URL获得HTML代码填充指定元素
    1
    $("#message").load("add.html");

Ajax与表单

  1. 序列化
    有两个序列化方法:.serialize() 与 .serializeArray()

    1
    2
    // .serialize()会返回一个形如name=yrq的查询字符串
    console.log($("form").serialize());
    1
    2
    // .serializeArray()会返回一个形如{"name":"yrq"}的对象
    console.log($("form").serializeArray());
  2. 客户端验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 验证输入
    $("#submt_btn").click(
    $("#form").submit(function( event ) {
    console.log(event);
    // 若phone的值的长度为0
    if ( $( "#phone" ).val().length === 0 ) {
    // 阻止表单提交
    event.preventDefault();
    } else {
    $.get("http://yrq110.me",function (r) {
    console.log(r);
    })
    }
    })
    );
  3. 预过滤
    使用$.ajaxPrefilter在请求发送之前修改ajax的设置。
    若只想处理返回数据为json和script的请求,可以在ajaxPrefilter函数中指定:

    1
    2
    3
    $.ajaxPrefilter( "json script", function( options, originalOptions, jqXHR ) {
    // 在这里做一些预过滤操作,不过进针对于指定dataType为"JSON"或"script"的请求
    });

JSONP

使用Yahoo! Query Language上的JSONP数据测试。

1
2
3
4
5
6
7
8
9
10
11
12
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql",
jsonp: "callback",
dataType: "jsonp",
data: {
q: "select title,abstract,url from search.news where query=\"cat\"",
format: "json"
},
success: function( response ) {
console.log( response ); // server response
}
});

Ajax事件

有时想在Ajax请求的开始或结束时执行一些操作,比如隐藏或显示某个元素。不需要在每个Ajax请求中定义这些行为,只需将Ajax事件与元素绑定即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$("#stats")
.ajaxStart(function() {
console.log("ajax start");
$("#stats").html("请求开始");
})
.ajaxStop(function() {
console.log("ajax finished");
$("#stats").html("请求结束");
});
$("#req").click(function () {
$.ajax({
url: "http://yrq110.me",
type: "GET"
})
});

插件

查询插件

官方的jQueryUI

jQueryUI: http://jqueryui.com/

创建插件

  1. jQuery对象方法

    1
    $("p").css("color","red");

    使用$选择元素后会返回一个jQuery对象,这个对象拥有$.fn对象中的一些方法,$.fn对象包含jQuery对象中的所有方法,因此也可以给$.fn对象编写一些自定义方法。

  2. 编写插件

    1
    2
    3
    4
    5
    6
    $.fn.turngreen = function () {
    this.css("color","green");
    };
    $("#begin").click(function () {
    $("p").turngreen();
    });
  3. 链式

    1
    2
    3
    4
    5
    6
    7
    $.fn.turnred = function () {
    this.css("color","red");
    return this;
    };
    $("#chain").click(function () {
    $("#text").turnred().addClass("big");
    });
  4. 避免命名冲突
    使用匿名函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    (function ($) {
    $.fn.turnred = function() {
    this.css( "color", "red" );
    return this;
    };
    }(jQuery));
    $("#chain").click(function () {
    $("#text").turnred().addClass("big");
    });
  5. 最小化插件足迹

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (function ($) {
    // 不好的写法
    $.fn.openPopup = function() {};
    $.fn.closePopup = function() {};
    // 好的写法,通过输入参数控制操作
    $.fn.popup = function( action ) {
    if ( action === "open") {}
    if ( action === "close" ) {}
    };
    }(jQuery));

6.使用each方法
jQuery对象通常是与多个DOM元素关联的,若想一次操作特定元素,可以使用each()方法遍历每个元素。

1
2
3
4
5
6
7
8
9
$.fn.smaller = function () {
return this.each(function () {
this.className = "small";
return this;
});
};
$("#each").click(function () {
$("p").smaller();
});

7.选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.fn.setcolor = function (options) {
var settings = $.extend({
// 默认设置
color: "#ff0000",
bgcolor: "#00ff00"
},options);
return this.css({
color: settings.color,
backgroundColor: settings.bgcolor
});
};
$("#options").click(function () {
$("#op").setcolor({color:"orange"});
});

进阶

1.提供默认设置的访问接口
在编写插件时,应该暴露插件中默认的属性设置,让使用者可以查看或覆盖这些参数,

1
2
3
4
5
6
7
8
9
$.fn.setfontsize = function (options) {
var settings = $.extend({},$.fn.setfontsize.defaults,options);
return this.css({
fontSize : settings.size
});
};
$.fn.setfontsize.defaults = {
"size" : "20px"
};

1
2
3
4
5
6
7
8
// 使用默认设置
$("#default").click(function () {
$("#de").setfontsize();
});
// 覆盖默认设置
$("#default_2").click(function () {
$("#de").setfontsize({"size":"10px"});
});
  1. 提供辅助功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $.fn.setpreword = function (options) {
    return this.each(function() {
    var elem = $( this );
    var markup = elem.html();
    markup = $.fn.setpreword.bestrong( markup );
    elem.html( markup );
    });
    };
    $.fn.setpreword.bestrong = function( txt ) {
    return "Become strong! <strong>" + txt + "</strong>";
    };
    $("#secondary").click(function () {
    $("p").setpreword();
    });
  2. 私有属性
    使用闭包实现内部私有属性与函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    (function($) {
    $.fn.select = function( options ) {
    debug(this);
    };
    function debug( obj ) {
    if ( window.console && window.console.log ) {
    alert( "selection count: " + obj.length );
    }
    };
    })(jQuery);
    $("#private").click(function () {
    $(this).select();
    });
  3. 给予完整的元素控制权
    不要像如下指定具体类型与属性(插件代码)

    1
    2
    $( "<div class='gallery-wrapper' />" ).appendTo( "body" );
    $( ".gallery-wrapper" ).append( "..." );

    可以改成如下这样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var wrapper = $( "<div />" )
    .attr( settings.wrapperAttrs )
    .appendTo( settings.container );
    wrapper.append( "..." );
    var defaults = {
    wrapperAttrs : {
    class: "gallery-wrapper"
    },
    };
    // 接着使用extend方法合并选项与设置
    var settings = $.extend( true, {}, defaults, options );
  4. 提供回调功能
    在options后添加的参数即为回调函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $.fn.setitalic = function (options,callback) {
    var settings = $.extend({},$.fn.setitalic.defaults,options);
    callback(this);
    return $(this).css({
    "font-style" : settings.fontStyle
    })
    };
    $.fn.setitalic.defaults = {
    "fontStyle" : "italic"
    };
    $("#callback").click(function () {
    $(this).setitalic({
    "font-style" : "oblique"
    },function (data) {
    console.log(data);
    })
    })

性能

文章目录
  1. 1. Ajax
    1. 1.1. 核心概念
    2. 1.2. jQuery中的Ajax相关方法
    3. 1.3. Ajax与表单
    4. 1.4. JSONP
    5. 1.5. Ajax事件
  2. 2. 插件
    1. 2.1. 查询插件
    2. 2.2. 创建插件
    3. 2.3. 进阶
  3. 3. 性能
|