当前位置: 首页 > news >正文

提示网站建设中四会城乡建设局网站

提示网站建设中,四会城乡建设局网站,上海网站建设品,专业全网优化原文#xff1a;Beginning jQuery 协议#xff1a;CC BY-NC-SA 4.0 一、你需要知道的 JavaScript jQuery 是一个建立在 JavaScript 之上的框架#xff0c;它本身并不是一种语言。几乎没有任何 JavaScript 知识也可以编写 jQuery#xff0c;但是我们不建议这样做。如果您希… 原文Beginning jQuery 协议CC BY-NC-SA 4.0 一、你需要知道的 JavaScript jQuery 是一个建立在 JavaScript 之上的框架它本身并不是一种语言。几乎没有任何 JavaScript 知识也可以编写 jQuery但是我们不建议这样做。如果您希望能够自信地为您的站点编写 jQuery 插件或者修改其他人编写的插件您需要熟悉基本的 JavaScript。这就是为什么这本书从你需要知道的 JavaScript 开始。本章涵盖 网页上的 JavaScript 脚本JavaScript 中的变量和对象JavaScript 函数条件式在数组和对象上循环调试 JavaScript 如果你熟悉 JavaScript你可能想跳过这一章。这很好但请考虑先略读一下以确保你对所涉及的一切都感到满意。抵制跳到 jQuery 部分的诱惑——因为你会纠结于它。相信我们在接下来的几章时间里这些准备工作看起来都是值得的。我们在网上帮助过的许多开发人员都迫不及待地一头扎进了 jQuery但很快就因为缺乏对 jQuery 语言的理解而停滞不前。当你写 jQuery 时你写的是 JavaScript但是使用的是 jQuery 库。在继续学习之前确保你对本章的内容感到满意是非常重要的。我们建议您在阅读本章时尝试一下这些代码。不要自欺欺人地认为你理解了它因为你已经读过了没有什么可以代替你自己输入代码。 要运行代码我们建议使用 JS 控制台( https://jsconsole.com )这是 Remy Sharp 的一个工具允许您执行 JavaScript 并查看结果。一些备选方案是 JS Bin ( http://jsbin.com )或 JSFiddle ( https://jsfiddle.net )。您可以在浏览器中输入代码并查看结果。这对短代码行非常有用。图 1-1 显示了 JS 控制台的示例。 img/A310335_2_En_1_Fig1_HTML.jpg) 图 1-1。 The Console tab displays the results of the JavaScript tab using JS bin 对于较大的代码最好建立一个index.html页面并在其中包含您的 JavaScript 文件。这将是你真正把一个网站放在一起的方式。下一节将解释如何做到这一点。在本章中有几个例子使用了alert()函数来演示某个变量的值。这纯粹是用来演示概念的。在现实生活中当您需要检查变量时您不会使用警报—您会使用浏览器的 JavaScript 控制台。在本章的基本示例中使用警报的原因是它更容易上手。此时不需要加载开发人员工具这需要时间来适应。一旦你在本章的后面进入更复杂的代码你将花时间探索开发者工具。 在网页上使用 JavaScript 在一个典型的 HTML 文件中通常有两种方式向页面添加 JavaScript。要添加一些 JavaScript您可以在一个script标签内内联添加代码如下所示: script typetext/javascript//write code here /script 或者您可以创建一个带有.js文件扩展名的外部 JavaScript 文件然后通过script标签加载它: script typetext/javascript srcpath/to/your/file.js/script Note 你必须关闭script标签。 第一个位置在head元素中第二个位置就在结束的/body标签之前。过去脚本总是被加载到head元素中但是随着性能和页面加载速度比以往任何时候都更加重要通常建议将脚本放在页面的底部。这也是我们支持的方法。 浏览器从上到下呈现页面当它遇到您的脚本时它暂停呈现页面以加载到您的 JS:。因此页面加载较慢(或者更重要的是用户会有这种感觉)因为您加载的 JavaScript 文件阻止了呈现。因此将脚本放在结束的/body标签之前意味着当加载脚本的时候页面的其余部分已经被加载了。 在开始研究语言本身之前还有一点需要注意。使用 HTML5 doctype (!DOCTYPE html)您实际上不需要在脚本标签上定义 type 属性。简单地使用以下代码就足够了: script srcpath/to/your/file.js/script 这在旧浏览器中不会引起问题 HTML5 doctype 也不会——我们强烈推荐使用它。 语法约定 JavaScript 的语法非常基本和清晰但是在这个过程中您会发现一些微妙之处。通常有不止一种方法来做事情但是社区有一些随着时间的推移而变得根深蒂固的惯例。 分号 我们想直接提到的一个约定是分号的使用。通常在 JavaScript 中在行尾添加分号是可选的你会看到教程没有这样做。然而惯例是总是在一行的末尾使用分号这就是我们在本书中要遵循的。显然在某些情况下你不能使用分号你会在本书中看到但是在任何分号可选的情况下我们都会使用分号。我们建议您也这样做。 空格 另一个要考虑的是留白。在 JavaScript 中这是无关紧要的所以你可以按照你喜欢的方式用空白来布局代码。无论何时你在一组大括号中你都应该缩进一个制表符但是除此之外你会发现自己在适应自己的标准。 评论 在继续之前在这个阶段值得讨论的意见。JavaScript 允许您在代码中插入注释。这些内容将被忽略不会被视为代码因此您可以在注释中添加任何内容。插入注释对于记录代码很有用。注释有两种语法一种用于单行注释另一种用于多行注释: //this is a single-line comment, denoted by two forward slashes /* this is a multiline comment, started with a slash and an asterisk and ended with an asterisk and a slash */ 使用注释来提醒自己一段代码及其作用或者为未来的你提供参考。在很长一段时间没有从事代码工作之后注释确实可以帮助你记住你为什么要写你所写的东西。 变量 通常在编码的时候你想要保存一些东西的状态。也许你想记住你的背景的当前颜色是红色或者你刚刚计算的总数是 33。和大多数语言一样JavaScript 也有变量:存储信息的地方。要创建一个变量只需用关键字var声明它给它命名然后将其设置为等于某个值。您也可以在不显式设置变量值的情况下声明变量。如果这样做变量将被设置为undefined这是 JavaScript 中的一个特殊值仅仅意味着这个变量没有被设置为任何值。以下示例声明了三个变量: var twoPlusThree 5; var twoPlusTwo 2 2; var notYetDefined; 第一个变量twoPlusThree被设置为值5。第二个twoPlusTwo被设置为22的结果。在这里你会遇到 JavaScript 的众多操作符之一。这些运算符对值执行运算。大部分都很明显。除了(加法)还有–(减法)、/(除法)、*(乘法)还有更多。你会在整本书中遇到更多所以现在不要太担心他们。第三个变量notYetDefined没有值设置为undefined因为我们声明了一个变量(也就是我们创建了一个新变量)但是没有设置值。 创建变量 变量可以包含字母、数字和下划线。它们不能以数字开头。因此变量名0abc无效而abc0有效。通常大多数开发人员不在变量名中使用数字而是坚持使用字母大小写或下划线符号。 Note 注意我们对变量的命名约定。我们使用的是所谓的 camelCase这意味着变量名中的第一个单词应该以小写字母开头但名称中的其他每个单词都应该以大写字母开头。我们将在整本书中使用这个约定。还有其他流行的命名约定最著名的是 _ 下划线 _ 方法。这使所有单词保持小写并用下划线分隔。这在其他语言中更流行。大多数 JavaScript 社区都使用 camelCase。 当然一旦你设置了一个变量的值并不意味着你不能改变这个值。所有变量的值都可以更改。这与声明变量的方式非常相似唯一的区别是开头缺少了关键字var。只有在声明变量的时候才需要。这个例子将totalCost设置为 5然后再次将其更新为 5 3(显然您可以将它写成 8): var totalCost 5; totalCost 5 3; 类型 在继续之前您会注意到到目前为止所有变量都被设置为非十进制数。在 JavaScript(和所有编程语言)中有类型的概念。变量可以是几种类型中的任何一种。最常见的是数字类型和字符串类型。还有布尔型只能设置为true或者false。使用 JavaScript 时通常不必太担心类型。即使变量是用整数值(例如 5)声明的也可以将其更新为字符串值如下所示: var testVariable 5; testVariable Jack; 这就把testVariable的类型从整数变成了字符串JavaScript 一点也不抱怨。除了字符串、数字和布尔值您需要关注的另外两种类型(目前)是数组和对象。两者都将很快得到更详细的介绍但是现在只需要知道数组本质上是一个值的列表。这些值可以是任何类型并且不是数组中的所有值都必须是同一类型。您可以通过在方括号之间列出值来创建数组如下所示: var squares [1, 4, 9, 16, 25];var mixed [1, Jack, 5, true, 6.5, Franklin]; 现在这就是你需要知道的关于数组的全部内容。 另一种类型object用一个例子更容易解释。假设您的应用中有一个汽车的概念。这辆车有一定数量的轮子和座位有一定的颜色有最大速度。你可以用四个独立的变量来模拟这辆车: var carWheelCount 4; var carColor red; var carSeatCount 5; var carMaximumSpeed 99; 如果只有一个包含所有这些信息的变量——car——那就更容易了。这就是一个物体的作用。这是一种在一个变量中存储大量信息(通常是相关的)的方法。如果您使用对象汽车的先前代码可能如下所示: var car {wheelCount: 4,color: red,seatCount: 5,carMaximumSpeed: 99 }; 创建对象的语法与您到目前为止看到的任何语法都有一点不同所以让我们浏览一下。像平常一样创建变量但是要创建一个对象就要用花括号把它括起来。对象是一组键值对也称为属性。通过以格式key: value列出它们来创建它们在除最后一个属性之外的所有属性的末尾加上一个逗号。这是一种更好的以编程方式对代码建模的方式。 要访问对象中的属性有两种选择: car.wheelCount; car[wheelCount]; 使用两种方法访问属性的原因很容易解释。大多数情况下您将使用第一个版本点符号。唯一需要使用第二个版本的时候是如果你需要访问一个对象中的一个键而这个键的名字存储在一个变量中。在演示中可以更清楚地看到这一点。假设您想要访问的键wheelCount由于您的应用中的一些在先代码而存储在一个变量中。如果你想得到wheelCount的值你必须使用第二种符号如下所示: var keyToGet wheelCount; car[keyToGet]; //this will give us 4 这种情况不经常发生但是有时候需要用到。在本书的后面你会看到这样的例子。现在让我们继续。 功能 一旦你写了一些你可能想在别处再次使用的代码你有两个选择。当你需要使用它的时候你可以简单的复制代码——但是这不是一个好的方法。如果你需要改变它你必须在两个或更多的地方改变它。最好创建一个函数。 创建函数 这使您可以在多个地方重用代码如果您需要进行更改您只需在一个地方进行更改。创建一个函数非常简单。使用function关键字表示您正在创建一个新函数。然后命名它并将函数代码放在花括号内。 function alertTwo() {alert(2); } 这个功能只是在你的屏幕上显示一个显示“2”的警告。注意函数名后面的括号是空的。这意味着你声明的函数没有任何参数。您可以声明另一个函数该函数接受一个参数并发出警报如下所示: function alertSomething(something) {alert(something); } 这个函数通过一个参数传递这个参数在函数中是一个变量您可以将其称为something。您所做的只是提醒该变量的值如下所示: alertSomething(Jack); alertSomething(2); 如果在浏览器中运行这段代码会弹出两个警告框第一个显示文本“Jack”。一旦你点击警告框来消除它另一个包含数字“2”的框将会弹出。 函数也可以接受多个参数例如: function alertThings(thing1, thing2) {alert(thing1);alert(thing2); }alertThings(Jack, Franklin); 和前面的例子一样这也给出了两个警告。第一个包含“杰克”第二个包含“富兰克林”。 jQuery 开发中经常做的事情是将一个对象传递给一个函数而不是多个变量。调用一个函数并传入多个参数会让人感到困惑例如: someFunction(Jack, Franklin, 1, 2, 3, 4, a, x); 所以许多插件 jQuery 广泛使用的东西——将对象传递给函数。例如如果您要声明一个带有三到四个或更多参数的函数您可能会让该函数接受一个对象如下所示: function aPerson(person) {alert(person.firstName);alert(person.lastName);alert(person.age); }var jack {firstName: Jack,lastName: Franklin,age: 20 }aPerson(jack); 如果运行该代码您将看到三个警告每个警告都警告存储在jack变量中的对象的属性。这是在大量使用 jQuery 时使用的一种模式所以一定要理解这里发生了什么。为了避免向函数传递大量参数——这使得很难记住哪个参数是哪个参数以及它们进入的顺序——开发人员通常编写他们的函数来接受一个对象作为唯一的参数。这意味着每个参数都可以被命名——顺序并不重要——作为开发人员查看代码并了解发生了什么要容易得多。 与其现在讨论函数及其所有细节不如在后面的章节中讨论它们。然而在继续之前您需要理解函数返回值的概念。 返回值的函数 函数通常用作执行某些计算的方法例如将英寸转换为厘米。这是一个你期望传入一个值的函数它计算并“返回”一个值。以下示例显示了如何实现这一点: function inchesToCM(inches) {return inches * 2.54; }var sixFeetInInches 72; var sixFeetInCM inchesToCM(sixFeetInInches); 这就剩下sixFeetInCM为 182.88也就是 72 乘以 2.54。给sixFeetInCM变量赋予那个值的原因是因为inchesToCM()函数返回它的自变量——英寸——乘以 2.54。通过返回参数sixFeetInCM变量被设置为inches * 2.54给你的值。 函数绝对可以返回任何值。通常您可能希望返回一个布尔值true或false如下所示: function isItSunnyInBritain() {return false; }var isSunny isItSunnyInBritain(); 这个函数将返回false这是应该的。面对现实吧英国从来都不是晴天从函数返回值是你会经常用到的。 条件式 您经常想做的事情是有条件地运行代码。也就是说只有在其他事情为真或为假的情况下才做某事。例如如果age变量小于 12则警告“孩子”。JavaScript 通过if语句拥有这种能力: var age 10; if(age 12) {alert(Child); } 但是如果年龄大于 12 岁你想做别的事情呢除了if语句您还可以在它的末尾附加一个else如下所示: var age 15; if(age 12) {alert(Child); } else {alert(Not a child); } 这里您遇到了另一个操作符—小于符号。还有它的反义词大于还有“小于等于”和“大于等于”和。如果你想检查多个条件你也可以使用else if就像这样: if(age 12) {alert(Child); } else if (age 20) {alert(Teenager); } else {alert(Adult); } 当然如果需要您可以使用多个else if语句但是通常您不需要多于一个或者两个。任何可以评估为true或false的东西都可以作为if语句的条件。一个更简单的方法是想象把一些陈述放在这些括号里在你的头脑中计算这个陈述是对还是错。如果你能做到这一点你的条件可以用在一个if语句中。 var name Jack; var age 20;if(age 18 name Jack) {alert(Hello Jack, you’re older than 18!); } 这里有两件新的事情要讨论。首先您用 and 运算符将两个条件组合成一个.这意味着只有当条件的左右两边都计算为true时条件才会计算为true。 其次您已经看到了如何检查等式。在 JavaScript 中这是一个复杂的领域。您可以同时使用和来检查相等性两者都有细微但重要的区别。现在当我们告诉你总是使用时请相信我们。 除了还有||它是“或”操作符。让我们来看看实际情况: var age 19; var name bob; if(age 18 || name Jack) {alert(your name is Jack or you’re older than 18); } 即使只有一个条件语句为真警报仍会显示在这里。年龄确实大于 18这使得这个人的名字不是 Jack 无关紧要因为只要满足其中一个条件or 运算符就会返回true。 确保你理解了||和.之间的区别如果两个条件中的任何一个计算为true那么第一个计算为true而如果两个条件都评估为true则评估为true。 也可以否定条件句也就是说如果相反的情况成立它们就通过了如下所示: var age 20; if(!age 18) {alert(Hello adult); } 求反运算符!反转条件运算的结果。在这个例子中age 18是false但是前缀为条件反转false到true的!。 一般来说你应该尽量避免像前面那样的否定把它写成age 18而不是!age 18因为这样代码更容易阅读。扫描代码和评估其功能越快越好。 使用控制台调试 前面我们简要地提到了浏览器中可用的开发人员控制台。我们说过一旦我们遇到更复杂的例子我们将从使用alert()切换到使用console.log()。在进行这种转换之前您需要查看一下您可以使用的调试。 现代浏览器附带了一个 JavaScript 控制台这是 JavaScript 开发人员宝库中的一个无价工具。下表描述了如何在所有现代浏览器中访问控制台: IE10:按 F12 并单击控制台选项卡。chrome:MAC OS 上的 AltCmdJ。Windows 上的 CtrlShiftJ。safari:MAC OS 上的 AltCmdI。Windows 上的 CtrlAltI。火狐:macOS 上的 AltCmdK。Windows 上的 CtrlShiftK。opera:MAC OS 上的 AltCmdI。Windows 上的 CtrlShiftI。 我使用谷歌 Chrome 作为我的首选浏览器本书中的所有截图都来自 Chrome 的控制台(除非另有说明)但所有浏览器都有非常相似的功能集它们看起来都一样所以选择一个最适合你的。请看图 1-2 中的例子。 img/A310335_2_En_1_Fig2_HTML.jpg) 图 1-2。 After declaring a variable, viewing its value in Google Chrome’s JS console 控制台非常适合尝试代码片段但它更适合调试。最流行的方法是console.log()它会将数据记录到控制台供您查看。从这一章开始示例使用这种方法而不是alert()。当处理复杂的数据结构时console.log()提供了一种更好的查看变量值的方式。 要查看示例请创建以下 HTML 文件(将其命名为 sensible ),然后使用开发人员工具在浏览器中打开它: !DOCTYPE html htmlheadtitleHey/titlescript typetext/javascript charsetutf-8console.log(Jack);/script/headbody/body /html 如果您按照前面的说明打开开发人员控制台您应该会看到类似图 1-3 的内容。 img/A310335_2_En_1_Fig3_HTML.jpg) 图 1-3。 The string “Jack” being logged to the console 你可以把任何事情记录到控制台它会知道如何处理。当您深入研究数组时您将会看到这一点。 数组 在继续学习 jQuery 之前了解数组是很重要的。如前所述数组只是一个值的列表。下面是一个数组的示例: var classMates [Jack, Jamie, Rich, Will]; 这差不多就是前面所介绍的内容所以现在是时候深入研究了。 您可以通过在变量后的方括号中添加一个数字来访问数组中的单个元素如下所示: classMates[1]; //Jamie 注意这里位置 1 的元素不是“Jack”而是“Jamie”。这是因为数组是零索引的。也就是说数组中的第一个元素实际上位于位置 0而不是位置 1。如果你不是程序员这可能需要一些时间来适应但是一旦你掌握了它它就会成为你的第二天性。因此要从数组中获取名称“Jack”您需要使用classMates[0]。您可以使用classMates.length找出数组的长度在本例中返回 4。作为一个快速的测试当你不知道数组的长度时你认为如何得到数组的最后一个元素呢 你应该这样做: classMates[classMates.length - 1]; // Will 看看你是否能在不先阅读解释的情况下弄清楚这是如何工作的。classMates.length给出数组长度即 4。因此要获取数组中的最后一项需要获取最后一个索引处的 person即长度减一直到第一个元素位于位置 0 而不是位置 1。 记住JavaScript 数组中可以包含任何东西包括对象和其他数组。这就是你所谓的二维数组数组中的每个元素本身就是一个数组: var twoDArray [[Jack, Jon, Fred],[Sue, Heather, Amy] ]; 要访问数组的数组中的元素使用方括号符号就像您之前使用的那样来获取classMates数组中的第二个元素classMates[1]: twoDArray[0][0]; //Jack twoDArray[1][0]; //Sue twoDArray[1][2]; //Amy 第一组方括号抓取了twoDArray的元素所以twoDArray[0]返回包含Jack, Jon,和Fred的数组。twoDArray[1]是包含Sue, Heather,和Amy的数组。 这并不是你必须经常做的事情但是在这个 JavaScript 介绍中向你展示是值得的因为它确实让你理解了数组的基础。 要向数组中添加元素使用push()方法: classMates.push(Catherine); 注意push()总是会在数组的末尾添加一个元素。 不幸的是没有这样的方法可以轻松地删除数组中的项目。您可以使用delete操作符乍一看它可以完成您需要的一切: delete classMates[1] 虽然这看起来可行但实际上并不可行。如果您对初始数组“Jack”、“Jamie”、“Rich”、“Will”执行该命令将会发生以下情况: delete classMates[1]; console.log(classMates); //[Jack, undefined, Rich, Will] 这是delete的关键之处:它不从数组中移除元素。它只是用undefined替换该索引处的值。因此要真正从数组中完全删除一个元素还需要做更多的工作。当这个问题实际发生时您将在本书的后面部分重新讨论这个问题。 环 现在您已经了解了使用数组的基本知识可以开始学习循环了。很自然的一旦你有了一个条目列表你经常想要依次检查每一个条目并对其执行一些计算或功能。您将在这里遇到的两个循环是while循环和for循环。 while循环非常简单实际上采用了您已经看到的形式即if语句。基本的while循环如下所示: while(condition) {//code } 当条件评估为true时大括号内的代码将继续执行。这有许多用例但最常见的是用于遍历一个列表就像这样: var count 0; while(count classMates.length) {alert(classMates[count]);count; } 如果您要运行该代码您将得到五个警报—“Jack”、“Jamie”等等分别对应于classMates数组中的五个项目(在前面的示例中您使用了push()方法来添加第五个项目“Catherine”)。一行一行地看它是这样工作的: 首先将一个新的count变量设置为 0。代码执行的条件是count变量必须小于classMates.length的长度。如果是你要做两件事: 首先警告classMates[count]处的值它将是classMates[0]然后是classMates[1]直到classMates[3]——最后一次count变量小于classMates的长度。第二运行count这是一个你没见过的新操作符。这只是count count 1的一个快捷方式所以它将count变量加 1。 你会发现自己经常使用while循环。当然它不一定要和数组一起使用——你可以在没有数组的情况下使用它但是它会导致一个无限循环所以我们不建议运行它。这里有一个例子: while(1 5) {alert(hello); } 在这里条件 1 5 将始终为真因此循环内的代码将被反复执行。大多数现代浏览器会检测到这一点并防止代码使浏览器崩溃但即使如此我们也不建议运行它。 除了while循环还有一个for循环。其语法略有不同: for(before loop; condition; iteration) {//code } 在一个for循环的参数中您定义了三件事: 循环开始前要运行的代码大括号内的代码可以执行所必须满足的条件每次迭代结束时运行的代码 最好用一个例子来说明这一点。下面将显示数字 0 到 9: for(var i 0; i 10; i) {alert(i); } 如果您想使用一个for循环而不是一个while来循环通过classMates数组可以这样做: for(var i 0; i classMates.length; i) {alert(classMates[i]); } 将此与while循环进行比较: var count 0; while(count classMates.length) {alert(classMates[count]);count; } 唯一的区别是首字母var count 0;被移到了for的括号内而count被移到了括号的末尾。开发人员通常会使用count作为变量来循环一些代码其他时候你会看到在“迭代器”中使用了i当然您可以使用任何您喜欢的变量名但这两个往往是最受欢迎的。我们将在本书的大部分内容中使用i但是如果你喜欢更冗长的count或者任何类似的东西请随意使用。 使用while循环或for循环可以在循环时编辑数组的值如下所示: var i 0; while(i classMates.length) {classMates [i] Class Mate i;i; } 这会将您的classMates数组更新为 [Class Mate 0, Class Mate 1, Class Mate 2, Class Mate 3] 在本章结束之前还有一件关于for循环的事情你需要知道。当处理一个对象时你可以结合使用for循环和in操作符来循环属性: var classMates {Jamie : 20,Will: 21,Rich: 22,Jack: 23 }for(classMate in classMates) {console.log(classMate is classMates[classMate] years old); } 这将为您提供以下输出: Jamie is 20 years oldWill is 21 years oldRich is 22 years oldJack is 23 years old 这里的关键是第一行for(classMate in classMates) {}。这将遍历classMates对象并遍历对象中的每个属性。然后你可以通过classMates[classMate]得到那个属性的值。 More console.log() 您在查看数组时使用了console.log(),但是到目前为止您只在最基本的形式中使用了它通过向它传递一个参数您希望它记录到控制台。比那强大多了。您可以传入多个参数它会在同一行记录所有参数。例如: var classMates [Jack, Jamie, Rich, Will]; var twoPlusTwo 4; console.log(classMates); console.log(twoPlusTwo, twoPlusTwo); 您将看到如图 1-4 所示的输出。 img/A310335_2_En_1_Fig4_HTML.jpg) 图 1-4。 The console logging out your array and variable 您可以看到注销classMates数组可以完全清楚它包含的内容这正是console.log()存在的目的。如果希望在一行中输出多种内容可以通过向函数传递多个参数来轻松实现。第二个例子注销字符串twoPlusTwo然后注销变量twoPlusTwo。我们经常在记录大量值时这样做所以在控制台中哪一行记录了什么就更清楚了。我们将在本书中大量使用console.log()。 摘要 本章涵盖了很多 JavaScript 基础知识包括变量、if语句、循环、数组、对象等等现在您已经有了坚实的基础。当您进入 jQuery 时我们会定期停下来以确保您对所做工作背后的 JavaScript 感到满意。系好安全带因为在下一章中是时候继续前进认识 jQuery 了。 二、jQuery 的基础知识 jQuery 是一个强大而复杂的库于 2006 年 8 月首次发布尽管最初的想法出现得更早。在开始之前我们有时间上一堂简短的历史课介绍图书馆是如何产生的。 第一次在网上发布任何暗示潜在图书馆正在形成的消息是在 2005 年 8 月 22 日。jQuery 的创始人约翰·瑞西格(John Resig)发布了一篇名为“JavaScript 中的选择器”( https://johnresig.com/blog/selectors-in-javascript/ )的博文展示了瑞西格的想法即我们可以使用 CSS 选择器与 JavaScript 中的元素进行交互。这展示了一个新的想法最终形成了我们今天所知道和喜爱的图书馆的雏形。jQuery 于 2006 年 1 月在纽约的 Bar Camp 正式发布并迅速风靡互联网占据了许多热门网站的首页。jQuery 不断发展并在 2006 年 8 月达到稳定的 v1。从那以后它继续增长。它对 web 开发的影响不可低估对 JavaScript 的社区观点的影响更为重要。 在本章中您将执行以下操作: 看看浏览器如何通过文档对象模型(DOM)表示网页。看看 web 页面上下文中的 DOM 节点和术语父节点、子节点和兄弟节点。下载 jQuery 源代码并将其包含在网页中。编写一些利用 jQuery 的代码。详细探究代码是如何工作的并了解 jQuery 的一些特性。探索 jQuery API 文档以及如何使用它来回答您可能遇到的任何问题。 jQuery 让“普通”开发人员更容易理解 JavaScript。例如在通过 ID 选择元素时您更喜欢以下两种语法中的哪一种 document.getElementById(example); 或者 $(#example); 突然如果您知道如何用 CSS 选择元素您可以通过使用 jQuery 将这些知识转移到 JavaScript。jQuery 提供了一种与文档对象模型交互的可靠的跨浏览器方法。在我们继续深入之前是时候讨论 DOM 了。 文档对象模型(DOM) 当你浏览一个网站时你会看到许多元素组合在一起形成你面前的东西。为了能够通过代码访问这些元素来删除、添加和操作它们您需要某种形式的接口——页面上元素的表示它是结构化的并遵循一组关于如何对它们建模的规则。这就是大教堂。DOM 还允许您捕获浏览器事件——比如用户点击链接、提交表单或向下滚动页面。在第三章中你将看到如何使用 jQuery 来遍历 DOM。 在网络和浏览器的早期JavaScript 实现的标准并不十分清晰。这导致浏览器以不同的方式实现功能这给开发人员带来了问题。这导致任何 JavaScript 都必须为具有不同实现的不同浏览器编写多次主要是 Netscape 和 Internet Explorer (IE)。 幸运的是随着事情的进展浏览器采用了相同的标准事情也解决了。然而浏览器支持 DOM 的水平在今天仍然会引起问题。特别是我们不能摆脱旧版本的 Internet Explorer它不支持 DOM 到更现代的浏览器的水平。这是 jQuery 如此有价值的一个原因:它提供的一切在旧版本的 IE 中都能很好地工作就像在最新版本的 Google Chrome 或 Mozilla Firefox 中一样。需要注意的是IE 的最新版本是 11微软 Edge 现在是 Windows 10 的默认浏览器。 在继续使用 jQuery 之前(您很快就会明白了)有必要花点时间介绍一下 DOM 是如何工作的。当一个页面被加载时浏览器生成一个页面内容的表示对于每个元素它生成一个或多个表示它的节点。节点有多种类型如果这是一本纯粹关于 DOM 与 JavaScript 交互的书我们将会更详细地讨论 DOM。 正如我们在第一章中提到的我们认为给刚接触 jQuery 的人一个坚实的 jQuery 基础介绍是非常重要的。我们已经非常详细地介绍了 JavaScript我们觉得看一下 DOM 很重要。当浏览器将当前页面表示为 DOM 时每个元素都是一个节点。假设您有一个包含一些文本的段落例如: pHello World/p 那不是一个节点而是两个节点。有一个包含“Hello World”的文本节点和一个段落的元素节点。 Note 文本节点将是元素节点的子节点因为它驻留在元素节点中。在一个典型的页面中有许多嵌套的节点。 包含两个段落且两个段落中都有文本的,div的结构如下: div element node -- paragraph element node ---- text node -- paragraph element node ---- text node 这个实例中的两个段落是兄弟因为它们有相同的父节点。段落是div的子节点但是文本节点不是子节点因为它们不是div元素的直接后代。它们是段落节点的子节点。您需要了解三种主要的节点类型:元素、文本和属性节点。假设你给了段落一个类比如: p classintroHello World/p 现在有三个节点在起作用: 代表段落的元素节点包含文本“Hello World”的文本节点表示该元素的属性节点有classintro 有点令人困惑的是属性节点不被认为是元素节点的子节点。 在这些元素之间它们构成了绝大多数网页的绝大部分。在(最后)开始学习 jQuery 之前请确保您理解了以下术语因为它们在本书中会不断出现: 子节点:是另一个节点的直接后代的节点通常是元素节点父节点:具有直接后代的节点(例如子节点)兄弟节点:共享同一父节点的两个节点 最后再重复一次下面是一个可视化的表示: div parent-- p child of div, sibling of p---- hello world - child of p-- p child of div, sibling of p---- strong child of p------ hello child of strong 当我们在本书后面讨论用 jQuery 选择元素时理解术语“子元素”、“父元素”和“兄弟元素”将非常重要所以请确保您对它们的含义有信心。 正在下载 jQuery 在做了大量准备之后您已经准备好开始第一次使用 jQuery 了。最好的起点是位于 http://jquery.com 的 jQuery 网站(见图 2-1 )。 img/A310335_2_En_2_Fig1_HTML.jpg) 图 2-1。 The jQuery home page 单击 jQuery 主页上的大下载 jQuery 按钮(或下载选项卡)打开下载页面。这里给出了将 jQuery 添加到项目中的许多方法。例如如果您想在本地添加 jQuery您可以下载压缩版本或未压缩版本。如果您正在使用 npm(节点包管理器)或 Bower(另一个包管理器)您可以在这里找到说明。此外还有使用 CDN(内容交付网络)和其他一些方式的说明。 如果您单击主页上的“下载 jQuery”按钮。下载 jQuery 有多种选择。下载页面上列出了两个压缩级别选项: 生产(87KB)缩小并压缩开发(268KB)未压缩代码 除非您想详细研究使用 jQuery 创建的每个项目的 jQuery 源代码否则请始终选择产品版本。这段代码是通过一个 minifier 运行的mini fier 是一个将 JavaScript 文件压缩成较小版本的程序。缩小器执行许多操作来使代码尽可能小包括 去掉所有的空白。删除所有注释。重命名长变量名例如var myCar可能会变成var a。 精简的代码是完全不可读的但它并不是为了可读而设计的——它的设计是为了使文件尽可能小。从现在开始当我们提到 jQuery 源代码时我们指的是 jQuery 的缩小版。 一些开发者链接到一个 CDN 托管版本的 jQuery其中最流行的是谷歌的 CDN ( https://developers.google.com/speed/libraries/#jquery )。这些允许您通过引用驻留在 CDN 上的 jQuery 文件来包含 jQuery。如果您想包含来自 Google CDN 的最新版本的 jQuery您可以这样做: script srchttp://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js/script 这样做有好处。如果用户访问了以这种方式引用 jQuery 的另一个站点他们可能已经缓存了该文件这意味着浏览器不必再次下载它。然而对于本书中的示例我们选择在本地下载一个版本的 jQuery原因很简单:您不需要通过互联网来完成这些示例。这听起来可能很愚蠢但不止一次我们的一位作者在火车上准备做一些工作只记得他参考了 Google CDN 版本的 jQuery而且他没有互联网连接。 jQuery API 文档 如果您正在使用 jQuery您需要一个很好的来源来了解每个 API 的功能。jQuery 文档( http://api.jquery.com )列出了 jQuery 提供的每一种方法。jQuery 如此成功的另一个原因是它的文档这很棒。我们不能夸大我们认为文档有多好(见图 2-2 )。 img/A310335_2_En_2_Fig2_HTML.jpg) 图 2-2。 The jQuery API index page 有几种方法可以在网站上找到你想要的东西。如果你确切地知道你想要哪种方法使用位于屏幕右上角的搜索框是最快的方法。如果您不确定您到底想要什么——也许您正在寻找一种方法来做一些特定的事情但是您不确定它是否存在——您可以浏览屏幕左侧列出的 jQuery API 类别来缩小搜索范围。你现在还不需要看这些但是你会多次回到 API。把它放在你的书签栏上或者找一个简单的方法浏览它因为你会经常用到它。 编写一些 jQuery 将下载的 jQuery 文件作为jquery.js保存在机器上的新文件夹中。您还将向该文件夹添加一个 HTML 文件因此也创建一个index.html页面。最后您想在一个单独的文件中编写所有的 JavaScript所以创建app.js。此代码在02/code/ex1内可用。 在您选择的编辑器中加载 HTML 页面——我个人使用 Vim 我们强烈推荐 Sublime Text 2 ( www.sublimetext.com/2 )、Visual Studio Code ( https://code.visualstudio.com )或 Atom ( https://atom.io )所有这些都可以在 Windows、macOS 和 Linux 上运行——并添加以下内容: !DOCTYPE html htmlheadtitleChapter 02, Exercise 01/titlescript srcjquery.js/scriptscript srcapp.js/script/headbodypHello World/p/body /html 这只是一个基本的 HTML 页面没有什么花哨的。看看这两个script标签 script srcjquery.js/script script srcapp.js/script 先载入 jQuery 再载入app.js文件目前为空。 Note 使用script标签加载文件的顺序非常重要。请记住您编写的代码将依赖于 jQuery因此您必须在任何使用它的脚本之前加载 jQuery。 现在你有了自己的页面继续在浏览器中加载index.html。除了“Hello World”文本之外您还看不到任何内容。进入app.js并添加下面一行——你在书中写的 jQuery 的第一行 $(body).css(background, red); 你能猜到这是干什么的吗你已经看到了$(body)选择了body标签(记住它们只是 CSS 选择器)你可能会尝试一下css(background, red)做什么。刷新页面你…不会看到任何变化。 这是许多 jQuery 初学者在开始时都会犯的错误。问题又回到了您的index.html文件中: !DOCTYPE html htmlheadmeta charsetutf-8 /titleChapter 02, Exercise 01/titlescript srcjquery.js/scriptscript srcapp.js/script/headbodypHello World/p/body /html 在加载页面的其余部分之前先加载 JavaScript所以当执行 JavaScript 时页面还没有完全加载这意味着 DOM 还没有准备好。因为在运行 JavaScript 时页面没有完全加载所以浏览器没有完成 DOM 的构建这意味着就 DOM 而言在运行 JavaScript 时,body并不存在。您有两种选择: 在页面底部包含您的 JavaScript就在关闭/body之前。这意味着它在 DOM 加载后运行。告诉您的 JavaScript 在 DOM 准备好之前不要执行。 实际上最好在底部包含 JavaScript这样就不会延迟内容加载。所以在这本书的大部分时间里我们都会这么做。然而这一次我们将选择第二个选项——纯粹是因为我们需要解释你如何着手去做。为了讨论如何在 DOM 加载之前停止代码的运行我们将简单讨论一下事件。我们将在第四章中详细介绍这些事件但是你现在需要尝试一下这个话题。 在浏览器中编写 JavaScript 是非常基于事件的。编写基于事件执行的代码。用户单击一个按钮向下滚动页面悬停在一个图像上等等。这些动作中的每一个都会引发一个事件这个事件被 JavaScript 捕获然后基于事件的发生执行代码。 加载 DOM 时浏览器也会发出一个事件。然后您可以编写仅在该事件触发时执行的代码这意味着您知道您的代码将仅在 DOM 设置完毕并准备就绪时执行。使用 jQuery您可以这样做: $(function() {//DOM is ready to go }); 让我们来分解这条线: $(document):这将变量document传递给 jQuery。document变量是一个特殊的变量它包含对页面上所有 HTML 元素的引用。当这个对象触发一个ready事件时您想要执行一些代码。 .ready() : ready是 jQuery 支持的众多事件之一。你传递给它一个函数这个函数在ready事件被触发时被执行。因为你正在做$(document).ready()当一个ready事件在document对象上注册时你传入的函数被触发。 function() {}:您传递给ready调用的是一个常规的 JavaScript 函数当事件发出时它将被调用。这就像创建函数就像你在第一章中所做的那样但是你没有命名它们而是直接传入一个函数。你可以这样做: function onReady() {alert(READY TO GO!); } $(document).ready(onReady); 但在实践中更简单的方法是创建函数并立即将其传递给事件处理程序而不需要先显式命名它。这样你就创建了一个匿名函数一个没有名字的函数。 前面一行代表以下所有内容: $(function() {$(body).css(background, red); }); 当你刷新index.html时你会看到一个红色的背景现在做$(document).ready(function() {})是如此普遍jQuery 有一个方便的快捷方式。您可以简单地执行以下操作: $(function() { }); 这意味着完全相同的事情。如果 jQuery 检测到您已经向它传递了一个函数它会认为这个函数应该已经在 DOM 上执行了。这是一个方便的小快捷方式可以帮你节省少量的打字时间。 上一段中的短语“jQuery 检测到您已经向它传递了一个函数”意味着当您选择类似于$(body);的东西时您实际上正在做的是调用 jQuery 提供的一个函数该函数被存储为一个名为$符号的变量。你也可以轻松做到这一点。下面的代码是有效的因为 JavaScript 不介意变量中有$符号或者变量名只有一个字符长: var $ function() { console.log(hey); }; $(); //logs hey to the console Note 如果页面上有 jQuery就不要这样做因为您将覆盖$变量——这意味着它将不再引用 jQuery。 所以 jQuery 所做的就是将一个函数绑定到$这很聪明。它可以检测您传递给它的内容并执行某些操作。所以当你传入$(body);时它知道选择 body 元素。但是当你传入$(function() {}) ;时它会检测到你传入了一个函数并相应地采取行动。 现在尝试一些更复杂的东西。在 HTML 页面的head中添加一个到新样式表的链接您也应该创建这个样式表如下所示: link relstylesheet typetext/css hrefstyle.css / 删除 Hello World 段落并在body标记中用以下 HTML 替换它: div idboxmy box/div 进入style.css并添加以下内容: #box {width: 100px;height: 100px;text-align: center;background: #f00;font-size: 14px; } 最后将您的app.js编辑成简单的: $(function() { }); 您应该会看到一个简单的屏幕如图 2-3 所示。 img/A310335_2_En_2_Fig3_HTML.jpg) 图 2-3。 The resulting box 它不会赢得任何设计奖项但现在你可以用这个盒子做一些有趣的东西。首先创建一个变量来存储对 ID 为box的div的引用如下所示: var box $(#box); 将对它的引用保存为变量因为您将不止一次使用它。执行以下操作是低效的因为每次使用$(#box)时都要让 jQuery 选择元素两次: $(#box).doSomething(); $(#box).doSomethingElse(); 最好只做一次然后保存到一个变量中。 动画示例 现在让我们看一个 jQuery 动画示例。虽然动画可能看起来令人望而生畏特别是在开始时但它是真正展示 jQuery 能力并立即给出结果的领域之一这使得它成为一个很好的起点。这个例子不会涉及太多的细节只是浏览一下 jQuery 的一些关键特性。稍后您将详细了解每个领域。这纯粹是对 jQuery 功能的简单介绍。 你要做的第一件事是淡出你的盒子。使您的app.js文件看起来如下: $(function() {var box $(#box);box.fadeOut(slow); }); 刷新你的页面——那个可爱的红框会慢慢淡出你的视线。很容易理解为什么fadeOut()方法被恰当地命名。正如你所看到的传入参数slow使盒子淡出得更慢。你也可以使用关键字normal和fast它们的功能和你想象的完全一样。 如果您想要一个全面概述fadeOut方法如何工作以及如何使用它的页面请查阅 jQuery API 文档。如果您搜索 fadeOut 并找到该方法的文档您会看到如图 2-4 所示的内容。 img/A310335_2_En_2_Fig4_HTML.jpg) 图 2-4。 The jQuery documentation for the fadeOut() method 文档的第一部分如下: .fadeOut( [duration] [, complete] ) duration A string or number determining how long the animation will run. complete A function to call once the animation is complete. 能够阅读和理解 API 将为您节省大量时间。前面的语法现在可能还很陌生但是一旦你知道它是如何工作的就很容易理解了因为它在整个 API 中都是一致的。第一行描述了如何调用该方法。这表明您可以通过传入一个持续时间和一个完成函数来调用fadeOut()。每个参数周围的方括号表示该参数是可选的您不必传递任何一个参数。您可以传入一个参数传入两个参数或者一个都不传jQuery 知道如何处理这种情况。之前您这样称呼它: $(#box).fadeOut(slow); 您可以看到您传入了持续时间但没有传入完成方法。回调是 JavaScript 中经常使用的一个术语指的是一旦某个东西执行完毕就被调用的函数。在fadeOut()的上下文中这个完成函数会在你的盒子淡出后被调用。要查看实际效果请将您的app.js更改为以下内容: $(function() {var box $(#box);box.fadeOut(slow, function() {alert(box finished fading out);}); }); 一旦该框淡出您将在屏幕上看到一个警告。这给了你很大的力量去做一些事情然后在最初的事情完成的时候运行其他的事情。回调在 jQuery 中被广泛使用。大量的方法尤其是动画方法都需要回调你会经常用到它们。当然因为两个参数都是可选的所以您也可以只传入一个回调就像这样: $(function() {var box $(#box);box.fadeOut(function() {alert(box finished fading out);}); }); 你会注意到当你刷新的时候这个盒子会更快的消失。以前你以“慢”的速度通过。但是如果没有传入一个会怎么样呢jQuery 是做什么的 任何可选的参数都有一个默认值jQuery API 会告诉你它是什么。以fadeOut()为例jQuery API 说: Duration is given in milliseconds; Higher values indicate slower animations, not faster ones. You can provide the strings “fast” and “slow” to represent the durations of 200 and 600 milliseconds, respectively. If any other string is provided or the duration parameter is omitted, the default duration of 400 milliseconds is used. ( http://api.jquery.com/fadeOut/ ) 所以如果你遗漏了一个参数它默认为 400 毫秒。传入“slow”是将它设置为 600 毫秒。你也可以传入一个数字。试着慢慢来。记住数字是毫秒所以 3 秒 3000 毫秒。 $(function() {var box $(#box);box.fadeOut(3000, function() {alert(box finished fading out);}); }); 所以有了fadeOut()jQuery 就有了它能识别的三个默认字符串: slow : 600 毫秒normal : 400 毫秒(也是默认)fast : 200 毫秒 除此之外您可以以毫秒为单位传入一个值。 现在假设您想要连续地淡入淡出一个框可能需要十次。你不会惊讶地发现fadeOut()有一个同伴fadeIn()它做的正好相反。所以你可以把这两种方法结合起来得到想要的效果。至少如果您没有正确地浏览 API您会这样做。 你看除了fadeIn()和fadeOut()还有fadeToggle()。如果它不可见它将在框中淡入如果它可见它将淡出框。因此你可以利用这一点使事情变得容易得多。如果您在文档中搜索了“fade ”,那么您已经看到了这个方法。我们怎么鼓励你广泛使用 API 文档都不为过尤其是在学习的时候。 img/A310335_2_En_2_Fig5_HTML.jpg) 图 2-5。 The API documentation search results for “fade” 所以你要做的是: 创建一个函数将切换框然后退出。存储一个变量记录你这样做的次数。有一个段落它的文本总是更新为框淡入淡出的次数。 然后该函数将调用自身使该框再次淡入淡出——如果保持计数的变量小于某个数量。 这里会有几个新东西耐心点。最后您将会看到 jQuery 让事情变得多么简单这是非常令人兴奋的。你是从上一个练习停止的地方继续所以你不是完全从头开始。 首先要做的是将段落添加到您的index.html页面看起来应该如下: !DOCTYPE html htmlheadtitleChapter 02, Exercise 02/titlescript srcjquery.js/scriptscript srcapp.js/scriptlink relstylesheet typetext/css hrefstyle.css //headbodydiv idboxmy box/divp/p/body /html 添加一个空的 HTML 元素并不是一个好的做法但是在不久的将来你将学会如何避免这个问题。编辑app.js设置将要使用的变量如下所示: $(function() {var box $(#box);var para $(p);var i 0; }); 您将存储对框、段落和count变量i的引用该变量被设置为 0。首先要做的是让你的段落显示计数器的值。要更新元素中的文本可以使用text()方法。如果您不带参数调用text()将会返回文本。如果你传入一个参数它会将文本设置为你传入的内容。因此你可以做para.text(i);来设置文本的值为i。 现在您必须编写主函数来执行所有的切换。与其一行一行地做这件事不如直接查看完整的代码然后遍历它。您的app.js文件将如下所示: $(function() {var box $(#box);var para $(p);var i 0;para.text(i);function toggleBox(i) {box.fadeToggle(500, function() {i i 1;if(i 10) {para.text(i);toggleBox(i);};});};toggleBox(i); }); 先说一下toggleBox()功能: function toggleBox(i) {box.fadeToggle(500, function() {i i;if(i 10) {para.text(i);toggleBox(i);};});}; 你做的第一件事是调用fadeToggle()它将根据当前状态淡入或淡出盒子。就像fadeIn()和fadeOut()一样给它一个速度——半秒(500 毫秒)——和一个回调函数一旦盒子淡入/淡出就执行这个函数。该函数采用一个参数i变量它存储已经执行的渐变次数。你需要这个来看看你是否应该继续褪色。 在回调中执行以下操作: 将i的值增加 1-使用运算符这是i i 1的快捷方式。如果i 10: 将段落的值设置为i的当前值。再次调用toggleBox()传入i。 这样你可以刷新你的页面看到一个在停止前会淡入淡出五次的框。您还会看到显示发生次数的段落。 但是坚持住。为什么它显示 9而不是 10事实上它已经淡入淡出十次了。原因是i最初被设置为 0所以盒子第一次褪色时实际上是第零次褪色。因此当i为 9 时它实际上发生了十次。 通常的做法是让count变量从 0 开始主要是因为数组是零索引的正如你在第一章中看到的。但是您可能希望输出的值从 1 到 10这很容易通过更改两行代码来实现 para.text(i); 到 para.text(i1); 因此1–10 将显示在浏览器中但在幕后它使用 0–9。 摘要 哇哦。这是艰难的一章你已经做了很多: 看到了如何下载最新版本的 jQuery。发现了什么是精简代码以及为什么您应该总是使用精简的 jQuery 版本。通过fadeIn()、fadeOut()、fadeToggle()介绍了一些动画。使用回调函数在动画完成后运行一段代码。通过text()方法更新了 DOM 中的文本。发现了如何通过使用$(document).ready()使代码仅在 DOM 加载后运行。使用 jQuery API 找到您想要的方法。 如果你感到有点害怕不要担心。这是 jQuery 所能提供的一些功能的一个短暂停留。下一章通过展示如何遍历 DOM更系统地介绍了 jQuery 所提供的一切。 三、穿越大教堂 您已经看到了 jQuery 如何工作以及如何让动画框淡入淡出。现在是时候更有条理地看看这个库探索它能做的一切了。本章没有涵盖 jQuery 必须提供的每一种方法因为许多方法做的事情非常相似。也有一些方法做了完全相反的事情。例如在第二章中在看了fadeOut()如何工作之后你只简单地看了一下fadeIn()因为在见过fadeOut()之后很明显它会做什么。很多 jQuery 方法也有类似的情况。 然而这一章不仅仅是所有 jQuery 遍历方法的文档。效率是这一章的一大部分——而且会被多次提到。本章的内容如下: 用 CSS 选择器选择元素并探索哪一个是最有效的。使用 jQuery 伪选择器。探索 jQuery 提供的各种遍历方法。缓存选择器和链接方法以避免重选元素。避免不必要的 DOM 工作。任何 jQuery 项目的瓶颈总是 DOM 交互。与 DOM 交互是昂贵的所以你能做的次数越少越好。 jQuery 中的 CSS 选择器 jQuery 的魅力以及它如此受欢迎的原因当然与它如此易于使用这一事实有关。您可能熟悉 CSS并且知道要通过 ID 选择元素可以使用散列符号(#)。要按类选择元素可以使用句点(。)等等。jQuery 允许您使用这些选择器(以及更多)从 DOM 中选择元素。同样重要的是它提供了向后兼容性。所以即使你用的 CSS 选择器在 IE7 及以下不能用在 jQuery 中用的时候还是可以用的。 然而伴随着强大的能力而来的是巨大的责任从计算的角度来看很多这样的选择器是非常低效的。选择元素的最基本方法是按其 ID如下所示: $(#header); $(#maincontent); 这种方式总是比通过类或标签名选择更快其他常见的方式例如: $(.column); $(.header);$(body); $(div); 通过 ID 选择是最佳方式的原因有两个。首先JavaScript 有自己的按 ID 选择的机制—document.getElementById(header)—所以当 jQuery 检测到您传入了一个 ID 时它可以简单地调用那个方法。第二应该只有一个元素具有特定的 ID所以一旦找到结果它就停止搜索。 Note 由您来确保一个页面上只有一个 ID 实例。如果有多个元素具有相同的 IDJavaScript(以及 jQuery)将只返回第一个元素。一个 id 存在于多个元素上是无效的 HTML。 如果你通过一个类寻找某个东西可能会有多个结果所以 JavaScript 必须继续搜索整个 DOM。如果可以通过 ID 选择元素那么就这样做。 另一件值得一提的事情是 jQuery 处理选择器结果的方式。无论返回一个元素还是五十个元素结果都将返回一个类似数组的结构(它实际上不是一个数组但很快会有更详细的描述)。假设你在一页上有一个段落你运行$(p)。看看你得到了什么: [pHey/p] 如果你还有几个你会得到这个: [pHey/p, pHey/p, pHey/p, pHey/p] Note 如果你使用的是谷歌浏览器以外的浏览器你的输出可能会略有不同。前面的示例显示了 Chrome 浏览器开发工具的输出。例如在 Firefox 中输出是 [p, p, p] 请放心代码会找到相同的元素集。只是控制台输出的方式不同而已。 这样做的好处之一是您可以通过对结果使用.length来轻松地找出返回的项目数如下所示因为结果的行为就像一个 JavaScript 数组: $(p).length; // 4 在 jQuery 1.8 之前的版本中可以使用 jQuery 方法$(p).size()但是.size()所做的只是返回使用.length的结果所以开发人员通常使用.length。 在这个阶段jQuery 可能看起来只是返回了一个常规数组但事实并非如此。它返回一个 jQuery 对象。这个 jQuery 对象就像你在第一章 1 中探索的常规对象一样。它包含所有 jQuery 属性和方法以及您执行的选择器中的元素。一种很好的理解方式是jQuery 对象是一个增强的数组。在其核心它有一个 DOM 元素列表——但远不止这些。请记住当您运行$(p)并返回看起来非常像数组的内容时它并不是。它实际上是一个 jQuery 对象。 jQuery 的新用户发现最令人困惑的事情之一是一些方法在它们返回的每个元素上都被调用而另一些则没有。例如假设你有一个包含四个段落的列表你想给每个段落一个类。以下将起作用: $(p).addClass(paragraph); addClass()方法非常简单明了。它只是向元素添加了一个类。注意这个addClass()方法在结果集中的每个元素上运行。还要注意的是您不必循环遍历它们。如果您有一组元素并调用一个方法jQuery 通常会隐式地为您执行循环。这真的很有用但是可能有点混乱所以只要记住 jQuery 会尽可能地为您循环。 当然因为 jQuery 可以解析 CSS 选择器所以可以给它传递非常复杂的选择器比如: $(divul a); $(div#main p strong); $(div.main pli a); 但是这些选择器的缺点是它们越复杂运行的时间就越长代码执行的速度就越慢。jQuery 从右到左解析它的 CSS 选择器所以最后一个例子做的是 定位所有定位元素。过滤掉不在列表项中的锚元素。过滤掉所有剩余的元素这样剩下的元素就在一个段落的直接子元素li中。仅选择类别main中的剩余元素。仅选择那些在具有该类别main的div内的剩余部分。 光是找到一些链接就要做很多工作。在决定使用哪个选择器时您需要警惕并牢记这种事情。 遍历方法 遍历方法是让我们在 DOM 中“跳”来寻找特定元素的方法。遍历方法将帮助您通过多种方式从元素 A 到达元素 B。在本节中您将研究这些方法是什么并探索如何尽可能提高效率。jQuery 有大量的遍历方法正如文档( http://api.jquery.com/category/traversing/ )将向您展示的那样。 在这一章的剩余部分我们将讨论我们认为最有用的方法——也是你最常用的方法。一路上会有各种切线进一步讨论你需要知道的东西。 您通常会有一组想要缩小范围的元素。也许你只想要第一个或者最后一个或者你想从数组中选择一个特定的。您可以使用eq()方法来实现这一点。假设您的 HTML 包含一些段落如下所示: pPara 1/p pPara 2/p pPara 3/p 那我们假设你跑了$(p)。您将得到以下结果: [pPara 1/p, pPara 2/p, pPara 3/p] eq()方法将返回一个 jQuery 对象其中包含特定索引处的元素。例如$(p).eq(0)将给出包含第一段的 jQuery 对象(记住数组是零索引的)。假设您要运行以下内容: alert($(p).eq(0).text()); 您会看到Para 1因为获取第一个元素是如此常见的事情以至于 jQuery 提供了first()它做的完全一样。得知还有一种last()方法你不会感到惊讶。 因为获得第一个结果是如此常见jQuery 给了我们另一种做事方式。请考虑以下几点: $(p:first); $(p:eq(0)); 这两者会达到同样的效果。jQuery 支持许多这样的伪类。 Note jQuery 支持大多数 CSS 伪类但也有一些自己的伪类比如:eq(0)。你可以在 https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes 找到更多关于伪类的信息 一些伪类直接匹配 CSS3 规范但是其他的(包括前面两个)不匹配。在本章和本书的过程中你会看到很多。 现在的问题是当 jQuery 同时提供伪类选择器和方法时应该使用哪一个。我们更喜欢使用方法而不是伪选择器。我们认为他们阅读能力更强更容易明白发生了什么。这是因为当您使用该方法时它不包含在选择器中。这意味着当您浏览代码时对该方法的调用更加突出因为它不在选择器中。 不过还有另一个原因。更新、更现代的浏览器如 Google Chrome 和 Mozilla Firefox 支持两种非常强大的方法:querySelector()和querySelectorAll()。这些是强大的选择方法可以解析任何 CSS 选择器。querySelector()返回选择器的第一个匹配querySelectorAll()返回所有匹配。jQuery 将始终使用querySelector()和querySelectorAll()如果它们可用的话因为这样做可以更快地获得具有复杂选择器的元素。 如果使用$(p:first)选择器jQuery 不能简单地将p:first传递给querySelectorAll()方法因为:first不是 CSS 伪类。但是如果使用$(p).first()jQuery 可以将p选择器传递给一个本地 JavaScript 方法——在本例中为getElementsByTagName()——然后对$(p)的结果调用first()。任何本地方法总是最快的所以无论何时您可以选择允许 jQuery 使用本地方法您都应该这样做。 进一步遍历 一旦获得了初始的元素集很有可能需要在其中进行进一步的搜索。以下面的 HTML 结构为例: divpParagraph strongone/strong/ppParagraph Two/p /div 假设您首先选择了div然后将其保存到一个变量中(也称为缓存): var myDiv $(div); 现在让我们假设您想要查找那个div中的所有段落。jQuery 提供了两种实现方式: myDiv.find(p); myDiv.children(p); 或者当然你本来可以写 $(div p); 综合考虑这三种方法哪种最好如果单从速度上来说$(div p)在新的浏览器中总是最快的——也就是说那些支持querySelector()和querySelectorAll()的浏览器。如果你只为这些浏览器建立一个网站那么在最初的选择中进行大部分过滤实际上更有效所以你使用querySelectorAll()。 如果你担心老版本和新版本的浏览器那么$(div p)通常是最慢的方法特别是当你的选择器更复杂的时候。这样就剩下两种方法:find()和children()。这两种方法有一个重要的区别。API 将它们在 http://api.jquery.com/category/traversing/ children()处描述为“获取匹配元素集合中每个元素的子元素可选地由选择器过滤。”find()被描述为“获取当前匹配元素集中每个元素的后代由选择器、jQuery 对象或元素过滤。” 关键的区别在于每个描述的第三个词。第一个方法将获得每个元素的子元素第二个方法获得子元素。看这张图表: div - p - p - - strong - - - a 在这里段落是div的子段落。然而段落、strong和锚都是div的后代。子元素只是直接的后代而后代则意味着元素中的一切不管它在哪个层次上。 在这种情况下请检查以下结构: divpParagraph strongone/strong/ppParagraph Two/p /div 你应该用children()而不是find。原因是find()将搜索 DOM 的每一层来尝试找到一个匹配而children()将只搜索元素的直接层来找到一个匹配。所以当你只想要直系后代的时候比如这个例子children()会更快。诚然这是一个微小的速度差异但它只会做你需要它做的事情——而find会做得更多——所以坚持使用children()是有意义的。这还表明您只选择了直系后代使您的代码读起来更好。 有了children()和find()这两个方法您就不局限于传入一个标签了。它们以及所有类似的遍历方法接受任何 CSS 选择器就像您可能通过$()传递给初始 jQuery 对象的那些一样比如: $(div).find(pstrong); 这将返回作为段落直接子元素的所有strong元素这些段落存在于一个div中。 另一个非常有用的方法是siblings()如您所料它获取当前元素的所有兄弟元素。以这个结构为例: divp classfirst-paragraphParagraph 1/ppParagraph 2/ppParagraph strong3/strong/p /div 运行$(div).siblings()不会给你任何结果。这是因为div是该级别的唯一元素。要获得第一段的所有兄弟您可以执行以下操作: $(.first-paragraph).siblings(); 这将给出包含其他两个段落的结果集但不包含初始段落。如果您想将初始段落添加到元素集合中这样您就拥有了元素的兄弟元素和原始元素您可以使用.add()它可用于将其他元素添加到现有集合中。例如考虑使用以下内容: $(.main).add(.paragraphs); 它将留给您一个包含类main的元素结果集以及包含类paragraphs的元素结果集。因此在本例中您可以执行以下操作: $(.first-paragraph).siblings().add(.first-paragraph); 但是这不是很有效率。请注意您运行了选择器两次。这意味着您要搜索 DOM 两次这一点也不好。幸运的是jQuery 提供了andSelf()这是一种更简单的方法。它从上一个选择中获取一组元素并将其添加到当前选择中: $(.first-paragraph).siblings().andSelf(); 这给出了一个包括兄弟()和初始段落的集合。andSelf()你会发现自己并不经常使用这种方法但了解这种方法非常有用。使用 DOM 结构实际上还有另一种方法可以获得第一段的兄弟段落: $(.first-paragraph).nextAll(); nextAll()获取当前元素之后的所有兄弟元素。因此对于这个 HTML如下所示: divpParagraph 1/pp classsecondParagraph 2/ppParagraph 3/p /div 运行$(.second).nextAll();只会返回一个元素——第三段。运行$(.second).siblings()给出两个元素——第一段和最后一段。因此nextAll()获得 DOM 结构中当前元素之后的所有兄弟元素。还有一个相反的方法prevAll()它获取当前元素之前的所有兄弟元素。还有prev()和next()它们获取当前元素旁边的兄弟元素——在prev()的情况下是当前元素之前的兄弟元素或者在next()的情况下是当前元素之后的兄弟元素。 链接方法 您可能已经注意到前面的例子将两个方法链接在一起就像这样 $(.first-paragraph).siblings().andSelf(); 这是 jQuery 的关键特性之一。方法可以被一个接一个地调用并被链接在一起。任何返回 jQuery 对象的方法都可以被链接。要判断一个方法是否返回 jQuery 对象请查看其 jQuery API 文档的右上角(参见图 3-1 )。 img/A310335_2_En_3_Fig1_HTML.jpg) 图 3-1。 The top-right corner of the documentation shows that this method returns “jQuery”, meaning it can be chained 截图右上角显示该方法返回 jQuery。这意味着该方法可以被链接。 有些方法可以被链接也可以不被链接这取决于它们的使用方式。一种这样的方法是你在第 2 text()章看到的。如果不带参数调用text()它将返回元素的文本。但是如果您向它传递一些文本它将设置该元素的文本然后返回一个 jQuery 对象。text()的文档显示了这一点。有两个不同的条目。 第一个是针对text()本身它返回文本。你可以看到文档表明它返回一个字符串(见图 3-2 )。 img/A310335_2_En_3_Fig2_HTML.jpg) 图 3-2。 This method cannot be chained because it returns a string 然后是text()它接受一个参数并设置文本。它确实返回了 jQuery 对象(参见图 3-3 )。 img/A310335_2_En_3_Fig3_HTML.jpg) 图 3-3。 When you use .text() to set the text, it returns jQuery , so it can be chained 一般的经验法则是任何不显式返回除一组元素之外的东西的方法都可以被链接。 链接是避免多次选择元素的好方法如下所示: $(div).fadeOut(); $(div).css(color, red); $(div).text(hello world); 您可以这样做而不是那样做并运行$(div)三次: $(div).fadeOut().css(color, red).text(hello world); 空白在这里并不重要所以如果你想把它们分成多行请随意。我们经常这样做: $(div).fadeOut().css(color, red).text(hello world); 注意不要遗漏方法之间的任何点记住分号只在最后。如果您不喜欢链接您可能更喜欢缓存选择正如您已经看到的: var div $(div); div.fadeOut(); div.css(color, red); div.text(hello world); 到目前为止您已经使用了children()和find()来进一步遍历 DOM 结构但是当然也有一些函数可以做完全相反的事情。这些被称为parent()和parents()。两者的关键区别在于parent()只在 DOM 中向上一级而parents()一直向上。您可以在 jQuery 站点上找到这些函数的定义。 从字面上得到一个元素的所有父元素直到最顶层的元素。以下面的 HTML 结构为例: div pstrongHello/strong/p /div $(strong).parents()的结果是 [p.../p, div.../div, body.../body,html.../html] $(strong).parent()的结果是 [p.../p] 因为parents()遍历整个 DOM所以您几乎总是想要传递给它一些选择器只是因为对于.parents()来说返回body和html元素很少有用。然而有时您可能希望所有的父元素都包含在body元素中所以您经常需要做的是过滤掉parents()返回的元素集。有两种方法可以做到这一点。第一种是使用 jQuery 过滤器。之前您使用了:eq选择器和.eq()方法将结果过滤为一个结果。那是 jQuery 的过滤方法之一API ( http://api.jquery.com/category/traversing/filtering/ )里都有记载。 我们现在感兴趣的方法是not()。我们也将讨论其余的部分——一些在本章一些在本书的其他地方。not()完全按照您的预期进行操作——过滤结果。如果您想从您的parents()通话中删除body和html元素就像这样简单: $(strong).parents().not(html, body); 这将获取所有的父标签并过滤掉html和body标签。这是因为not()采用了 CSS 选择器。您实际上是告诉 jQuery 过滤掉与 CSS 选择器html, body匹配的元素。当然这个选择器匹配html和body元素。您也可以使用伪类:not就像您可以使用:eq一样但是如前所述使用该方法比伪类更可取(并且更容易阅读)所以这是您将在本书的其余部分看到的。 然而有一种更好的方法来做你想做的事情那就是使用parentsUntil()。有了parentsUntil()你的代码就简单多了。记住parentsUntil()获取所有元素但不包括选择器匹配的元素。现在你已经知道了这个方法你要做的就是下面的事情: $(strong).parentsUntil(body); 这给出了期望的结果。jQuery 是一个强大的趋势。如果有些事情看起来有点罗嗦很有可能有更简单的方法来做。 两个非常有用的过滤器是:even和:odd过滤器。将它们与采用过滤器并返回通过的过滤器的filter()方法结合起来您可以轻松地将背景颜色应用于行使表格看起来有条纹。这里有一个简单的表格可以使用: !DOCTYPE html htmlheadtitleChapter 03, Exercise 01/titlescript srcjquery.js/scriptscript srcapp.js/scriptlink relstylesheet typetext/css hrefstyle.css //headbodytabletrtdJack/tdtdFranklin/td/trtrtdStuart/tdtdRobson/td/trtrtdRob/tdtdHawkes/td/trtrtdAlex/tdtdOlder/td/tr/table/body /html 下面只是给出了表格的一些边框以便清楚地定义行: table {border-collapse: collapse; } tr {border-left: 1px solid grey;border-right: 1px solid grey;border-bottom: 1px solid grey; }td {padding: 10px; } 你可以在图 3-4 中看到结果。 img/A310335_2_En_3_Fig4_HTML.jpg) 图 3-4。 The plain table ready to apply the striped effect 下面是app.js文件: $(function() {var rows $(tr);rows.filter(:even).css(background, red);rows.filter(:odd).css(background, blue); }); 这给出了如图 3-5 所示的结果(当然不会赢得任何设计奖项)。 img/A310335_2_En_3_Fig5_HTML.jpg) 图 3-5。 The table once the code has run app.js文件做三件非常简单的事情: 将$(tr)的结果存储到变量rows中。过滤偶数行并将其涂成红色。过滤奇数行并将其涂成蓝色。 这是css()方法但是非常简单。当传递两个参数(一个属性和一个值)时它将设置集合中元素的 CSS 值。这个非常简单的例子向您展示了 jQuery 过滤器的强大功能。 进一步过滤 如果 jQuery 的内置过滤器还不够它还提供了一种机制允许您根据需要进行过滤。当您使用filter(even)过滤偶数行时您简要地看到了filter()方法的作用。您还可以给filter()传递一个函数该函数将评估集合中的每个元素并只返回符合特定条件的元素。 在你的index.html页面中添加四个段落看起来像这样: !DOCTYPE html htmlheadtitleChapter 03, Exercise 02/titlescript srcjquery.js/scriptscript srcapp.js/scriptlink relstylesheet typetext/css hrefstyle.css //headbodypstrongJack/strong Franklin/ppstrongJohn/strong Hammelink/ppstrongRichard/strong Quick/ppWill Hammil/p/body /html 摆脱你之前的一切你不需要任何造型。 现在让我们说你想过滤只有段落有一个strong标签并给他们一个红色背景。你要做的第一件事是获取所有的段落并把它们存储在一个变量中就像这样: $(function() {var ps $(p); }); 当你传递给filter()一个函数时它期望这个函数为每个元素返回true或false. filter()运行一次当你传递的函数计算结果为true时它将保留元素。它将去掉使函数评估为false的元素。 在这个函数中你可以通过第一章中提到的this关键字访问当前元素。this关键字是 JavaScript 中的一个特殊变量您可以经常使用它来引用您正在处理的当前项目。要访问您正在处理的但是包装在 jQuery 对象中的当前元素您可以简单地运行$(this)。 要过滤掉所有没有strong元素的元素您需要检查段落是否包含任何元素。有两条信息可以得到这个结果: 你可以通过$(p).children(strong);得到一个元素内的所有strong元素通过添加.length可以看到结果集中有多少个元素比如:$(p).children(strong).length; 因此对于包含strong元素的段落必须满足以下条件: $(p).children(strong).length 0; 这个表达式可以返回true或false它就是你要传递给过滤函数的内容就像这样: $(function() {var ps $(p);var strongPs ps.filter(function() {return $(this).children(strong).length 0;});strongPs.css(background, red); }); 你得到了想要的结果如图 3-6 所示。 img/A310335_2_En_3_Fig6_HTML.jpg) 图 3-6。 Three of the four paragraphs, the ones with a inside, are given a red background 我相信你可以想象到当传递一个函数时filter()方法是非常强大的。你可以过滤任何你想要的东西只要你能把它评估为true。 有一种方法可以简化代码。filter()方法仍然返回 jQuery 对象这意味着它可以被链接。这意味着您可以稍微缩短代码如下所示: $(function() {var ps $(p);ps.filter(function() {return $(this).children(strong).length 0;}).css(background, red); }); 这里你使用了一个ps变量但是只引用了一次把它扔掉这样你就剩下了: $(function() {$(p).filter(function() {return $(this).children(strong).length 0;}).css(background, red); }); 好多了 摘要 这是迄今为止最紧张的一章你涵盖了许多新的领域。书中涉及的所有方法都会用到所以如果有什么你不太确定的不要担心——会有很多机会用到这些方法。对于 jQuery很多都是实践所以我们建议您自己编写一些代码。试试看。记得使用 API 文档——它真的很棒。在下一章你将开始用 jQuery 操作 DOM。 四、使用 jQuery 操作 DOM 现在您已经对 jQuery 及其功能有了一定的了解。您知道如何选择元素如何确保您的代码只在 DOM 加载后运行以及更多。您还看了一些动画并通过使用css()方法改变元素的颜色做了一些基本的操作。你可能没有意识到动画是一种操作。之前您使用fadeIn() / fadeOut()来操作一段时间内元素的不透明度。本章将完全集中在元素的操作上包括: 用css()方法改变 CSS 样式遇到 jQuery 的animate()方法时会有更多的动画在 DOM 中插入、移除和移动元素用attr()编辑元素属性jQuery 提供了无数的操作方法 在您的过程中您将会有规律的停顿和小的偏离来检查最佳实践。正如在第三章中提到的DOM 操作通常是网站的一个巨大瓶颈所以你应该尽量少做。有很多技巧和方法可以限制花在 DOM 上的时间我们会在你阅读本章的时候提到这些技巧和方法。 第三章还指出jQuery API 让你很好地掌握了 API 的操作方法( http://api.jquery.com/category/manipulation/ )所以你可以随时参考。 半铸钢ˌ钢性铸铁(Cast Semi-Steel) jQuery 的css()方法非常强大。实际上有三种主要的方法可以使用它。第一种是在确定元素的属性值时。只需给它传递一个参数—您想要知道其值的属性: $(div).css(width);$(div).css(margin-right);$(div).css(color); 重要的是要注意如果你有一组不止一个的元素并且你调用了css()你将得到的结果就好像是在第一个元素上调用了css()。另一个重要的注意事项是你不能使用速记。例如这是行不通的: $(div).css(margin); Note 如果您使用css()来获取宽度那么您可能想看看 jQuery 的width()、innerWidth()和outerWidth()方法。虽然css(width)将返回一个类似200px的字符串但是宽度方法总是返回一个整数值。如果您正在执行任何基于宽度的计算那么从一开始就将其作为一个整数要比获取一个字符串并转换它容易得多。 也可以使用 CSS 来设置值。若要只设置一个值请将属性和值作为单独的参数传入。你在第三章用过这个。 $(div).css(color, red);$(div).css(border, 1px solid red); 更有用的是css()方法还接受一个键值对对象该对象将 CSS 属性映射到您想要设置的值。例如: $(div).css({background : red,margin-left: 200px,color: black }); 这是设置 CSS 属性更快的方法。然而如果您发现自己经常这样做很可能您应该实际创建一个新的 CSS 类来拥有这些属性然后简单地用 jQuery 将该类添加到元素中。这意味着 jQuery 做的操作更少因为它只需要添加一个类。要添加一个类只需使用addClass()方法: $(div).addClass(column); 还有removeClass(): $(div).removeClass(column); 如果你想检查一个元素是否有一个特定的类有hasClass(): $(div).hasClass(column); 这将返回true或false。如果你想给某个东西添加一个类不管这个元素是否已经有了这个类你都可以这样做。jQuery 足够聪明可以为您解决所有这些问题。没有必要这样做: if( !$(div).hasClass(main) ) {$(div).addClass(main); }; 简单的叫addClass()。类似地在移除类之前不需要检查元素是否有类。这两种方法都可以接受多个参数: $(div).addClass(one two three); $(div).removeClass(four five six); 如果元素没有类您想添加一个类但是如果元素有了类您又想删除同一个类那么 jQuery 也能满足您的需求: $(div).toggleClass(main); 如果该集合中的元素具有该类它们将移除该类但是如果他们没有它将被添加。 还有一些事情您可以使用css()方法因为 jQuery 提供了更好的替代方法。例如要隐藏某个元素可以将其 CSS“显示”属性更改为“无”: $(div).css(display, none); 然后你可以再展示一次: $(div).css(display, block); 但是如果在您隐藏它之前它的“显示”属性被设置为“内联”或“内联块”呢jQuery 通过提供两个方法来解决这个问题:hide()和show()。它们的伟大之处在于当您使用hide()隐藏一个元素时jQuery 不仅隐藏了它还记住了它的“显示”属性。然后当您在该元素上调用show()时它会将 display 属性设置回之前的状态。因此要显示和隐藏元素请按如下方式操作而不要使用css()方法: $(div).hide();$(div).show(); animate()和动画便利方法 你已经发现了动画但是直到现在你还没有遇到 jQuery 使用的主要动画函数:animate()。从它的文档来看( http://api.jquery.com/animate/ )你会认为它非常复杂和难以使用但实际上它非常棒。即使你还没遇到过这种方法但你目前为止用过的动画方法包括fadeIn()和fadeOut()都用的是animate()。jQuery 提供了这些被称为便利方法的方法以节省您的输入。下面是 jQuery 源代码中实现fadeIn()的代码: function (speed, easing, callback) {return this.animate(props, speed, easing, callback); } 它所做的只是传递您传递给animate()方法的参数。如果没有 fade 方法下面是淡出元素的方法: $(div).animate({opacity: 0 }, 1000); 这将使div的不透明度在 1000 毫秒或 1 秒内下降到 0。每次输入都会令人沮丧所以实现了像fadeIn()这样的便利方法来节省您的输入。还有很多更方便的方法不只是针对动画一般的也可以。你会在整本书中遇到很多。 animate()的一般用法与css()方法非常相似:它需要一个对象的属性和值来设置。第二个参数是制作属性动画所需的时间。第三个是回调函数它的工作方式与您在本书前面传递给 fade 方法的函数完全一样。下面的代码片段向animate()传递了三个参数。第一个是键-值对的对象包含属性和您希望它们最终成为的值第二个是以毫秒为单位的时间(还是那句话1 秒 1000 毫秒)第三个是回调函数。该功能将在动画完成后立即执行。 $(div).animate({width : 200 }, 2000, function() {alert(Div is now 200px wide!); }); 另一种常见的动画是动画显示元素的高度通常通过“向上”滑动它们来隐藏它们这样它们的高度为 0实际上是隐藏的或者通过“向下”滑动它们来显示高度从而向用户显示元素。通过将高度设置为 0您可以有效地隐藏div: $(div).animate({height : 0 }, 2000); 但是由于这种情况非常普遍jQuery 提供了三种方法来使事情变得更简单: slideUp()slideDown()slideToggle() 这些方法通过高度来激活元素。将一个元素的高度设置为 0创建一个元素在页面上向上滑动的效果其高度越来越小直到消失。slideDown()相反动画元素的高度到一个特定的值。最后slideToggle()根据调用元素时的状态向上或向下滑动元素。如果在高度为 0 的元素上调用slideToggle()它会向下滑动并显示它。如果你在一个可见的元素上调用slideToggle()它会向上滑动。 现在看一个例子看看如何使用这些方法。您将使用一小段 CSS 在页面上创建一个“盒子”然后看看 slide 方法如何影响这个元素。 创建一个新文件夹来存放这些文件并创建index.html、app.js和style.css。添加您在之前所有练习中使用的基本 HTML(我们建议您简单地复制并粘贴一个旧练习然后将其重命名)。你的index.html应该是这样的: !DOCTYPE html htmlheadtitleChapter 04, Exercise 01/titlescript srcjquery.js/scriptscript srcapp.js/scriptlink relstylesheet typetext/css hrefstyle.css //headbodydiv idboxpA box/p/div/body /html 迅速做出一些造型: #box {width: 200px;height: 200px;background: red; } 让你的app.js空白准备好被一些令人惊叹的动画填充: $(function() { }); 现在选择div后添加对slideUp()的调用: $(function() {$(#box).slideUp(2000); }); 刷新页面您将看到框在 2 秒钟内滑出视图。记住slideUp()所做的只是调用animate()方法这是一条很好的捷径。 现在更改您的app.js文件使其看起来像这样: $(function() {var i 0;while( i 10 ) {$(#box).slideToggle(2000);i;}; }); 当你刷新页面时你会看到框向上、向下、向上滑动等等。它会滑动十次。前面的代码包含一个在变量i小于 10 时运行的循环。在i初始设置为 0 的情况下这确保了循环将运行十次。在这个循环中您调用slideToggle()如果它可见它将向上滑动一个框如果不可见它将向下滑动一个框。下面的一行是i它将i的值增加 1。 属性和特性 为了获取和设置 DOM 元素的属性jQuery 提供了attr()方法。这就像css()方法一样。做事有三种方式: $(div).attr(id)获取 ID 属性的值 $(div).attr(id, main)将 ID 属性的值设置为“main” $(div).attr({id : main,rel : one });一次设置多个属性 但是还有prop()它处理属性。attr()处理属性。例如给定一段 HTML如下所示: input typecheckbox checkedchecked / 那个checked属性表示当页面加载时复选框是否应该被选中。当用户与它交互时它不会自我更新。这是通过checked属性来管理的该属性在用户勾选或取消勾选复选框时更新。这是一个你应该使用prop()而不是attr()的例子。属性是你可以在 HTML 中看到的而属性是在“幕后”使用的如果你想这方面的内容jQuery 在 http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ 的博客是一个很好的起点。它对不同之处以及何时应该使用其中一种进行了详尽的解释。 根据我们的经验绝大多数时候您可以(也应该)使用attr()。甚至当你在更倾向于使用prop()的地方使用attr()时attr()也会简单地为你调用prop()。这并不意味着你应该简单地总是使用attr()——使用prop()可以提高速度。在本书中你会看到应该使用prop()的时候特别是在本书的后面当你看 HTML 表单的时候。 当在窗口或文档对象上设置属性时你应该总是使用prop()仅仅因为窗口和文档对象不是 HTML 元素——因为它们没有属性。 这里prop()的用法和attr()完全一样不用演示怎么用了。这一部分的关键是它们之间的区别。这可能是一个令人困惑的差异需要一段时间才能理解。如果您需要重读这一部分请不要担心。 文本()和 html() 如果想要更新元素中的一些文本最好的方法是使用text()方法。像许多其他 jQuery 方法一样它将在不带参数调用时返回文本的值但是当用一个参数调用时它将设置一个元素的文本。例如: pHello/p $(p).text(); //Hello $(p).text(Hey); $(p).text(); //Hey $(p).text(strongHey/strong); $(p).text(); //strongHey/strong 当您将 HTML 传递给text()方法时它会自动为您进行转义。这意味着 jQuery 替换了符号““lt;”。然后浏览器将此显示为“收件人”gt;。这意味着您将看到文本“嘿”而不是包裹在strong标签中的单词“嘿”。 strong标签被转义所以它没有被应用。这就是html()的用武之地。html()的工作方式与text()完全相同但不会对其中的任何 HTML 进行转义。这意味着在前面的例子中如果你使用html()而不是text()你会看到它被解释为 HTML这意味着strong标签没有被转义因此你会看到单词“嘿”现在应该是粗体的。 但是您不应该通过这些方法插入复杂的 HTML。jQuery 提供了无数插入 DOM 的选项您很快就会看到。 从 DOM 中移除元素 jQuery 有很多从 DOM 中移除元素的方法你可以在 http://api.jquery.com/category/manipulation/dom-removal/ 找到。 先说看起来最明显的一个:remove()。它从 DOM 中删除了元素集但也删除了与之相关的任何东西——比如事件。假设您有一些在元素被单击时运行的代码但是您随后移除该元素并将其重新插入到 DOM 的其他地方。在这种情况下您必须重新分配该代码以便在单击该元素时运行。运行remove()完全摆脱了与之相关的任何东西。 使用remove()返回匹配选择器的整个元素集而不仅仅是它刚刚移除的元素集。这是一个容易犯的错误。给定这个 HTML 结构: divphey/p /div 这个 JavaScript: $(function() {var p $(p).remove();console.log(p); }); 记录了以下内容。请注意这些示例是从 Google Chrome 开发者控制台生成的。如果您使用不同的您可能会得到不同的输出。例如对于下一个例子Firefox 控制台将简单地显示[p]。不要担心这个——这只是每个浏览器如何将结果输出到它的控制台。 [pHey/p] 这会让你认为它会把它拿走的东西还给你。但是如果您有这个 HTML: divphey/pp classremovehello/p /div 这个 JavaScript: $(function() {var p $(p).remove(.remove);console.log(p); }); 你把这两段都记录下来: [phey/p, p classremovehello/p] 请注意您是如何将选择器传递给remove()方法来过滤结果的。这里我们只从选择中选择了类别为“remove”的元素$(p)。在这种情况下我们本可以使用$(.remove).remove()取得同样的成绩。 您可能会问如果您无法获得刚刚移除的内容如何将该元素重新插入 DOM以便将它从 DOM 中的一个位置移动到另一个位置。我们稍后将讨论如何将该元素添加回 DOM。 如果您想从 DOM 中移除一个元素但不想移除它的关联那么可以使用detach()它的工作方式与remove()完全相同除了它不会移除当元素被点击时运行的代码之类的东西尽管您已经将元素从 DOM 中移除了。因此如果你要重新插入用detach()移除的元素任何事件处理程序仍然会触发。另一方面remove()完全删除元素和所有事件处理程序。 有时您可能希望删除元素中的所有内容而不是元素本身。这就是empty()的用武之地。以之前使用的 HTML 结构为例: divphey/pp classremovehello/p /div 运行这段 JavaScript 代码: $(function() {var d $(div).empty();console.log(d); }); 记录以下内容(同样如果您在不同的浏览器中您可能会得到略有不同的输出): [div/div] div被完全清空。关于empty()非常重要的一点是它还会删除元素中的文本。这是因为从技术上讲文本是一个 DOM 节点而empty()从元素中移除所有节点。 移除元素的最后一个方法是unwrap()它的操作大致与empty(). empty()相反获取元素并移除其子元素而unwrap()获取元素并移除其父元素。鉴于以下情况: divphey/p /div 以及下面的 JavaScript: $(function() {$(p).unwrap();console.log($(body).html()); }); 一旦您调用了unwrap()您就可以使用html()方法当不带任何参数调用该方法时它会返回一个字符串该字符串是该元素中的 HTML。可以预见的结果是 [pHey/p] 简单地删除它所调用的元素的父元素。 创建新元素 在开始向 DOM 插入新内容之前首先需要了解如何创建一个新对象。最简单的方法是创建一个 HTML 字符串。您将看到的大多数插入方法都会欣然接受这一点: var newParagraph pHello/p; 然而如果您插入更复杂的结构这可能会变得非常复杂。像上一个例子一样用一个字符串做快速加法没有错但是对于任何更复杂的东西你应该像这样创建它: var newDiv $(div/div, {text: Hello,class: newDiv,title: Hello }); 这是创建复杂元素的最佳方式因为复杂元素需要设置很多属性。您在一个空元素上调用 jQuery然后传入一个将属性映射到值的对象。注意您也可以使用 jQuery 方法。前面的例子表示一个属性“text ”,并给它一个值“Hello ”, jQuery 随后转换这个值并使用它的text()方法将文本设置为“Hello”。然后可以将这个新元素保存到一个变量中这样就可以将它插入到 DOM 中。让我们现在就做吧 插入到 DOM 中 你终于来了这需要一段时间但是您最终可以看到如何将东西放入 DOM。到目前为止您已经操作了现有的元素并删除了它们但是没有添加任何东西。jQuery 提供了大量向 DOM 中插入内容的方法因此您将看到一些最流行的方法。我们还将讨论效率因为当涉及到 DOM 时低效地做事在计算上是非常昂贵的。如果您看一下 jQuery 文档会发现有三类 DOM 插入方法: DOM InsertionAround:这些方法允许您在现有元素周围插入元素。DOM InsertionInside:这些方法允许您在现有元素中插入元素。DOM InsertionOutside:这些方法允许您在完全独立的现有元素之外插入元素。 我们将讨论每一个类别。有太多的方法来讨论它们但是像往常一样我们将选择我们最经常使用的方法和我们看到其他人经常使用的方法。 DOM 插入周围 在这个部分中只有三种方法。您会记得您曾经看过unwrap()以及它是如何被用来移除一个元素的父元素的。“around”方法都做了与此相反的事情:它们在现有元素周围包装新元素。有三种方法: wrap()wrapAll()wrapInner() 您最常使用的是wrap()但是其他方法也很有用所以您将从wrap()开始研究它们。对于所有使用wrap()的例子您将使用这个 HTML 结构: divphey/p /div 最简单的用法是向wrap()传递一个字符串: $(p).wrap(div/div); 这给了你: divdivpHey/p/div /div 这在段落元素周围包装了一个新的div元素。 你可以把它缩短一点。当传入一个新的空元素 HTML 字符串时只需执行以下操作就可以节省一些字符: $(p).wrap(div /); 当然您也可以通过创建新的元素来包装元素方法是通过传入 HTML 字符串和一个 properties 对象来创建新元素。然后您可以调用wrap()传入您刚刚创建的新对象。例如: var newDiv $(div /, {class : Hello,text: Hey }); $(p).wrap(newDiv); 给你: div div classHelloHeyphey/p/div /div 你可以看到你的段落已经用新的div换行了。 做一些类似的事情:它获取集合中的每个元素并将它们全部包装在新元素中。因此在前面的例子中您可以使用wrapAll()来获得相同的效果。如果你有两个段落并调用wrapAll()它们都被包裹在一个div中。例如: divpHey/ppHello/p /div$(p).wrapAll(div /); 给你: divdivpHey/ppHello/p/div /div 如果您需要在整个元素组周围添加新的包含元素这将非常有用。 最后一个 wrap 函数是wrapInner()将每个元素的内容包装在新元素中。例如前面运行的 HTML 结构 $(p).wrapInner(strong /); 给你: div pstrongHey/strong/p pstrongHello/strong/p /div DOM 插入内部 DOM InsertionInside 方法允许您获取 DOM 中的现有元素并在其中添加元素。jQuery 文档( http://api.jquery.com/category/manipulation/dom-insertion-inside/ )对此做了最好的总结:“这些方法允许我们在现有元素中插入新内容。” 这里有六种方法(您已经见过其中两种): append()appendTo()html()prepend()prependTo()text() 您已经看到并使用了html()和text()所以我们将跳过这一部分。你大概可以猜到prepend()和append()(以及“To”版本)做的事情非常相似这里没有太多要说的。你可能会发现自己经常使用append()和prepend()所以理解这些例子很重要。 非常简单。你给它传递一个新元素或者一些 HTML它把它添加到集合中每个元素的末尾。最好用一个例子来解释假设您有三个空的div元素: div/div div/div div/div 并运行: var p $(p /, {text : Hello }); $(div).append(p) 因此DOM 现在看起来像这样每个div包含一个新段落: divpHello/p/div divpHello/p/div divpHello/p/div 需要注意的是append()在元素的最后添加内容在所有其他元素之后。从这里你大概可以猜到prepend()会在开头插入元素在所有其他元素之前。取一个已经包含一些内容的div运行prepend()会在该内容之前插入新元素而append()会将其放在该内容之后。以前面 HTML 中的这个div为例: divpHello/p/div 如果您随后运行相同的 jQuery 代码片段但是更改了段落中的文本: var p $(p /, {text : Howdy }); $(div).append(p) 你会看到: divpHello/ppHowdy/p/div 但是如果你跑了: var p $(p /, {text : Howdy }); $(div).prepend(p) 你会看到: divpHowdy/ppHello/p/div prependTo()和appendTo()只是一种不同的代码编写方式。使用append()您选择元素然后向其添加内容而appendTo()执行相反的操作。例如: pHowdy/p$(stronghello/strong).appendTo(p) 给你: pHowdystronghello/strong/p appendTo()接受一个参数它可以是任何 CSS 选择器或 jQuery 对象。因此您可以使用以下代码获得相同的结果: var p $(p); $(strongHello/strong).appendTo(p); 这些在prependTo中也能很好地工作(这两种方法在这方面完全相同)。例如: var p $(p); $(strongHello/strong).prependTo(p); 结果如下: pstrongHello/strongHowdy/p DOM 插入外部 这些方法允许您在其他元素之外插入内容。这里有四种方法但实际上只有两种因为它们是完全相反的就像prepend()和append(): after()before()insertAfter()insertBefore() after()用于在你的集合中的元素后插入内容。例如: divpHello/p/div$(p).after(spanHey/span); 会给你: divpHello/pspanHey/span/div 如果你要做: $(p).before(spanHey/span); 你会得到: divspanHey/spanpHello/p/div 从这里开始根据您在上一节中所做的您大概可以猜出insertAfter()是做什么的。这只是一种不同的语法: $(spanHey/span).insertAfter(p); $(spanHey/span).insertBefore(p); 我们倾向于使用这种语法— prependTo()、insertAfter()等等—比其他语法多得多。这主要是因为使用一种方法其中您想要插入的东西是代码中的“第一个”您可以创建新元素并更容易地插入它们。例如这个: $(p /, {text: Hello }).insertAfter(p); 比这个好得多: var p $(p /, {text: Hello }) $(p).after(p); 在本书的后续练习中我们将倾向于使用insertAfter()、appendTo()等但是如果您喜欢这样做可以随意交换它们。 有效的 DOM 插入 在继续第五章中的事件之前我们想花点时间讨论一下效率。正如我们已经提到的DOM 操作是昂贵的。相对于您将要编写的大多数 JavaScript移除、操作或插入 DOM 元素将是最慢的部分。我们看到人们低效使用它的最常见的例子是当他们在一个循环中插入大量内容时。假设您想要生成一个由 1 到 10 的数字组成的无序列表并且您决定在一个循环中执行这个操作是一个很好的方法。你可以这样做。为这个练习创建一个新文件夹并设置通常的结构一个index.html文件和一个app.js文件其中只包含 $(function() { }); 喜欢的话可以加个style.css做造型。以下是列出清单的初步尝试: $(function() {var i 0;var newUl $(ul /).appendTo(body);while( i 10 ) {$(li /, {text : i1}).appendTo(newUl);i;} }); 以下是步骤: 创建一个新的无序列表并将其添加到body元素中。然后循环十次。在循环中创建一个新的列表项并将其添加到无序列表中。将文本值设置为 i1因此列表项显示为 1–10而不是 0–9。 您可能认为这很好但是在这段代码中您将插入 DOM 次——一次插入列表一次插入每个列表项。那是一笔巨款。如果你制作无序列表会更好但是不要把它插入到 DOM 中。然后将每个列表项添加到这个无序列表中并将整个列表项插入到 DOM 中将 DOM 插入的数量从 11 个减少到 1 个。这很容易做到: $(function() {var i 0;var newUl $(ul /);while( i 10 ) {$(li /, {text : i1}).appendTo(newUl);i;}newUl.appendTo(body); }); 这里的关键是在循环完成之前不要将无序列表追加到主体中。在将元素添加到 DOM 之前可以创建一个元素并向其中添加元素。那是做这件事的最好方法。您仍然将每个列表项追加到无序列表中但是这不是一个 DOM 插入因为这个无序列表没有被添加到 DOM 中。只是在最后才加上的。在写这篇文章的时候我们很好奇这会带来多大的不同我们发现在循环中插入比在末尾插入慢 45%到 60%。当然在这种情况下差异要小得多因为您只插入了十个元素但是您应该始终致力于生成高效的代码并且注意像这样的情况是其中的一大部分。 摘要 在一章的篇幅中涵盖了大量内容。现在您可以操纵 DOM 了与一章前相比您可以做更多的事情。接下来您将了解事件以及如何编写基于用户交互执行的代码。您还将构建一个手风琴将事件和 DOM 操作放在一起。
http://www.tj-hxxt.cn/news/133868.html

相关文章:

  • 东三省网站建设公司wordpress 首页模版
  • 建一个网站难不难服务好的南京网站建设
  • 专做老酒的网站济南网站建设行知科技不错
  • 网站建设360搜索引擎广告图片
  • 大型网站系统图wordpress 做一个视频站
  • 关于网站备案前置审批的相关说明 吉林一站式服务广告语
  • 北京网站设计公司哪儿济南兴田德润简介网站设计与推广
  • 网站建设与管理适合女生学吗江苏省建设厅 标准化网站
  • 协会网站方案广州腾虎网络网站建设熊掌号
  • 外贸网站建设模式株洲网站优化找哪家
  • 怎么创建网站赚钱dede网站怎么做404页面
  • 怎么在云服务器上搭建网站t恤在线制作网站
  • 网站建设分为多少模块我市建设车辆违章查询网站 病句
  • 网站建设所需要的软件十大难进的互联网公司
  • 郑州网站建设企业推荐我有云服务器如何建站
  • 建设网站手机版怎么看一级还是二级域名
  • 重庆官方网站建设导入表格数据做地图网站
  • 学习网站开发心得体会学校网站的建设论文
  • 黄页网站怎么查wordpress主题手动安装
  • 网站模板定制app产品开发公司
  • 网站制作优化全包湖南企业seo优化报价
  • 怎么给网站做网站地图南京工程造价信息网
  • 做网站需要什么开发语言网站开发属于哪个税收分类
  • 重庆企业网站推广平台营销网站建设哪里好薇
  • 网站源码是什么龙岗网站设计资讯
  • 内江网站建设公司甘肃省城乡住房建设厅网站首页
  • 四川住房城乡建设厅官方网站公司网站建设代理
  • 看电视剧的免费网站大全手机企业网站制作
  • 网站设计模板是什么陕西省建设银行分行网站
  • 献县做网站价格三七游戏官网