目录

1 jQuery实例对象的方法

1.1 结果集的过滤方法

1.1.1 first方法,last方法

1.1.2 next方法,prev方法

1.1.3 parent方法,parents方法,children方法

1.1.4 siblings方法,nextAll方法,prevAll方法

1.1.5 closest方法,find方法

1.1.6 add方法,addBack方法,end方法

1.1.7 filter方法,not方法,has方法

1.1.8 length属性

1.1.9 下标运算符

1.1.10 is方法

1.1.11 get方法

1.1.12 eq方法

1.1.13 each方法,map方法

1.1.14 内置循环

1.2 DOM相关方法

1.2.1 html方法和text方法

1.2.2 addClass方法,removeClass方法,toggleClass方法

1.2.3 css方法

1.2.4 val方法

1.2.5 prop方法,attr方法

1.2.6 removeProp方法,removeAttr方法

1.2.7 data方法

1.2.8 $.fn.load()

1.3 添加、复制和移动网页元素的方法

1.3.1 append方法,appendTo方法

1.3.2 prepend方法,prependTo方法

1.3.3 after方法,insertAfter方法

1.3.4 before方法,insertBefore方法

1.3.5 wrap方法,wrapAll方法,unwrap方法,wrapInner方法

1.3.6 clone方法

1.3.7 remove方法,detach方法,replaceWith方法

1.4 动画效果方法

1.4.1 动画效果的简便方法

1.4.2 animate方法

1.4.3 stop方法,delay方法

1.5 实用工具方法

1.5.1 $.trim

1.5.2 $.contains

1.5.3 $.each,$.map

1.5.4 $.inArray

1.5.5 $.extend

1.5.6 $.proxy

1.5.7 $.data,$.removeData

1.5.8 $.parseHTML,$.parseJSON,$.parseXML

1.5.9 $.makeArray

1.5.10 $.merge

1.5.11 $.now

1.5.12 判断数据类型的方法

1.6 其他方法

1.6.1 serialize()

1.6.2 serializeArray()

1.6.3 链式操作

1.6.4 $(document).ready()

1.6.5 $.noConflict方法


1 jQuery实例对象的方法

1.1 结果集的过滤方法

选择器选出一组符合条件的网页元素以后,jQuery提供了许多方法,可以过滤结果集,返回更准确的目标。

1.1.1 first方法,last方法

first方法返回结果集的第一个成员,last方法返回结果集的最后一个成员。

$("li").first()

$("li").last()

1.1.2 next方法,prev方法

next方法返回紧邻的下一个同级元素,prev方法返回紧邻的上一个同级元素。

$("li").first().next()
$("li").last().prev()

$("li").first().next('.item')
$("li").last().prev('.item')

如果next方法和prev方法带有参数,表示选择符合该参数的同级元素。

1.1.3 parent方法,parents方法,children方法

parent方法返回当前元素的父元素,parents方法返回当前元素的所有上级元素(直到html元素)。

$("p").parent()
$("p").parent(".selected")

$("p").parents()
$("p").parents("div")

children方法返回选中元素的所有子元素。

$("div").children()
$("div").children(".selected")

// 下面的写法结果相同,但是效率较低

$('div > *')
$('div > .selected')

上面这三个方法都接受一个选择器作为参数。

1.1.4 siblings方法,nextAll方法,prevAll方法

siblings方法返回当前元素的所有同级元素。

$('li').first().siblings()
$('li').first().siblings('.item')

nextAll方法返回当前元素其后的所有同级元素,prevAll方法返回当前元素前面的所有同级元素

$('li').first().nextAll()
$('li').last().prevAll()

1.1.5 closest方法,find方法

closest方法返回当前元素,以及当前元素的所有级元素之中,第一个符合条件的元素。find方法返回当前元素的所有符合条件的级元素

$('li').closest('div')
$('div').find('li')

上面代码中的find方法,选中所有div元素下面的li元素,等同于$('li', 'div')。由于这样写缩小了搜索范围,所以要优于$('div li')的写法。

1.1.6 add方法,addBack方法,end方法

add方法用于为结果集添加元素。

$('li').add('p')

addBack方法将当前元素加回原始的结果集。

$('li').parent().addBack()

end方法用于返回原始的结果集。

$('li').first().end()

1.1.7 filter方法,not方法,has方法

filter方法用于过滤结果集,它可以接受多种类型的参数,只返回与参数一致的结果。主要用于自身元素

// 返回符合CSS选择器的结果
$('li').filter('.item')

// 返回函数返回值为true的结果
$("li").filter(function(index) {
    return index % 2 === 1;
})

// 返回符合特定DOM对象的结果
$("li").filter(document.getElementById("unique"))

// 返回符合特定jQuery实例的结果
$("li").filter($("#unique"))

not方法的用法与filter方法完全一致,但是返回相反的结果,即过滤掉匹配项。

$('li').not('.item')

has方法与filter方法作用相同,但是只过滤出子元素符合条件的元素。has和filter区别:filter()用于自身,has()条件是作用于它的后代元素中。

$("li").has("ul")

上面代码返回具有ul子元素的li元素。

1.1.8 length属性

jQuery对象返回的结果集是一个类似数组的对象,包含了所有被选中的网页元素。查看该对象的length属性,可以知道到底选中了多少个结果。

if ( $('li').length === 0 ) {
    console.log('不含li元素');
}

上面代码表示,如果网页没有li元素,则返回对象的length属性等于0。这就是测试有没有选中的标准方法。

所以,如果想知道jQuery有没有选中相应的元素,不能写成下面这样。

if ($('div.foo')) { ... }

因为不管有没有选中,jQuery构造函数总是返回一个实例对象,而对象的布尔值永远是true。使用length属性才是判断有没有选中的正确方法。

if ($('div.foo').length) { ... }

1.1.9 下标运算符

jQuery选择器返回的是一个类似数组的对象(jQuery)。但是,使用下标运算符取出的单个对象,并不是jQuery对象的实例,而是一个DOM对象。

$('li')[0] instanceof jQuery // false
$('li')[0] instanceof Element // true

上面代码表示,下标运算符取出的是Element节点的实例。所以,通常使用下标运算符将jQuery实例转回DOM对象。

1.1.10 is方法

is方法返回一个布尔值,表示选中的结果是否符合某个条件。这个用来验证的条件,可以是CSS选择器,也可以是一个函数,或者DOM元素和jQuery实例。

$('li').is('li') // true

$('li').is($('.item')) 

$('li').is(document.querySelector('li'))

$('li').is(function() {
      return $("strong", this).length === 0;
});

1.1.11 get方法

jQuery实例的get方法是下标运算符的另一种写法。

$('li').get(0) instanceof Element // true

1.1.12 eq方法

如果想要在结果集取出一个jQuery对象的实例,不需要取出DOM对象,则使用eq方法,它的参数是实例在结果集中的位置(从0开始)。

$('li').eq(0) instanceof jQuery // true

由于eq方法返回的是jQuery的实例,所以可以在返回结果上使用jQuery实例对象的方法。

1.1.13 each方法,map方法

这两个方法用于遍历结果集,对每一个成员进行某种操作。

each方法接受一个函数作为参数,依次处理集合中的每一个元素

$('li').each(function( index, element) {
  $(element).prepend( '<em>' + index + ': </em>' );
});

// <li>Hello</li>
// <li>World</li>
// 变为
// <li><em>0: </em>Hello</li>
// <li><em>1: </em>World</li>

从上面代码可以看出,作为each方法参数的函数,本身有两个参数,第一个是当前元素在集合中的位置,第二个是当前元素对应的DOM对象。

map方法的用法与each方法完全一样,区别在于each方法没有返回值,只是对每一个元素执行某种操作,而map方法返回一个新的jQuery对象。

$("input").map(function (index, element){
    return $(this).val();
})
.get()
.join(", ")

上面代码表示,将所有input元素依次取出值,然后通过get方法得到一个包含这些值的数组,最后通过数组的join方法返回一个逗号分割的字符串。

1.1.14 内置循环

jQuery默认对当前结果集进行循环处理,所以如果直接使用jQuery内置的某种方法,each和map方法是不必要的。

$(".class").addClass("highlight");

上面代码会执行一个内部循环,对每一个选中的元素进行addClass操作。由于这个原因,对上面操作加上each方法是不必要的。

$(".class").each(function(index,element){
     $(element).addClass("highlight");
});

// 或者

$(".class").each(function(){
    $(this).addClass("highlight");
});

上面代码的each方法,都是没必要使用的。

由于内置循环的存在,从性能考虑,应该尽量减少不必要的操作步骤。

$(".class").css("color", "green").css("font-size", "16px");

// 应该写成

$(".class").css({ 
  "color": "green",
  "font-size": "16px"
});

1.2 DOM相关方法

许多方法可以对DOM元素进行处理。

1.2.1 html方法和text方法

html方法返回该元素包含的HTML代码,text方法返回该元素包含的文本。

假定网页只含有一个p元素。

<p><em>Hello World!</em></p>

html方法和text方法的返回结果分别如下。

$('p').html()
// <em>Hello World!</em> 

$('p').text()
// Hello World!

jQuery的许多方法都是取值器(getter)与赋值器(setter)的合一,即取值和赋值都是同一个方法,不使用参数的时候为取值器,使用参数的时候为赋值器。

上面代码的html方法和text方法都没有参数,就会当作取值器使用,取回结果集的第一个元素所包含的内容。如果对这两个方法提供参数,就是当作赋值器使用,修改结果集所有成员的内容,并返回原来的结果集,以便进行链式操作。

$('p').html('<strong>你好</strong>')
// 网页代码变为<p><strong>你好</strong></p> 

$('p').text('你好')
// 网页代码变为<p>你好</p>

下面要讲到的jQuery其他许多方法,都采用这种同一个方法既是取值器又是赋值器的模式。

html方法和text方法还可以接受一个函数作为参数,函数的返回值就是网页元素所要包含的新的代码和文本。这个函数接受两个参数,第一个是网页元素在集合中的位置,第二个参数是网页元素原来的代码或文本。

$('li').html(function (i, v){
    return (i + ': ' + v);        
})

// <li>Hello</li>
// <li>World</li>
// 变为
// <li>0: Hello</li>
// <li>1: World</li>

1.2.2 addClass方法,removeClass方法,toggleClass方法

addClass方法用于添加一个类,removeClass方法用于移除一个类,toggleClass方法用于折叠一个类(如果无就添加,如果有就移除)

$('li').addClass('special')
$('li').removeClass('special')
$('li').toggleClass('special')

1.2.3 css方法

css方法用于改变CSS设置。

该方法可以作为取值器使用。

$('h1').css('fontSize');

css方法的参数是css属性名。这里需要注意,CSS属性名的CSS写法和DOM写法,两者都可以接受,比如font-size和fontSize都行

css方法也可以作为赋值器使用。

$('li').css('padding-left', '20px')
// 或者
$('li').css({
  'padding-left': '20px'
});

上面两种形式都可以用于赋值,jQuery赋值器基本上都是如此。

1.2.4 val方法

val方法返回结果集第一个元素的值,或者设置当前结果集所有元素的值。

$('input[type="text"]').val()
$('input[type="text"]').val('new value')

1.2.5 prop方法,attr方法

首先,这里要区分两种属性。

一种是网页元素的属性,比如a元素的href属性、img元素的src属性。这要使用attr方法读写。

// 读取属性值
$('textarea').attr(name)

//写入属性值
$('textarea').attr(name, val)

下面是通过设置a元素的target属性,使得网页上的外部链接在新窗口打开的例子。

$('a[href^="http"]').attr('target', '_blank');
$('a[href^="//"]').attr('target', '_blank');
$('a[href^="' + window.location.origin + '"]').attr('target', '_self');

另一种是DOM元素的属性,比如tagNamenodeNamenodeType等等。这要使用prop方法读写。

// 读取属性值
$('textarea').prop(name)

// 写入属性值
$('textarea').prop(name, val)

所以,attr方法和prop方法针对的是不同的属性。在英语中,attr是attribute的缩写,prop是property的缩写,中文很难表达出这种差异。有时,attr方法和prop方法对同一个属性会读到不一样的值。比如,网页上有一个单选框。

<input type="checkbox" checked="checked" />

对于checked属性,attr方法读到的是checked,prop方法读到的是true。

$(input[type=checkbox]).attr("checked") // "checked"

$(input[type=checkbox]).prop("checked") // true

可以看到,attr方法读取的是网页上该属性的值,而prop方法读取的是DOM元素的该属性的值,根据规范,element.checked应该返回一个布尔值。所以,判断单选框是否选中,要使用prop方法。事实上,不管这个单选框是否选中,attr("checked")的返回值都是checked。

if ($(elem).prop("checked")) { /*... */ };

// 下面两种方法亦可

if ( elem.checked ) { /*...*/ };
if ( $(elem).is(":checked") ) { /*...*/ };

prop和attr的区别个人总结

  • 如果是name,value之类的取值prop和attr结果是一样的,
  • 对于具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled,prop()返回的结果是true或false,而attr()就是对应的值,
  • 如果是未声明定义的属性,prop返回false或0或""(空字符串),而attr()一律返回undefined

1.2.6 removeProp方法,removeAttr方法

removeProp方法移除某个DOM属性,removeAttr方法移除某个HTML属性。

$("a").prop("oldValue",1234).removeProp('oldValue')
$('a').removeAttr("title")

1.2.7 data方法

data方法用于在一个DOM对象上储存数据。

// 储存数据
$("body").data("foo", 52);

// 读取数据
$("body").data("foo");

该方法可以在DOM节点上储存各种类型的数据。

1.2.8 $.fn.load()

$.fn.load用于获取服务器端的HTML文件,将其放入当前元素

$('#newContent').load('/foo.html');

$.fn.load方法还可以指定一个选择器,将远程文件中匹配选择器的部分,放入当前元素,并指定操作完成时的回调函数。

$('#newContent').load('/foo.html #myDiv h1:first',
    function(html) {
        console.log('内容更新!');
});

上面代码只加载foo.html中匹配“#myDiv h1:first”的部分,加载完成后会运行指定的回调函数。

$('#main-menu a').click(function(event) {
   event.preventDefault();

   $('#main').load(this.href + ' #main *');
});

上面的代码将指定网页中匹配“#main *”,加载入当前的main元素。星号表示匹配main元素包含的所有子元素,如果不加这个星号,就会加载整个main元素(包括其本身),导致一个main元素中还有另一个main元素。

load方法可以附加一个字符串或对象作为参数,一起向服务器提交。如果是字符串,则采用GET方法提交;如果是对象,则采用POST方法提交。

$( "#feeds" ).load( "feeds.php", { limit: 25 }, function() {
  console.log( "已经载入" );
});

上面代码将{ limit: 25 }通过POST方法向服务器提交。

load方法的回调函数,可以用来向用户提示操作已经完成。

$('#main-menu a').click(function(event) {
   event.preventDefault();

   $('#main').load(this.href + ' #main *', function(responseText, status) {
      if (status === 'success') {
         $('#notification-bar').text('加载成功!');
      } else {
         $('#notification-bar').text('出错了!');
      }
   });
});

1.3 添加、复制和移动网页元素的方法

jQuery方法提供一系列方法,可以改变元素在文档中的位置。

1.3.1 append方法,appendTo方法

append方法将参数中的元素插入当前元素的尾部。

$("div").append("<p>World</p>")

// <div>Hello </div>
// 变为
// <div>Hello <p>World</p></div>

appendTo方法将当前元素插入参数中的元素尾部

$("<p>World</p>").appendTo("div")

上面代码返回与前一个例子一样的结果。

1.3.2 prepend方法,prependTo方法

prepend方法将参数中的元素,变为当前元素的第一个子元素。

$("p").prepend("Hello ")

// <p>World</p>
// 变为
// <p>Hello World</p>

如果prepend方法的参数不是新生成的元素,而是当前页面已存在的元素,则会产生移动元素的效果。

$("p").prepend("strong")

// <strong>Hello </strong><p>World</p>
// 变为
// <p><strong>Hello </strong>World</p>

上面代码运行后,strong元素的位置将发生移动,而不是克隆一个新的strong元素。不过,如果当前结果集包含多个元素,则除了第一个以后,后面的p元素都将插入一个克隆的strong子元素。prependTo方法将当前元素变为参数中的元素的第一个子元素。

$("<p></p>").prependTo("div")

// <div></div>
// 变为
// <div><p></p></div>

1.3.3 after方法,insertAfter方法

after方法将参数中的元素插在当前元素后面。

$("div").after("<p></p>")

// <div></div>
// 变为
// <div></div><p></p>

insertAfter方法将当前元素插在参数中的元素后面。

$("<p></p>").insertAfter("div")

上面代码返回与前一个例子一样的结果。

1.3.4 before方法,insertBefore方法

before方法将参数中的元素插在当前元素的前面。

$("div").before("<p></p>")

// <div></div>
// 变为
// <p></p><div></div>

insertBefore方法将当前元素插在参数中的元素的前面。

$("<p></p>").insertBefore("div")

上面代码返回与前一个例子一样的结果。

1.3.5 wrap方法,wrapAll方法,unwrap方法,wrapInner方法

wrap方法将参数中的元素变成当前元素的父元素。

$("p").wrap("<div></div>")

// <p></p>
// 变为
// <div><p></p></div>

wrap方法的参数还可以是一个函数。

$("p").wrap(function() {
  return "<div></div>";
})

上面代码返回与前一个例子一样的结果。

wrapAll方法为结果集的所有元素,添加一个共同的父元素。

$("p").wrapAll("<div></div>")

// <p></p><p></p>
// 变为
// <div><p></p><p></p></div>

unwrap方法移除当前元素的父元素。

$("p").unwrap()

// <div><p></p></div>
// 变为
// <p></p>

wrapInner方法为当前元素的所有子元素,添加一个父元素。

$("p").wrapInner('<strong></strong>')

// <p>Hello</p>
// 变为
// <p><strong>Hello</strong></p>

1.3.6 clone方法

clone方法克隆当前元素。

var clones = $('li').clone();

对于那些有id属性的节点,clone方法会连id属性一起克隆。所以,要把克隆的节点插入文档的时候,务必要修改或移除id属性

1.3.7 remove方法,detach方法,replaceWith方法

remove方法移除并返回一个元素,取消该元素上所有事件的绑定detach方法也是移除并返回一个元素但是不取消该元素上所有事件的绑定。

$('p').remove()
$('p').detach()

replaceWith方法用参数中的元素,替换并返回当前元素,取消当前元素的所有事件的绑定。

$('p').replaceWith('<div></div>')

1.4 动画效果方法

jQuery提供一些方法,可以很容易地显示网页动画效果。但是,总体上来说,它们不如CSS动画强大和节省资源,所以应该优先考虑使用CSS动画。

如果将jQuery.fx.off设为true,就可以将所有动画效果关闭,使得网页元素的各种变化一步到位,没有中间过渡的动画效果。

1.4.1 动画效果的简便方法

jQuery提供以下一些动画效果方法。

  • show:显示当前元素。
  • hide:隐藏当前元素。
  • toggle:显示或隐藏当前元素。
  • fadeIn:将当前元素的不透明度(opacity)逐步提升到100%。
  • fadeOut:将当前元素的不透明度逐步降为0%。
  • fadeToggle:以逐渐透明或逐渐不透明的方式,折叠显示当前元素。
  • slideDown:以从上向下滑入的方式显示当前元素。
  • slideUp:以从下向上滑出的方式隐藏当前元素。
  • slideToggle:以垂直滑入或滑出的方式,折叠显示当前元素。

上面这些方法可以不带参数调用,也可以接受毫秒或预定义的关键字作为参数

$('.hidden').show();
$('.hidden').show(300);
$('.hidden').show('slow');

上面三行代码分别表示,以默认速度、300毫秒、较慢的速度隐藏一个元素。

jQuery预定义的关键字是在jQuery.fx.speeds对象上面,可以自行改动这些值,或者创造新的值。

jQuery.fx.speeds.fast = 50;
jQuery.fx.speeds.slow = 3000;
jQuery.fx.speeds.normal = 1000;

上面三行代码重新定义fast、normal、slow关键字对应的毫秒数。

你还可以定义自己的关键字。

jQuery.fx.speeds.blazing = 30;

// 调用
$('.hidden').show('blazing');

这些方法还可以接受一个函数,作为第二个参数,表示动画结束后的回调函数。

$('p').fadeOut(300, function() {
  $(this).remove();
});

上面代码表示,p元素以300毫秒的速度淡出,然后调用回调函数,将其从DOM中移除。

使用按钮控制某个元素折叠显示的代码如下。

// Fade
$('.btn').click(function () {
  $('.element').fadeToggle('slow');
});

// Toggle
$('.btn').click(function () {
  $('.element').slideToggle('slow');
});

1.4.2 animate方法

上面这些动画效果方法,实际上都是animate方法的简便写法。在幕后,jQuery都是统一使用animate方法生成各种动画效果。

$('a.top').click(function (e) {
  e.preventDefault();
  $('html, body').animate({scrollTop: 0}, 800);
});

上面代码是点击链接,回到页面头部的写法。其中,animate方法接受两个参数,第一个参数是一个对象,表示动画结束时相关CSS属性的值,第二个参数是动画持续的毫秒数。需要注意的是,第一个参数对象的成员名称,必须与CSS属性名称一致,如果CSS属性名称带有连字号,则需要用“骆驼拼写法”改写。

animate方法还可以接受第三个参数,表示动画结束时的回调函数

$('div').animate({
    left: '+=50', // 增加50
    opacity: 0.25,
    fontSize: '12px'
  },
  300, // 持续时间
  function() { // 回调函数
     console.log('done!');
  }
);

上面代码表示,动画结束时,在控制台输出“done!”。

1.4.3 stop方法,delay方法

stop方法表示立即停止执行当前的动画。

$("#stop").click(function() {
  $(".block").stop();
});

上面代码表示,点击按钮后,block元素的动画效果停止。

delay方法接受一个时间参数,表示暂停多少毫秒后继续执行。

$("#foo").slideUp(300).delay(800).fadeIn(400)

上面代码表示,slideUp动画之后,暂停800毫秒,然后继续执行fadeIn动画。

1.5 实用工具方法

jQuery对象(简写为$),这个对象本身是一个构造函数,可以用来生成jQuery对象的实例。有了实例以后,就可以调用许多针对实例的方法,它们定义jQuery.prototype对象上面(简写为$.fn)

除了实例对象的方法以外,jQuery对象本身还提供一些方法(即直接定义jQuery对象上面),不需要生成实例就能使用。由于这些方法类似“通用工具”的性质,所以我们把它们称为“工具方法”(utilities)

1.5.1 $.trim

$.trim方法用于移除字符串头部和尾部多余的空格。

$.trim('   Hello   ') // Hello

1.5.2 $.contains

$.contains方法返回一个布尔值,表示某个DOM元素(第二个参数)是否为另一个DOM元素(第一个参数)的下级元素。

$.contains(document.documentElement, document.body); 
// true

$.contains(document.body, document.documentElement); 
// false

1.5.3 $.each,$.map

 $.each方法用于遍历数组和对象,然后返回原始对象。它接受两个参数,分别是数据集合和回调函数。

$.each([ 52, 97 ], function( index, value ) {
  console.log( index + ": " + value );
});
// 0: 52 
// 1: 97 

var obj = {
  p1: "hello",
  p2: "world"
};
$.each( obj, function( key, value ) {
  console.log( key + ": " + value );
});
// p1: hello
// p2: world

需要注意的,jQuery对象实例也有一个each方法($.fn.each),两者的作用差不多。

$.map方法也是用来遍历数组和对象,但是会返回一个新对象。

var a = ["a", "b", "c", "d", "e"];
a = $.map(a, function (n, i){
  return (n.toUpperCase() + i);
});
// ["A0", "B1", "C2", "D3", "E4"]

1.5.4 $.inArray

$.inArray方法返回一个值在数组中的位置(从0开始)。如果该值不在数组中,则返回-1。

var a = [1,2,3,4];
$.inArray(4,a) // 3

1.5.5 $.extend

$.extend方法用于将多个对象合并进第一个对象。

var o1 = {p1:'a',p2:'b'};
var o2 = {p1:'c'};

$.extend(o1,o2);
o1.p1 // "c"

$.extend的另一种用法是生成一个新对象,用来继承原有对象。这时,它的第一个参数应该是一个空对象。

var o1 = {p1:'a',p2:'b'};
var o2 = {p1:'c'};

var o = $.extend({},o1,o2);
o
// Object {p1: "c", p2: "b"}

默认情况下,extend方法生成的对象是“浅拷贝”,也就是说,如果某个属性是对象或数组,那么只会生成指向这个对象或数组的指针,而不会复制值。如果想要“深拷贝”,可以在extend方法的第一个参数传入布尔值true。

var o1 = {p1:['a','b']};

var o2 = $.extend({},o1);
var o3 = $.extend(true,{},o1);

o1.p1[0]='c';

o2.p1 // ["c", "b"]
o3.p1 // ["a", "b"]

上面代码中,o2是浅拷贝,o3是深拷贝。结果,改变原始数组的属性,o2会跟着一起变,而o3不会。

jQuery.fn.extend 和 jQuery.extend区别

extend方法在 jQuery 中是一个很重要的方法,jQuey 内部用它来扩展静态方法或实例方法,而且我们开发 jQuery 插件开发的时候也会用到它。但是在内部,是存在 jQuery.fn.extend 和 jQuery.extend 两个 extend 方法的,而区分这两个 extend 方法是理解 jQuery 的很关键的一部分。先看结论:

  • jQuery.extend(object) 为扩展 jQuery 类本身,为类添加新的静态方法;
  • jQuery.fn.extend(object) 给 jQuery 对象添加实例方法,也就是通过这个 extend 添加的新方法,实例化的 jQuery 对象都能使用,因为它是挂载在 jQuery.fn 上的方法 

它们的官方解释是:

  • jQuery.extend(): 把两个或者更多的对象合并到第一个当中,
  • jQuery.fn.extend():把对象挂载到 jQuery 的 prototype 属性,来扩展一个新的 jQuery 实例方法。

也就是说,使用 jQuery.extend() 拓展静态方法,我们可以直接使用 $.xxx 进行调用(xxx是拓展的方法名),而使用 jQuery.fn.extend() 拓展的实例方法,需要使用 $().xxx

需要注意的是这一句 jQuery.extend = jQuery.fn.extend = function() {} ,也就是 jQuery.extend 的实现和 jQuery.fn.extend 的实现共用了同一个方法,但是为什么能够实现不同的功能了,这就要归功于 javasc ipt 强大(怪异?)的 this 了。

  • 在 jQuery.extend() 中,this 的指向是 jQuery 对象(或者说是 jQuery 类),所以这里扩展在 jQuery 上;
  • 在 jQuery.fn.extend() 中,this 的指向是 fn 对象,前面有提到 jQuery.fn = jQuery.prototype ,也就是这里增加的是原型方法,也就是对象方法

1.5.6 $.proxy

$.proxy方法类似于ECMAScript 5的bind方法,可以绑定函数的上下文(也就是this对象)和参数,返回一个新函数。

jQuery.proxy()的主要用处是为回调函数绑定上下文对象。

var o = {
    type: "object",
    test: function(event) {
        console.log(this.type);
    }
};

$("#button")
  .on("click", o.test) // 无输出
  .on("click", $.proxy(o.test, o)) // object

上面的代码中,第一个回调函数没有绑定上下文,所以结果为空,没有任何输出;第二个回调函数将上下文绑定为对象o,结果就为object。

这个例子的另一种等价的写法是:

$("#button").on( "click", $.proxy(o, test))

上面代码的$.proxy(o, test)的意思是,将o的方法test与o绑定。

这个例子表明,proxy方法的写法主要有两种。

jQuery.proxy(function, context)

// or

jQuery.proxy(context, name)

第一种写法是为函数(function)指定上下文对象(context)第二种写法是指定上下文对象(context)和它的某个方法名(name)

再看一个例子。正常情况下,下面代码中的this对象指向发生click事件的DOM对象。

$('#myElement').click(function() {
    $(this).addClass('aNewClass');
});

如果我们想让回调函数延迟运行,使用setTimeout方法,代码就会出错,因为setTimeout使得回调函数在全局环境运行,this将指向全局对象。

$('#myElement').click(function() {
    setTimeout(function() {
        $(this).addClass('aNewClass');
    }, 1000);
});

上面代码中的this,将指向全局对象window,导致出错。

这时,就可以用proxy方法,将this对象绑定到myElement对象。

$('#myElement').click(function() {
    setTimeout($.proxy(function() {
        $(this).addClass('aNewClass'); 
    }, this), 1000);
});

1.5.7 $.data,$.removeData

$.data方法可以用来在DOM节点上储存数据。

// 存入数据
$.data(document.body, "foo", 52 );

// 读取数据
$.data(document.body, "foo");

// 读取所有数据
$.data(document.body);

上面代码在网页元素body上储存了一个键值对,键名为“foo”,键值为52。

$.removeData方法用于移除$.data方法所储存的数据。

$.data(div, "test1", "VALUE-1");
$.removeData(div, "test1");

1.5.8 $.parseHTML,$.parseJSON,$.parseXML

$.parseHTML方法用于将字符串解析为DOM对象。

$.parseJSON方法用于将JSON字符串解析为JavaScript对象,作用与原生的JSON.parse()类似。但是,jQuery没有提供类似JSON.stringify()的方法,即不提供将JavaScript对象转为JSON对象的方法。

$.parseXML方法用于将字符串解析为XML对象。

var html = $.parseHTML("hello, <b>my name is</b> jQuery.");
var obj = $.parseJSON('{"name": "John"}');

var xml = "<rss version='2.0'><channel><title>RSS Title</title></channel></rss>";
var xmlDoc = $.parseXML(xml);

1.5.9 $.makeArray

$.makeArray方法将一个类似数组的对象,转化为真正的数组。

var a = $.makeArray(document.getElementsByTagName("div"));

1.5.10 $.merge

$.merge方法用于将一个数组(第二个参数)合并到另一个数组(第一个参数)之中。

var a1 = [0,1,2];
var a2 = [2,3,4];
$.merge(a1, a2);

a1
// [0, 1, 2, 2, 3, 4]

1.5.11 $.now

$.now方法返回当前时间距离1970年1月1日00:00:00 UTC对应的毫秒数,等同于(new Date).getTime()。

$.now()
// 1388212221489

1.5.12 判断数据类型的方法

jQuery提供一系列工具方法,用来判断数据类型,以弥补JavaScript原生的typeof运算符的不足。以下方法对参数进行判断,返回一个布尔值。

  • jQuery.isArray():是否为数组。
  • jQuery.isEmptyObject():是否为空对象(不含可枚举的属性)。
  • jQuery.isFunction():是否为函数。
  • jQuery.isNumeric():是否为数值(整数或浮点数)。
  • jQuery.isPlainObject():是否为使用“{}”或“new Object”生成的对象,而不是浏览器原生提供的对象。
  • jQuery.isWindow():是否为window对象。
  • jQuery.isXMLDoc():判断一个DOM节点是否处于XML文档之中。

下面是一些例子。

$.isEmptyObject({}) // true
$.isPlainObject(document.location) // false
$.isWindow(window) // true
$.isXMLDoc(document.body) // false

除了上面这些方法以外,还有一个$.type方法,可以返回一个变量的数据类型。它的实质是用Object.prototype.toString方法读取对象内部的[[Class]]属性。

$.type(/test/) // "regexp"

1.6 其他方法

jQuery还提供一些供特定元素使用的方法。

1.6.1 serialize()

serialize方法用于将表单元素的值,转为url使用的查询字符串。

$( "form" ).on( "submit", function( event ) {
  event.preventDefault();
  console.log( $( this ).serialize() );
});
// single=Single&multiple=Multiple&check=check2&radio=radio1

1.6.2 serializeArray()

serializeArray方法用于将表单元素的值转为数组。

$("form").submit(function (event){
  console.log($(this).serializeArray());
  event.preventDefault();
});
//    [
//        {name : 'field1', value : 123},
//        {name : 'field2', value : 'hello world'}
//    ]

1.6.3 链式操作

jQuery最方便的一点就是,它的大部分方法返回的都是jQuery对象,因此可以链式操作。也就是说,后一个方法可以紧跟着写在前一个方法后面。

$('li').click(function (){
    $(this).addClass('clicked');
})
.find('span')
.attr( 'title', 'Hover over me' );


1.6.4 $(document).ready()

$(document).ready方法接受一个函数作为参数,将该参数作为document对象的DOMContentLoaded事件的回调函数。也就是说,当页面解析完成(即下载完</html>标签)以后,在所有外部资源(图片、脚本等)完成加载之前,该函数就会立刻运行。

$( document ).ready(function() {
  console.log( 'ready!' );
});

上面代码表示,一旦页面完成解析,就会运行ready方法指定的函数,在控制台显示“ready!”。

该方法通常作为网页初始化手段使用,jQuery提供了一种简写法,就是直接把回调函数放在jQuery对象中

$(function() {
  console.log( 'ready!' );
});

上面代码与前一段代码是等价的。

1.6.5 $.noConflict方法

jQuery使用美元符号($)指代jQuery对象。某些情况下,其他函数库也会用到美元符号,为了避免冲突,$.noConflict方法允许将美元符号与jQuery脱钩。

<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>$.noConflict();</script>

上面代码就是$.noConflict方法的一般用法。在加载jQuery之后,立即调用该方法,会使得美元符号还给前面一个函数库。这意味着,其后再调用jQuery,只能写成jQuery.methond的形式,而不能用$.method了。

为了避免冲突,可以考虑从一开始就只使用jQuery代替美元符号。