十五、框架

jQuery 框架是一个广泛使用的 JavaScript 库,旨在简化 DOM 操作并消除浏览器不兼容性。

包括 jQuery

要包含 jQuery,您可以在 web 文档的<head>部分放置以下引用。这将从 Google 的托管库服务中加载最新版本的 jQuery,在撰写本文时是版本 1.11.3。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.jsT2】

如果您喜欢脚本文件的本地副本,可以从jquery.com获得。然而,从内容交付网络(CDN)链接到 jQuery,比如上面的链接,提供了性能优势。托管 jQuery 的 CDN 服务器分布在全球各地,减少了延迟,已经从同一来源获得缓存副本的访问者不必再次下载。

使用 jQuery

当包含 jQuery 脚本时,它会向全局名称空间添加一个名为jQuery的对象。该对象提供对 jQuery 框架的实用方法的访问。其中许多方法旨在简化常用的 JavaScript 功能,例如isArrayisPlainObjectisFunction方法,它们提供了检查传递的参数是否属于这些类型之一的简单方法。

jQuery.isArray( [1, 2] ); // true

jQuery.isPlainObject( {} ); // true

jQuery.isFunction( function() {} ); // true

jQuery对象通常通过它的美元符号($)别名来引用,因为它输入起来更短,简洁是 jQuery 的一个关键特性。因此,可以用更短的语法调用 jQuery 方法。这里使用了type方法,它以字符串的形式返回参数的类型。

$.type(null); // "null"

$.type( [1, 2] ); // "array"

在这种情况下,type方法比typeof操作符更具体。

typeof( null ); // "object"

typeof( [1, 2] ); // "object"

元素选择

对 DOM 元素的访问和操作需要首先选择目标元素,jQuery 极大地简化了这个过程。假设一个 web 文档包含下面我们想要选择的元素。

<p id="myid">My paragraph</p>

jQuery对象可以用作一个函数,它接受一个参数并返回一个 jQuery 集合。如果参数是 CSS 选择器,则对象返回一个集合,其中包含与该选择器匹配的任何 DOM 元素。这为选择段落提供了一种方便的方法。

var selection = $("#myid");

与更冗长的 DOM 方法相比,DOM 方法通过 id 选择元素。

var domNode = document.getElementById("myid");

这些选择方法之间的一个重要区别是 DOM 方法返回对 DOM 元素的引用,而 jQuery 方法返回一个 jQuery 集合。该集合充当底层 DOM 元素的包装器,为在这些元素上执行操作提供了更易于使用的方法。如果希望使用原生 DOM 方法,可以使用方括号符号或 get 方法将 jQuery 集合展开到原始 DOM 节点。

domNode = selection[0];

domNode = selection.get(0);

相反,通过将 DOM 元素传递给jQuery对象,可以将其包装到 jQuery 集合中。

var selection = $(domNode);

jQuery 集合就像一个包含零个或多个 DOM 元素的数组。如果没有元素与提供的选择器匹配,或者没有提供选择器,则返回的集合为空。

var empty = $();

可以使用length属性检索所选元素的数量。在这种情况下,集合的长度为零。

console.log(empty.length); // "0"

如果选择器匹配多个元素,则返回的集合将包含所有匹配的元素。考虑以下div元素。

<div class="myclass" id="div1">First</div>

<div class="myclass" id="div2">Second</div>

通过类名选择这些元素将返回包含两个元素的集合。

var divs = $(".myclass");

console.log(divs.length); // "2"

可以使用add方法将新的选择添加到收藏中。

var div1 = $("#div1");

divs = div1.add("#div2");

同样,not方法从集合中取出一个或多个匹配的元素。

var div2 = divs.not("#div1");

有趣的是,jQuery 方法调用是可链接的,因为它们都返回 jQuery 集合。下面一行将所有的div元素添加到一个空集合中,然后移除div2元素,只留下div1元素。

var div1 = $().add("div").not("#div2");

集合遍历

一旦选定,就可以通过集合对象的方法来操作集合。为了说明,将使用下面包含三个列表项的列表。

<ul id="mylist">

<li>Item 1</li>

<li>Item 2</li>

<li>Item 3</li>

</ul>

以下查询匹配这些列表项,并将它们作为集合返回。

var items = $("#mylist li");

这个items集合现在包含三个 jQuery 元素。为了从这个集合中提取单个元素,可以使用eq方法,将元素的索引作为参数。

var first = items.eq(0);

var second = items.eq(1);

提供负参数将检索从集合末尾开始计数的元素。

var third = items.eq(-1);

快捷方法可用于检索集合的第一个或最后一个元素。

first = items.first();

third = items.last();

或者,在选择元素时,这些方法名可以用作后缀。

first = $("#mylist li:first");

second = $("#mylist li:eq(1)");

third = $("#mylist li:last");

还有其他几个与索引相关的选择器或过滤器,它们允许非常精确的选择查询。例如,oddevenlt(小于)和gt(大于)过滤器。

var first_third = $("#mylist li:even");

second = $("#mylist li:odd");

first = $("#mylist li:lt(1)");

third = $("#mylist li:gt(1)");

DOM 遍历

可以相对于集合中的元素遍历 DOM 树。使用前面的列表示例,这里的第二个列表项被选为起点。

var second = $("#mylist li:eq(1)");

使用nextprev方法,可以从这个元素将 DOM 横向导航到兄弟元素。

var third = second.next();

var first = second.prev();

为了在层次结构中向上移动,提供了parent方法。在这种情况下,无序列表元素被选中。

var list = second.parent();

children方法可用于在树中向下移动。它在这里将所有三个列表项作为集合返回。

var items = list.children();

要选择一个元素的所有兄弟元素,可以使用siblings方法。请记住,原始元素不包含在同级元素中。

var first_third = second.siblings();

如果集合包含多个元素,大多数集合方法都会影响集合中的所有元素。例如,对包含第一个和第二个列表元素的集合调用 next 将返回包含第二个和最后一个列表元素的集合。

var first_second = $("#mylist li:lt(2)");

var second_third = first_second.next();

修改属性

提供了attr方法来访问和修改所选元素的属性。为了说明,考虑下面的 HTML。

<p id="myid" class="myclass">First paragraph</p>

<p class="myclass">Second paragraph</p>

当用属性名调用时,attr方法检索该属性的当前值。如果集合包含多个元素,就像在这种情况下,则只检索集合中第一个元素的属性值。

$(".myclass").attr("id"); // "myid"

若要添加或更改属性的值,该属性的名称及其新值将被传递给方法。因为这个集合包含两个元素,所以它们都将被赋予新的属性值。

$(".myclass").attr("title", "mytitle");

通过将一个对象传递给由属性-值对组成的方法,可以同时设置多个属性。

$(".myclass").attr({

lang: "en",

dir: "rtl"

});

可以使用removeAttr方法删除属性。如果应用于多个元素的选择,每个元素都将删除该属性。

$(".myclass").removeAttr("lang");

css方法允许通过元素的style属性检索或更改 CSS 样式。在下面的例子中,第一段是红色的。

$("#myid").css("color", "red");

向该方法传递单个参数将从style属性中检索该样式属性的值,如果该属性尚未设置,则为 undefined。

$("#myid").css("color"); // "rgb(255, 0, 0)"

要改变元素的样式,最好应用在外部样式表中定义这些样式的类,而不是修改style属性。addClassremoveClass方法通过允许在class属性中添加或删除类,提供了一种方便的方法。这两种方法都采用单个参数,该参数是一个字符串,指定要添加或删除的一个或多个类。

$("#myid").addClass("class1 class2");

$("#myid").removeClass("class2");

$("#myid").attr("class"); // "myclass class1"

hasClass方法确定任何匹配的元素是否被分配给指定的类。给定前面的 HTML,下面的代码返回 true。

$("#myid").hasClass("myclass"); // true

创建元素

除了操作现有的 DOM 节点,jQuery对象还可以用来创建新元素,方法是将 HTML 标记以字符串参数的形式传递给它。该字符串必须由一个顶级 HTML 元素组成,但该元素可以包含任意数量的子节点。

var myDiv = $("<div>My container</div>");

jQuery 提供了两种方法来修改元素的内容:texthtmlhtml方法将元素的内容更改为给定的字符串。

myDiv = myDiv.html("<b>Hello HTML</b>");

调用不带参数的方法将检索该元素的 HTML 内容。如果集合包含多个元素,则只返回第一个元素的标记。

// "<b>Hello HTML</b>"

console.log(myDiv.html());

相比之下,调用不带参数的text方法会检索去除了任何 HTML 标签的元素内容。

// "Hello HTML"

console.log(myDiv.text());

同样,当给定一个参数时,text方法将转义字符串中的任何 HTML,并将其作为纯文本内容插入元素中。

myDiv.text("<b>Hello text</b>");

// <b>Hello text</b>

console.log(myDiv.html());

请记住,新创建的元素不会自动包含在 DOM 中。它们只作为各自 jQuery 集合的一部分存在。

移动元素

可以使用一种 jQuery 插入方法在 DOM 树中移动或插入元素。举例来说,下面两个元素。

<div id="content">My content</div>

<div id="container"></div>

append方法将一个元素作为其参数,并将其添加到 jQuery 集合的每个元素的末尾。在本例中,内容元素被选中并作为最后一个子元素移动到容器元素中。

$("#container").append($("#content"));

要将元素作为第一个子元素插入,请使用prepend方法。

$("#container").prepend($("<div>First child</div>"));

after方法将元素作为兄弟元素直接放在集合之前。

$("#container").after($("<div>After</div>"));

before方法以同样的方式工作,但是将它的参数作为兄弟添加到集合之前。

$("#container").before($("<div>Before</div>"));

在执行这些代码行时,HTML 被转换成如下所示的标记。

<div>Before</div>

<div id="container">

<div>First child</div>

<div id="content">My content</div>

</div>

<div>After</div>

就绪方法

在大多数情况下,运行脚本的适当时间是 web 文档已经加载并且完整的 DOM 层次结构可用的时候。为此,jQuery 提供了ready方法,该方法将在该事件发生时执行的函数作为其参数。

function myHandler(e) { console.log("DOM ready"); }

$(document).ready(myHandler);

文档选择器可以省略,因为ready方法只能在文档的上下文中调用。

$(myHandler); // alternative syntax

请记住,jQuery ready 事件不同于 DOM load 事件,DOM load 事件只有在所有外部资源(如图像)完全加载后才会触发。

事件处理

jQuery 的on方法简化了事件处理。此方法将事件的事件处理程序附加到选定的元素。举个例子,考虑下面的列表。

<ul id="mylist">

<li>Item 1</li>

<li>Item 2</li>

</ul>

这些列表项的单击事件可以用下面的代码在一个步骤中注册。

$("#mylist li").on("click", myListHandler);

下面的事件处理程序使用 this 选择器来检索事件发生的元素的引用,因此单击第一个列表项将在控制台中显示“Item 1”。

function myListHandler(e) {

console.log( $(this).text() );

}

有些事件有速记法,比如clickchangekeypressblurfocus。这为前面注册事件处理程序的示例提供了一种替代语法。

$("#mylist li").click(myListHandler);

通过 jQuery 添加事件处理程序提供了与注册事件的 W3C 方法相同的好处,允许为同一个元素和事件附加多个事件处理程序。与 W3C 方法不同,它还具有与 IE6-8 跨浏览器兼容的额外优势,在成功注册事件和传递正确的事件对象方面都是如此。

AJAX

jQuery 极大地简化了使用 Ajax 的步骤,整个初始化、发送和接收服务器请求的过程只需要一个方法。在第 14 章中使用 jQuery 显示来自服务器的文本文件内容的例子。

$.ajax({

url: "mytext.txt",

type: "GET",

async: "true",

success: function(data) {

console.log(data);

}

});

如果 Ajax 请求成功,这里指定的success方法将被调用。只有url属性必须为ajax方法设置。其他属性是可选的,可以不指定使用它们的默认值。在这种情况下,typeasync属性都使用默认值,因此不需要指定它们。

$.ajax({

url: "mytext.txt",

success: function(data) {

console.log(data);

}

});

通过使用get方法,有另一种更短的方法来完成同样的任务。该方法使用 HTTP GET 请求来请求服务器数据。如果请求成功,将执行两个参数 URL 和回调函数。

$.get("mytext.txt", function(data, status) {

console.log(data);

});

类似于get方法,还有一个post方法使用 HTTP POST 请求发送服务器请求。该方法包括一个额外的参数,该参数包含要发送到服务器的数据。

$.post("myscript.php", {

name: "Alex",

age: "25"

}, function(data, status) {

console.log(data);

});

发送 Ajax 请求的 jQuery 方法自动增加了对 IE<7 的向后兼容性。具体来说,ajax方法考虑到 IE5-6 没有XMLHttpRequest对象,而是使用 ActiveX 对象。