S05-01 Library-jQuery
[TOC]
jQuery 概述
jQuery
jQuery 官网:https://jquery.com/
jQuery(/ˈdʒeɪkwɪəri/ ):是一个快速、小型且功能丰富的 JS 库。它的设计宗旨是“Write Less, Do More”(写得更少,做得更多)。
你可以把它理解为 JS 的一个“工具箱”,它封装了大量常用的、但用原生 JS 写起来很复杂的功能(比如 DOM 操作、事件处理、动画、Ajax 等),提供了一个非常简单易用的 API。这使得开发者可以用更少的代码完成更多的工作,并且无需担心不同浏览器之间的兼容性问题。
- 使 HTML 文档遍历、操作、事件处理、动画和 Ajax 之类的事情变得更加简单。
- 具有易于使用的 API,可在多种浏览器中使用。
- jQuery 结合多功能性和可扩展性,改变了数百万人编写 JS 的方式。
库和框架
随着 JS 的普及,以及越来越多人使用 JS 来构建网站和应用程序
- JS 社区认识到代码中存在非常多相同的逻辑是可复用的。
- 因此社区就开始对这些相同逻辑的代码封装到一个 JS 文件中。
- 这个封装好的 JS 文件就可称为 JS 库或 JS 框架。
库(Library):是一个预先编写好并实现了一些特定功能的代码片段的集合。
- 一个库中会包含许多的函数、变量等,可根据需求引入到项目中使用。
- 常见的库:jQuery、Day.js、Lodash 和 React 等
框架(Framework):是一个完整的工具集,可帮助塑造和组织您的网站或应用程序。
- 提供一个结构来构建整个应用程序,开发人员可以在结构的规则内更安全、更高效地工作。
- 常见的框架:Bootstrap、Angular、Vue、Next.js 等。
jQuery 优缺点
jQuery 的优点:
- 易于学习:相对于其它的前端框架,jQuery 更易于学习,它支持 JS 的编码风格。
- 少写多做(Write less, do more):
- jQuery 提供了丰富的功能(DOM 操作、过滤器、事件、动画、Ajax 等)。
- 可以编写更少可读的代码来提高开发人员的工作效率。
- 优秀的 API 文档:jQuery 提供了优秀的在线 API 文档。
- 跨浏览器支持:提供出色的跨浏览器支持(IE9+),无需编写额外代码。
jQuery 的缺点:
- 代码库一直在增长:自 jQuery 1.5 起超过 200KB
- 不支持组件化开发
- 复杂项目支持差:jQuery 更适合 DOM 操作,当涉及到开发复杂的项目时,jQuery 能力有限。
示例:原生 vs jQuery
原生:
jQuery:
jQuery 历史
jQuery 历史:
在 2005 年 8 月 22 日,John Resig 首次提出支持 CSS 选择器的 JS 库,语法比现有库(Behaviour)更简洁。
在 2006 年之前,John Resig(一名从事自己项目的 Web 开发人员)对编写跨浏览器的 JS 感到非常繁琐。
在 2006 年 1 月 16 日,John Resig 在 BarCamp 的演讲中介绍了他的新库( jQuery )。
之后 John Resig 又花了 8 个月的时间完善 jQuery 库,直到 2006-8-26 才发布了 1.0 版本。
原本打算使用 JSelect(JS Selectors)命名该库,但域名都已被占用。
jQuery 历史版本:
为什么学习 jQuery
jQuery 是一个非常受欢迎的 JS 库,被全球约 7000 万个网站使用。它优秀的设计和架构思想非常值得我们去学习。
jQuery 的座右铭是“Write less , do more”,它易于学习, 非常适合 JS 开发人员学习的第一个库。
前端 JS 库非常多,学习 jQuery 有利于我们学习和理解其它的 JS 库(例如:Day.js、Lodash.js 等)
许多大型科技公司,虽然他们现在不会直接使用 jQuery 来做项目,但在项目中仍然会借鉴很多 jQuery 设计思想。
因此,了解 jQuery 依然是一个好主意。
基本使用
CDN
CDN(内容分发网络,Content Delivery Network, Content Distribution Network):可以把它想象成一个由众多分布在全球各地的服务器组成的网络。它的主要任务是把网站或应用的内容(比如图片、视频、样式文件等)拷贝并存放在这些服务器上。当用户想要访问这些内容时,CDN 会智能地将用户的请求引导到离他地理位置最近或者响应最快的服务器上,从而提升访问速度,减轻原始服务器的压力。
- 简单理解:CDN 会将网站资源缓存到遍布全球的服务器,用户请求获取资源时,可就近获取 CDN 上缓存的资源,提高资源访问速度,同时分担源站压力。
常用 CDN 分类:
常用的 CDN 服务可以大致分为两种:
- 购买的 CDN 服务:需要购买开通 CDN 服务(会分配一个域名)。
- 目前阿里、腾讯、亚马逊、Google 等都可以购买 CDN 服务。
- 开源的 CDN 服务:
安装
jQuery 本质是一个 JS 库。
- 核心功能:该库包含了:DOM 操作、选择器、事件处理、动画和 Ajax 等核心功能。
- 现在我们可以简单的理解它就是一个 JS 文件。
- 执行该文件会给 window 对象添加一个 jQuery 函数(例如:
window.jQuery
)。 - 接着我们就可以调用 jQuery 函数,或者使用该函数上的类方法。
jQuery 安装方式:
下面我们来看看 jQuery 安装方式有哪些:
方式 1:CDN:
在页面中,直接通过 CDN 的方式引入。
方式 2:下载源码引入:
下载 jQuery 的源文件,并在页面中手动引入。
方式 3:包管理器:
使用 npm 包管理工具安装到项目中(npm 在 Node 基础阶段会讲解)
方式 1:CDN
CDN 方式引入:
当执行完以下代码后会给 window 对象添加 jQuery
和 $
函数对象。
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
示例:简单的 CDN 引入
实现一个 Hello jQuery 的案例:
示例:严谨的 CDN 引入
integrity
:防止资源被篡改,如果浏览器发现资源被篡改,就不会加载该资源。crossorigin
:加载不同源的资源时,浏览器是否需要携带用户凭证信息(cookie、ssl证书等)anonymous
:不需要携带user-credential
:需要携带
方式 2:下载源码引入
源码下载地址:
- 官网下载:https://jquery.com/download/
- CDN 下载:https://releases.jquery.com/jquery/
- GitHub 下载:https://github.com/jquery/jquery
示例:下载源码引入
下面使用源码的方式引入 jQuery:
方式 3:包管理器
使用 npm 安装 jquery 到项目中(npm 在 Node 基础阶段会讲解)
npm install jquery
# 或
yarn add jquery
基本使用
示例:jQuery 基本使用-计数器
原生实现:
jQuery 实现:
监听文档加载
$.ready():(handler)
,jQuery 中用来指定一个在 DOM 文档对象模型完全加载并解析后执行的函数。无需等待所有图像、视频等外部资源完全加载。
handler:
function
,当 DOM 准备就绪后要执行的函数。返回:
jq:
jQuery
,返回一个 jQuery 对象(具体来说是调用.ready()
的那个 jQuery 对象,即$(document)
)。
上述计数器代码中,如果 script 标签在计数器元素之前的话,会获取不到这些元素。
这就需要我们使用监听文档加载完毕的事件来解决。
监听文档加载的方式:
原生方式:
- 监听 document 的
DOMContentLoaded
事件:推荐
- 监听 document 的
jQuery 方式:
监听 document 的
DOMContentLoaded
事件:$(handler)
:推荐,其它方式可以使用但不推荐$(document).ready(handler)
: 已废弃$("document").ready(handler)
: 已废弃$().ready(handler)
:已废弃
监听 window 的
load
事件:$(window).on('load', handler)
: 推荐$(window).load(handler)
: 3.0 中废弃
示例:jQuery 监听 DOMContentLoaded 的方式
示例:监听文档加载
原生方式:
jQuery 方式-监听 DOMContentLoaded 事件:
jQuery 方式-监听 load 事件:
变量名冲突
$.noConflict():(removeAll?)
,用于放弃 jQuery 对 $
变量的控制权,并将其归还给先前拥有的库。用于解决和第三方库之间 $
和jQuery
变量的命名冲突。
removeAll?:
boolean
,默认:false
,用于指示是否同时放弃对jQuery
变量的控制。false
:仅放弃$
变量的控制权。true
:同时放弃$
和jQuery
两个变量的控制权(极端情况使用)。
返回:
$jq:
jQuery
,返回 jQuery 对象本身(即 jQuery 这个函数/对象)。
变量名冲突:
和 jQuery 库一样,许多 JS 库也会使用 $ 作为函数名或变量名。
在 jQuery 中,$ 是 jQuery 的别名。
如果我们在使用 jQuery 库之前,其它库已经使用了$ 函数或者变量,这时就会出现冲突的情况。
解决方案:调用 jQuery.noConflit()
解决冲突
调用 noConflit()
释放 jQuery 对全局变量 $
或 jQuery
的控制权,转而使用它返回的对象操作 jQuery。
源码:noConflict():
jQuery 在初始化前会先备份一下全局其它库的 jQuery 和 $ 变量。
调用 noConflict 函数只是恢复之前备份的 jQuery 和 $ 变量。
jQuery 函数对象
jQuery 函数
jQuery():(多态)
,工厂函数,是 jQuery 库的基石,几乎所有 jQuery 功能都始于对这个函数的调用。
jQuery():
(selector, context?)
,用于选择 DOM 元素。selector:
string
,包含 CSS 选择器的字符串,用于查找匹配的 DOM 元素。context?:
DOM|Document|jQuery
,默认:document
,搜索的上下文(起点)。js// 1. 在整个文档中选择所有 <p> 元素 $('p'); // 2. 在 #container 元素内选择所有 .item 元素 $('.item', '#container'); // 等价于: $('#container').find('.item');
jQuery():
(html, ownerDocument?)
,用于创建新的 DOM 元素。html:
string
,一个描述单个独立元素的 HTML 字符串(例如,<div>
、<span>
等)。关键点:如果 HTML 字符串的开头有空格,它会被解释为选择器;如果没有空格,则被解释为创建新元素。
$(' <div>')
→ 选择元素(注意开头的空格)$('<div>')
→ 创建元素$('div')
→ 选择所有现有的<div>
元素
ownerDocument?:
DOM|Document|jQuery
,默认:document
,用于创建新元素的文档对象。js// 1. 创建一个新的 div 元素 $('<div>'); // 2. 创建一个带有内容和属性的 li 元素 $('<li>', { text: 'New List Item', class: 'new', id: 'list-item-1' }); // 3. 创建更复杂的嵌套结构 $('<div><p>Hello <strong>World</strong></p></div>');
jQuery():
(callback)
,当传入一个函数时,该函数会被注册为 DOM 准备就绪后的执行函数。callback:
()=>void
,当 DOM 完全加载并解析后要执行的函数。js// 1. 标准写法 $(document).ready(function() { // DOM 已就绪,可以安全操作 }); // 2. 简写写法(功能完全相同) $(function() { // DOM 已就绪 });
jQuery():
(el | els | obj)
,用于将原生 DOM 元素或元素数组包装成一个 jQuery 对象,以便使用 jQuery 的方法。el:
Element
,一个原生的 DOM 元素。els:
array
,一个包含 DOM 元素的数组(或类数组对象,如NodeList
)。obj:
object
,一个普通的 JS 对象(不常用)。js// 1. 包装一个原生 DOM 元素 var nativeElement = document.getElementById('myId'); var $jqueryElement = $(nativeElement); // 现在可以使用 .css(), .hide() 等方法 // 2. 包装一个元素数组 var nativeElements = document.getElementsByTagName('div'); var $jqueryCollection = $(nativeElements); // 将 HTMLCollection 转换为 jQuery 对象 // 3. 包装一个普通对象(不常用,主要用于附加数据等特殊操作) var myObject = { name: 'John', age: 30 }; $(myObject).on('customEvent', function() { ... });
jQuery():
($el)
,当传入一个 jQuery 对象时,会返回该对象的副本。$el:
jQuery
,一个现有的 jQuery 对象。js// 创建一个新的、独立的 jQuery 对象 var $original = $('div'); var $copy = $( $original );
返回:
$els:
jQuery
,几乎总是返回一个新的 jQuery 对象。
源码:jQuery():
jQuery
和jQuery.fn.init
共享一个原型对象可以通过
new jQuery.prototype.init()
返回一个 jQuery 对象实例实现
jQuery.prototype.init()
构造方法
jQuery 对象
jQuery 对象:是一个包含一个或多个 DOM 元素的特殊 JS 对象,它附加了 jQuery 提供的所有方法和功能。
- jQuery 对象是通过调用 jQuery 函数来创建的。
- jQuery 对象中会包含 N(>=0)个匹配到的元素。
- jQuery 对象原型中包含了很多已封装好的方法。例如:DOM 操作、事件处理、动画等方法。
示例:
创建空 jQuery 对象
jsconst $jq = jQuery()
创建匹配 document 元素的 jQuery 集合对象
jsconst $jq = jQuery(document)
创建匹配多个 li DOM 元素的 jQuery 集合对象
jsconst $jq = jQuery('ul li') // 没有上下文参数,默认为上下文为 document const $jq = jQuery('ul li', document.querySelector('div')) // 有上下文参数
对比 DOMElement
对比 DOMElement:
jQuery 对象与 DOM 对象的区别
特性 | jQuery 对象 | DOM 对象 |
---|---|---|
类型 | 自定义对象,类数组结构 | 浏览器原生对象 |
创建方式 | $('selector') 或 $(DOMElement) | document.getElementById() 等 |
方法 | 可使用所有 jQuery 方法 | 只能使用原生 DOM 方法 |
空对象处理 | 安全,调用方法不会报错 | 可能引发错误 |
链式调用 | 支持 | 不支持 |
与 DOMElement 的转换
jQuery 对象转 DOMElement:
方法 1: 使用索引
只能获取到某一个元素
jsconst firstDiv = $divs[0]
方法 2: 使用
get()
方法可以获取到所有 DOM 元素
$els.get():
(index?)
,工具方法,用于从 jQuery 对象中获取底层的 DOM 元素。可以将 jQuery 对象转换回原生 DOM 元素。jsconst firstDiv = $divs.get(0) // 返回集合中的第一个 DOM 元素 const divs = $divs.get() // 返回集合中的所有 DOM 元素
方法 3: 直接操作单个元素
js$('#myElement').click(function () { // this 指向 DOM 元素 console.log(this.id) // 需要时再包装成 jQuery 对象 $(this).addClass('clicked') })
DOMElement 转 jQuery 对象:
方式 1:调用
jQuery(dom)
jsvar div = document.getElementById('myDiv') var jQueryDiv = jQuery(div)
方式 2:使用
$(dom)
包装jsvar div = document.getElementById('myDiv') var jQueryDiv = $(div)
链式调用
jQuery 原型上的方法大部分都支持链式调用。
链式调用原理:因为 jQuery 原型方法会返回 jQuery 对象。
jQuery 架构设计图
jQuery 架构设计图:
在开始学习 jQuery 语法之前,我们先来了解一下 jQuery 的架构设计图。
选择器/过滤器
jQuery 选择器
jQuery 函数支持大部分的 CSS 选择器(Selectors)。
语法:
jQuery('selector')
// 或
$('selector')
选择器:
原生 CSS 选择器:
通配符选择器:
*
基本选择器:
id
、class
、元素
属性选择器:
[attr]
、[atrr="value"]
后代选择器:
div > span
、div span
兄弟选择器:
div + span
、div ~ span
交集选择器:
div.container
伪类选择器:
:nth-child()
、:nth-of-type()
、:not()
注意:不支持链接伪类
:hover
、:focus
...内容选择器:
:empty
(指选中的元素没有子元素或文本):has(selector)
(指选中的元素是否存在某个子元素)
jQuery 扩展的选择器:
- 可见选择器:
:visible
、:hidden
- 结构伪类选择器(已废弃):
:eq()
、:odd
、:even
、:first
、:last
示例:
原生选择器
jQuery 扩展的选择器
生成代码片段
代码片段在线生成网站:https://snippet-generator.app/
代码片段模板:
jQuery 过滤器
常用的 jQuery 过滤器方法:
- $els.eq():
(index|indexFromEnd)
,过滤器,用于从当前匹配的元素集合中根据索引筛选出指定位置的元素,并将其封装为一个新的 jQuery 对象。 - $els.first():
()
,等价:.eq(0)
,过滤器,用于从当前匹配的元素集合中筛选出第一个元素,并将其封装为一个新的 jQuery 对象。 - $els.last():
()
,等价:.eq(-1)
,过滤器,用于从当前匹配的元素集合中筛选出最后一个元素,并将其封装为一个新的 jQuery 对象。 - $els.not():
(selector)
,过滤器,用于从当前匹配的元素集合中筛选出不符合指定条件的元素,返回一个新的 jQuery 对象。 - $els.filter():
(selector)
,过滤器,用于从当前匹配的元素集合中筛选出符合指定条件的元素,返回一个新的 jQuery 对象。 - $els.find():
(selector)
,遍历方法,用于在当前匹配元素集合的后代元素中查找与指定选择器匹配的元素。 - $els.is():
(selector)
,过滤器,用于检查当前匹配的元素集合中是否有至少一个元素与指定的选择器、元素、jQuery 对象或判断函数相匹配。 - $els.odd():
()
,过滤器,用于从当前匹配的元素集合中筛选出索引值为奇数的元素。是.filter()
方法的一个便捷替代。 - $els.even():
()
,过滤器,用于从当前匹配的元素集合中筛选出索引值为偶数的元素。是.filter()
方法的一个便捷替代。
示例:
eq() / first() / last():
not():
odd() / even():
filter():
文本操作
$els.text():
()
,文本操作,用于获取或设置匹配元素的文本内容。$els.text():
()
,获取文本内容。$els.text():
(textContent)
,设置文本内容。
$els.html():
()
,文本操作,用于获取或设置匹配元素的 HTML 内容。$els.html():
()
,获取 HTML 内容。$els.html():
(htmlContent)
,设置 HTML 内容。
$els.val():
()
,文本操作,用于获取或设置表单元素的值。$els.val():
()
,获取元素值。$els.val():
(value)
,设置元素值。
对比文本操作相关方法:
方法 | 描述 | 处理内容 | 安全性 |
---|---|---|---|
.text() | 获取或设置元素的文本内容 | 纯文本,HTML 会被转义 | 高,防止 XSS 攻击 |
.html() | 获取或设置元素的 HTML 内容 | HTML 代码,会被解析 | 低,可能引入 XSS 风险 |
.val() | 获取或设置表单元素的值 | 表单字段的值 | 取决于内容 |
<div id="content">
<p>这是第一个<strong>加粗</strong>段落。</p>
<p>这是第二个<span style="color: red;">红色</span>段落。</p>
</div>
<form id="myForm">
<input type="text" id="username" value="john_doe">
</form>
// .text() 忽略 HTML 标签,只处理文本内容
$('#content').text();
// 结果: 这是第一个加粗段落。这是第二个红色段落。
// .html() 包含所有子元素的完整 HTML(包括标签),
$('#content').html();
// 结果:
// <p>这是第一个<strong>加粗</strong>段落。</p>
// <p>这是第二个<span style="color: red;">红色</span>段落。</p>
// .val() 专门处理表单元素的值
$('#username').val() // 结果: "john_doe"
CSS 操作
样式操作
$els.css():
(propertyName|properties,value?)
,样式操作,用于获取或设置一个或多个 CSS 属性值。$els.css():
(propertyName)
,获取样式值(Getter)。$els.css():
(propertyName, value)
,设置单个样式(Setter)。$els.css():
(properties)
,设置多个样式(Setter)。
核心特性:
获取的是计算值:
而不是在样式表中设置的值。这意味着:
- 它会返回实际渲染的值(如
100px
而不是100
) - 它会解析相对值(如百分比、em等)
- 它会应用所有继承和层叠的样式规则
- 它会返回实际渲染的值(如
处理浏览器前缀
jQuery 会自动处理一些需要浏览器前缀的 CSS 属性。
js// jQuery 会自动处理浏览器前缀 $('div').css('transform', 'rotate(45deg)'); // 实际可能会设置为: -webkit-transform, -moz-transform, -ms-transform, transform
获取值的限制:
.css()
只能获取第一个元素的值,如果需要所有元素的值,需要使用.map()
或循环。jsvar allWidths = $('div').map(function() { return $(this).css('width'); }).get();
CSS权重:
通过
.css()
设置的样式具有最高优先级(相当于内联样式),会覆盖外部CSS和<style>
标签中的样式。
元素尺寸
$els.width():
(value?)
,元素尺寸,用于获取或设置匹配元素集合中第一个元素的内容区域宽度(不包含内边距、边框和外边距)。$els.width():
()
,获取宽度(Getter)。$els.width():
(value)
,设置宽度(Setter)。
$els.height():
(value?)
,元素尺寸,用于获取或设置匹配元素集合中第一个元素的内容区域高度(不包含内边距、边框和外边距)。$els.height():
()
,获取高度(Getter)。$els.height():
(value)
,设置高度(Setter)。
$els.innerWidth():
(value?)
,元素尺寸,用于获取匹配元素集合中第一个元素的内容区域宽度加上内边距的宽度(不包含边框和外边距)。$els.innerWidth():
()
,获取内部宽度(Getter)。$els.innerWidth():
(value)
,设置内部宽度(Setter) - 注意:此用法有限制。
$els.innerHeight():
(value?)
,元素尺寸,用于获取匹配元素集合中第一个元素的内容区域高度加上内边距的高度(不包含边框和外边距)。$els.innerHeight():
()
,获取内部高度(Getter)。$els.innerHeight():
(value)
,设置内部高度(Setter) - 注意:此用法有限制。
$els.outerWidth():
(includeMargin?|value)
,元素尺寸,用于获取匹配元素集合中第一个元素的内容宽度加上内边距和边框的宽度。通过可选参数,还可以包含外边距。$els.outerWidth():
(includeMargin?)
,获取外部宽度(Getter)。$els.outerWidth():
(value)
,设置外部宽度(Setter) - 注意:此用法有限制。
$els.outerHeight():
(includeMargin?|value)
,元素尺寸,用于获取匹配元素集合中第一个元素的内容高度加上内边距和边框的高度。通过可选参数,还可以包含外边距。$els.outerHeight():
(includeMargin?)
,获取外部高度(Getter)。$els.outerHeight():
(value)
,设置外部高度(Setter) - 注意:此用法有限制。
核心特性:
尺寸方法对比:
jQuery 提供了一系列相关的尺寸方法,理解它们的区别很重要,高度相关方法与此类似:
方法 描述 计算内容 .width()
获取/设置内容宽度 仅内容区域 .innerWidth()
获取内容+内边距宽度 内容 + padding .outerWidth()
获取内容+内边距+边框宽度 内容 + padding + border .outerWidth(true)
获取内容+内边距+边框+外边距宽度 内容 + padding + border + margin js// 假设一个div有以下样式: // width: 200px; padding: 15px; border: 3px solid; margin: 10px; var width = $('div').width(); // 200 (仅内容) var innerWidth = $('div').innerWidth(); // 230 (内容 + 左右内边距: 200 + 15 + 15) var outerWidth = $('div').outerWidth(); // 236 (内容 + 左右内边距 + 左右边框: 200 + 30 + 6) var outerWidthWithMargin = $('div').outerWidth(true); // 256 (加上左右外边距: 236 + 20)
设置宽度-注意事项:
在设置
innerWidth()
/outerWidth()
等时虽然语法上支持,但实际上设置的是内容宽度,更推荐通过width()
设置(高度同理):js// 设置"内部宽度"为300像素(实际上设置的是内容宽度) $('div').innerWidth(300); // 实际效果:设置内容宽度为300px,保持内边距不变 // 元素的总宽度变为:300 + 左内边距 + 右内边距
js// 设置"外部宽度"为300像素(实际上设置的是内容宽度) $('div').outerWidth(300); // 实际效果:设置内容宽度为300px,保持内边距和边框不变 // 元素的总宽度变为:300 + 左内边距 + 右内边距 + 左边框 + 右边框
对比
.css('width')
:特性 .width()
.css('width')
获取值 返回 number
类型的宽度值(不带单位)返回 string
类型的宽度值(带单位,计算值)设置值 传入 number
类型的值(不带单位)需明确指定单位 js// 获取值对比 var widthNum = $('div').width(); // 返回: 200 (数字) var widthStr = $('div').css('width'); // 返回: "200px" (字符串) // 设置值对比 $('div').width(200); // 简洁,自动添加px $('div').css('width', '200px'); // 需要明确指定单位
隐藏元素的宽度:
对于
display: none
的元素,.width()
返回0
。如果需要获取隐藏元素的潜在宽度,可以先临时显示它:jsvar $element = $('#hiddenElement'); var originalDisplay = $element.css('display'); $element.css('display', 'block'); // 临时显示 var width = $element.width(); $element.css('display', originalDisplay); // 获取宽度后,设置回去
盒子模型的影响:
.width()
总是返回内容宽度,不受box-sizing
属性的影响。性能考虑:获取元素尺寸会触发浏览器的重排(reflow),
- 需避免在循环或频繁调用的函数中大量使用。
- 如果需要多次获取同一元素的尺寸,应该缓存结果。
元素位置
$els.offset():
(coordinates?|fn?)
,元素位置,用于获取或设置匹配元素集合中第一个元素相对于文档(document)的当前坐标。$els.offset():
()
,获取位置(Getter)。$els.offset():
(coordinates|fn)
,设置位置(Setter)
$els.position():
()
,元素位置,只读,用于获取匹配元素集合中第一个元素相对于偏移父元素(offset parent)的当前坐标。$els.scrollTop():
(value?)
,元素位置,用于获取或设置匹配元素集合中第一个元素的垂直滚动条位置。$els.scrollTop():
()
,获取滚动位置(Getter)。$els.scrollTop():
(value)
,设置滚动位置(Setter)。
核心特性:
.offset()
对比.position()
:理解
.offset()
和.position()
的区别非常重要:特性 .offset()
.position()
参考点 相对于文档(document) 相对于最近的定位父元素(positioned ancestor) 可设置性 可以设置新位置 不能设置新位置(只读) 包含外边距 包含元素的外边距 不包含元素的外边距 滚动影响 不受滚动位置影响(相对于文档固定) 受滚动位置影响 js// 假设一个元素在可滚动的容器中 var offset = $('#element').offset(); // 相对于文档 var position = $('#element').position(); // 相对于最近的定位祖先 console.log('相对于文档: ', offset); console.log('相对于定位祖先: ', position);
返回值不带单位:
上述 3 种方法获取到的尺寸都是数字类型,不带单位。
.offset()
设置位置的要求:要使用
.offset()
设置位置,元素必须具有position: absolute
,position: relative
或position: fixed
。如果元素没有设置定位,jQuery 会自动将其设置为
position: relative
。滚动容器的影响:
.offset()
返回的是相对于文档的位置,不考虑滚动容器的偏移。如果需要相对于滚动容器的位置,可以使用
.position()
或手动计算。偏移父元素:
偏移父元素是指最近的定位祖先元素(position 值为 relative、absolute、fixed 或 sticky 的元素)。如果没有这样的元素,则偏移父元素是
<body>
。隐藏元素:
如果元素是隐藏的(
display: none
),.position()
/.offset()
返回的值可能不准确或为{top: 0, left: 0}
。
属性操作
class 属性
$els.addClass():
(className|fn)
,类名操作,用于向匹配元素集合中的每个元素添加一个或多个 CSS 类。$els.addClass():
(className)
,字符串参数,添加一个或多个类。$els.addClass():
(fn)
,函数参数,通过函数动态添加类。
$els.hasClass():
(className)
,类名操作,只读,用于检查匹配元素集合中的任何一个元素是否包含指定 CSS 类。$els.removeClass():
(className?|fn)
,类名操作,用于从匹配元素集合中的每个元素移除一个或多个 CSS 类。$els.removeClass():
()
,无参数,移除所有类。$els.removeClass():
(className?)
,字符串参数,移除一个或多个类。$els.removeClass():
(fn)
,函数参数,通过函数动态移除类。
$els.toggleClass():
(className|fn,state?,switch?)
,类名操作,用于动态操作 CSS 类的重要方法,允许在元素上切换(添加或移除)一个或多个 CSS 类。$els.toggleClass():
(className)
,切换单个或多个类。$els.toggleClass():
(className, state)
,根据条件切换类。$els.toggleClass():
(fn)
,使用函数动态决定切换。$els.toggleClass():
(className, state, switch?)
,切换多个类。
核心特性:
- CSS 特异性:通过上述class属性添加的类遵循 CSS 的特异性规则。
- 类名格式:
- 类名区分大小写,应与CSS中的类名完全一致。
- 不需要包含前导点号(
.
)。
- 多个类名:多个类名之间用空格分隔。
- 对比原生 class 方法:
- el.classList:
DOMTokenList
,只读,返回该元素包含的所有 class 属性。 - el.classList.add():
(className)
,添加一个类。 - el.classList.contains():
(className)
,检查是否存在指定类。 - el.classList.remove():
(className)
,移除一个类。 - el.classList.toggle():
(className)
,如果类不存在就添加类,存在就移除该类。 - el.classList.replace():
(oldClass, newClass)
,将旧类名替换成新类名。
- el.classList:
源码:class 属性:
attr 属性
$els.attr():
(attributeName|attributes,value?)
,HTML 属性操作,用于获取或设置匹配元素集合中第一个元素的属性值。$els.attr():
(attributeName)
,获取属性值(Getter)。$els.attr():
(attributeName,value)
,设置单个属性(Setter)。$els.attr():
(attributes)
,设置多个属性(Setter)。
$els.removeAttr():
(attributeName)
,HTML 属性操作,用于从匹配元素集合中的每个元素移除一个或多个指定的 HTML 属性。
核心特性:
对比
.prop()
:一般规则:
- 对于自定义属性和标准HTML属性,使用
.attr()
- 对于布尔属性(
checked
,selected
,disabled
等)和 JS 动态属性,使用.prop()
特性 .attr()
.prop()
操作目标 HTML 属性(attribute) JavaScript 属性(property) 值类型 总是返回字符串 返回属性的实际类型(布尔值、数字等) 适用场景 自定义属性、标准HTML属性 布尔属性、JavaScript动态属性 示例 $('input').attr('data-id')
$('input').prop('checked')
js// 对于复选框 var checkbox = $('#myCheckbox'); // .attr() - 操作HTML属性 console.log(checkbox.attr('checked')); // "checked" 或 undefined // .prop() - 操作JavaScript属性 console.log(checkbox.prop('checked')); // true 或 false
js// 正确设置复选框选中状态 checkbox.prop('checked', true); // 正确方式 checkbox.attr('checked', 'checked'); // 也能工作,但不是最佳实践
- 对于自定义属性和标准HTML属性,使用
使用时机:
- 使用
.prop()
的情况:- 布尔属性:
checked
,selected
,disabled
,readonly
,multiple
- 动态属性:
value
,selectedIndex
,defaultValue
- JavaScript原生属性:
tagName
,nodeName
,nodeType
,ownerDocument
- 布尔属性:
- 使用
.attr()
的情况:- 自定义HTML属性:
data-*
,aria-*
, 其他非标准属性 - 标准HTML属性:
id
,class
,src
,href
,title
,alt
- 自定义HTML属性:
js// 复选框示例 var $checkbox = $('#myCheckbox'); // .prop() - 操作JavaScript属性 $checkbox.prop('checked', true); // 设置为选中 var isChecked = $checkbox.prop('checked'); // true (布尔值) // .attr() - 操作HTML属性 $checkbox.attr('checked', 'checked'); // 添加checked属性 var hasCheckedAttr = $checkbox.attr('checked'); // "checked" (字符串)
js// 值属性示例 var $input = $('#myInput'); // .prop() - 获取当前值(可动态变化) $input.prop('value'); // 返回用户输入后的当前值 // .attr() - 获取初始值(不会变化) $input.attr('value'); // 返回HTML中设置的初始值
- 使用
标准属性和非标准属性:
prop 属性
$els.prop():
(propertyName|properties, value?)
,DOM 属性操作,用于获取或设置匹配元素集合中第一个元素的属性值。$els.prop():
(propertyName)
,获取属性值(Getter)。$els.prop():
(propertyName, value)
,设置单个属性(Setter)。$els.prop():
(properties)
,设置多个属性(Setter)。
$els.removeProp():
(propertyName)
,DOM 属性操作,用于从匹配元素集合中的每个元素移除通过.prop()
方法设置的 DOM 属性。
prop 的 JS 属性:
自定义 data-xx 属性
$els.data():
(obj|key,value)
,数据属性,用于在匹配的元素上存储或检索数据的方法。$els.data():
()
,读取所有数据。$els.data():
(key)
,读取特定键的值。$els.data():
(key,value)
,存储单个键值对数据。$els.data():
(obj)
,存储多个键值对数据。
$els.removeData():
(name|names)
,数据属性,用于移除通过.data()
方法存储在元素上的数据。$els.removeData():
()
,无参数,移除所有数据。$els.removeData():
(name)
,字符串参数,移除特定数据。$els.removeData():
(names)
,数组参数,移除多个数据。
核心特性:
HTML5 data-* 属性:
- jQuery 会自动读取元素上的
data-*
属性 - 通过
.data()
设置的值不会反映在 HTML 属性中 .removeData()
只移除通过.data()
方法存储的数据,不会影响 HTML5data-*
属性。- 数据类型会自动转换(字符串 "true" 变为布尔值 true,数字字符串变为数字等)
- jQuery 会自动读取元素上的
数据存储位置:
- 数据存储在 jQuery 的内部数据结构中,而不是 DOM 元素上
- 这避免了循环引用和内存泄漏问题
命名约定:
- 键名可以使用任何字符串,但应避免使用特殊字符
- jQuery 会自动将驼峰命名的键转换为连字符格式用于 HTML 属性
.data()
配合.removeData()
使用:.removeData()
通常与.data()
方法配合使用,一个用于存储数据,一个用于清理数据。
示例:
原生方式获取
data-*
数据jQuery方式获取
data-*
数据
DOM 操作
插入
$els.append():
(content|fn,...content?)
,DOM 插入,用于向匹配元素集合中的每个元素的内部末尾插入指定的内容。$els.append():
(content,...content?)
,插入内容。$els.append():
(fn)
,使用函数插入内容。
$els.prepend():
(content|fn,...content?)
,DOM 插入,用于向匹配元素集合中的每个元素的内部开头插入指定的内容。$els.prepend():
(content,...content?)
,插入内容。$els.prepend():
(fn)
,使用函数插入内容。
$els.after():
(content|fn,...content?)
,DOM 插入,用于在匹配元素集合中的每个元素后面插入指定的内容。$els.after():
(content,...content?)
,插入内容。$els.after():
(fn)
,使用函数插入内容。
$els.before():
(content|fn,...content?)
,DOM 插入,用于在匹配元素集合中的每个元素前面插入指定的内容。$els.before():
(content,...content?)
,插入内容。$els.before():
(fn)
,使用函数插入内容。
$els.appendTo():
(target)
,DOM 插入,用于将匹配元素集合中的每个元素插入到指定目标元素的内部末尾。$els.prependTo():
(target)
,DOM 插入,用于将匹配元素集合中的每个元素插入到指定目标元素的内部开头。$els.insertAfter():
(target)
,DOM 插入,用于将匹配元素集合中的每个元素插入到指定目标元素的后面。$els.insertBefore():
(target)
,DOM 插入,用于将匹配元素集合中的每个元素插入到指定目标元素的前面。
核心特性:
参数类型:
接受多种类型的内容参数:
js// 插入HTML字符串 $('#container').append('<div class="new-item">新项目</div>');
js// 插入DOM元素 var newElement = document.createElement('p'); newElement.textContent = '新创建的段落'; $('#container').append(newElement);
js// 插入文本内容 $('#container').append('纯文本内容');
js// 插入jQuery对象 var $newItem = $('<span>').text('动态创建的内容'); $('#container').append($newItem);
js// 插入多个内容 $('#container').append( '<h3>标题</h3>', '<p>段落内容</p>', $('<button>').text('按钮') );
对比相关方法:
方法 描述 插入位置 示例 .append()
在元素内部末尾插入内容 作为最后一个子元素 $('#div').append('<p>内容</p>')
.prepend()
在元素内部开头插入内容 作为第一个子元素 $('#div').prepend('<p>内容</p>')
.after()
在元素之后插入内容 作为下一个兄弟元素 $('#div').after('<p>内容</p>')
.before()
在元素之前插入内容 作为上一个兄弟元素 $('#div').before('<p>内容</p>')
html// 对比不同插入方法 <!-- .before() 会插入在这里 --> <div id="container"> <!-- .prepend() 会插入在这里 --> 现有内容 <!-- .append() 会插入在这里 --> </div> <!-- .after() 会插入在这里 -->
移动而非复制:如果插入的内容是页面上已经存在的元素,该元素会被移动到新位置,而不是被复制。
性能考虑:对大量元素使用可能会影响性能,在这种情况下,可以考虑使用文档片段(DocumentFragment)优化。
HTML 字符串解析:传入 HTML 字符串时,jQuery 会解析它并创建相应的 DOM 元素。要注意字符串中的特殊字符转义。
事件处理:插入的新元素不会自动继承原有的事件处理程序,除非使用事件委托。
.append()
对比.appendTo()
:两种方法实现相同效果,但语法不同
方法 语法 操作方向 返回对象 .append()
$(target).append(content)
目标.append(内容) 目标元素 .appendTo()
$(content).appendTo(target)
内容.appendTo(目标) 被插入的内容 js// 两种方法实现相同效果,但语法不同 // 使用 .append() - 以目标为主体 $('#container').append('<p>新段落</p>'); // 使用 .appendTo() - 以内容为主体 $('<p>新段落</p>').appendTo('#container'); // 两种方法最终的DOM结果相同: // <div id="container"><p>新段落</p></div>
移除
$els.remove():
(selector?)
,DOM 移除,用于从 DOM 中移除匹配元素集合中的所有元素,包括这些元素上的所有事件处理程序和 jQuery 数据。$els.remove():
()
,移除所有匹配元素。$els.remove():
(selector?)
,移除匹配特定选择器的元素。
$els.empty():
()
,DOM 移除,用于移除匹配元素集合中每个元素的所有子节点(包括文本节点和元素节点),但保留元素本身。
核心特性:
对比相关方法:
方法 描述 移除内容 保留数据和事件 返回值 .remove()
从DOM中移除元素 元素本身及其所有后代 ❌ 不保留 被移除的元素 .detach()
从DOM中移除元素 元素本身及其所有后代 ✅ 保留 被移除的元素 .empty()
清空元素内容 只移除所有子元素 ❌ 不保留 原始元素(已清空) js// .remove() vs .detach() vs .empty() 示例 var $container = $('#container'); // .remove() - 完全移除,不保留数据和事件 $('.item').remove(); // .detach() - 移除但保留数据和事件,可以重新插入 var $detached = $('.item').detach(); // 之后可以重新插入 $detached.appendTo($container); // .empty() - 只移除子内容,保留元素本身 $container.empty(); // 移除#container内的所有子元素
会移除事件处理程序和数据:
.remove()
会同时移除元素上的所有 jQuery 事件处理程序和数据- 如果需要保留事件处理程序和数据以便重新插入,使用
.detach()
代替
js// 使用 .remove() - 事件处理程序会被移除 $('#button').on('click', function() { alert('点击!'); }); $('#button').remove(); // 如果重新插入,点击事件不会工作
js// 使用 .detach() - 事件处理程序会保留 $('#button').on('click', function() { alert('点击!'); }); var $button = $('#button').detach(); $button.appendTo('body'); // 点击事件仍然工作
.empty()
对比.html('')
:.empty()
和.html('')
在功能上类似,但有一些区别.empty()
是更专门的方法,性能稍好,且会清理 jQuery 数据
js// 两种方法效果类似,但.empty()是更专门的方法 $('#container').empty(); // 推荐方式 $('#container').html(''); // 替代方式 // .empty() 还会清理子元素的 jQuery 数据,而 .html('') 不会
替换
$els.replaceAll():
(target)
,DOM 替换,使用当前选中的元素来替换所有指定的目标元素。$els.replaceWith():
(newContent|fn)
,DOM 替换,用指定的内容替换匹配的元素集合中的每个元素。返回被移除的元素集合。$els.replaceWith():
(newContent)
,替换内容。$els.replaceWith():
(fn)
,使用函数替换内容。
核心特性:
.replaceAll()
对比.replaceWith()
:二者实现相同的功能,但语法结构相反:
方法 语法 返回值 描述 .replaceWith()
$(target).replaceWith(content)
被替换元素的 jQuery 对象 用内容替换目标元素 .replaceAll()
$(content).replaceAll(target)
替换内容的 jQuery 对象 用当前元素替换目标元素 js// 这两种方式效果相同 $('#target').replaceWith($('.replacement')); // 使用 .replaceWith() $('.replacement').replaceAll('#target'); // 使用 .replaceAll()
移动而非复制:如果用于替换的元素已经存在于文档中,它会被移动到新位置,而不是被复制。
多个目标元素:当目标选择器匹配多个元素时,用于替换的元素会被复制并替换每个目标元素(第一个实例是移动,后续的是克隆)。
事件处理:
- 被移动的元素会保留其事件处理程序。
- 被替换的元素及其事件处理程序会被完全移除。
数据和方法:被替换的元素上的 jQuery 数据和自定义方法会被移除。
克隆
- $els.clone():
(withDataAndEvents?, deepWithDataAndEvents?)
,DOM 克隆,用于创建匹配元素集合的深度副本(包括所有后代元素和文本节点)。
核心特性:
ID 冲突: 克隆的元素会保留原始元素的 ID,这可能导致 ID 重复。通常需要修改克隆元素的 ID。
jsvar $cloned = $('#original').clone(); $cloned.attr('id', 'original-clone'); // 修改 ID
表单数据: 克隆的表单元素会保留原始元素的值,但不会保留用户输入的数据(除非使用参数复制数据)。
性能考虑: 克隆大型 DOM 结构可能会影响性能,应谨慎使用。
事件委托: 对于使用事件委托处理的事件,克隆元素会自动获得这些事件处理,不需要特别复制
源码:clone()
jQuery 事件
事件
事件处理方式
jQuery 事件处理方式:
事件绑定:
通用方法:
$els.on():
(events|eventsMap,selector?,data?,handler)
,事件处理,用于将一个或多个事件处理函数绑定到匹配的元素上。提供了统一的事件绑定接口。快捷方法:
$els.click():
(eventData?, handler?)
,事件处理,用于绑定点击事件处理程序和触发元素的点击事件。$els.hover():
(handlerInOut|handlerIn, handlerOut?)
,事件处理,用于处理鼠标悬停事件的便捷方法,可同时处理mouseenter
和mouseleave
事件。$els.mouseenter():
(eventData?, handler?)
,事件处理,不会冒泡,用于处理鼠标进入事件。$els.mouseleave():
(eventData?, handler?)
,事件处理,不会冒泡,用于处理鼠标离开事件。$els.keydown():
(eventData?, handler?)
,事件处理,用于处理键盘按键按下事件。
事件解绑:
$els.off():
(events?|eventsMap?,selector?,handler?)
,事件处理,用于移除一个或多个通过.on()
方法附加的事件处理程序。事件触发:
$els.trigger():
(eventType, extraParameters?)
,事件处理,用于手动触发元素上绑定的事件处理程序。不会模拟浏览器默认行为。
对比 :click()
和 on()
相同点:
- click 是 on 的快捷方式。
- 重复监听,都不会出现覆盖情况。
- 都支持事件委托。
- 底层用的是 addEventListener。
- 如果 on 没有使用 selector 的话,那么和使用 click 是一样的。
不同点:
- on 函数可以接受一个 selector 参数,用于筛选可触发事件的后代元素。
- on 函数支持给事件添加命名空间。
this
jQuery 事件中的 this:
this 指向 DOM 而非 jQuery 对象:
click 和 on 中的 this 都是指向原生 DOM 而非 jQuery 对象。
底层实现原理:
遍历后通过
addEventListener()
绑定事件。this 由 DOM 转为 jQuery 对象
通过
$(this)
转换为 jQuery 对象。
事件冒泡
jQuery 事件冒泡:
jQuery 为了更好的兼容 IE 浏览器,底层并没有实现事件捕获
事件对象
jQuery 事件对象 $event:
jQuery 事件系统的规范是根据 W3C 的标准来制定 jQuery 事件对象。
包含原生事件对象属性:
原生事件对象的大多数属性都被复制到新的 jQuery 事件对象上。
jQuery 兼容处理:
jQuery 对以下属性实现了跨浏览器的兼容处理:
target
:relatedTarget
:pageX
/pageY
:which
:metaKey
:
jQuery 常用事件方法:
jQuery 对原生事件方法进行了兼容处理
- event.preventDefault():
()
,用于阻止事件的默认行为(如表单提交、链接跳转)。 - event.stopPropagation():
()
,用于阻止事件在 DOM 树中继续传播(包括捕获和冒泡阶段)。
- event.preventDefault():
jQuery 访问原生事件对象:
可以通过
event.originalEvent
访问原生事件对象。
事件委托
jQuery 事件委托:
示例:jQuery 事件委托
一个 ul 中存放多个 li,使用事件委托的模式来监听 li 子元素的点击事件。
示例:jQuery 事件委托 + 选择器
常见事件
jQuery 特有事件:
jQuery 包含原生的事件,此外还有一些特有的事件:
鼠标事件
.hover()
文档事件
ready()
对比 mouseover 和 mouseenter:
mouseenter()
/mouseleave()
:不冒泡,鼠标进入 / 离开元素本身。仅在进入目标元素时触发一次,子元素之间移动不触发。mouseover()
/mouseout()
:冒泡,鼠标进入 / 离开元素或其子元素。鼠标在元素和子元素之间移动时会重复触发:先调用父元素的 mouseout
再调用子元素的 mouseover
因为支持冒泡,所以会将 mouseover 传递到父元素中;
案例:选项卡切换
jQuery 动画
animate()
$els.animate():
()
,动画,通过平滑地改变元素的 CSS 属性值来创建自定义动画效果。$els.animate():
(properties,durations?,easing?,complete?)
,基础语法。$els.animate():
(properties,options)
,选项对象语法。
properties 参数对象的值的类型:
number
:数字类型,animate({height: 0})
string
:字符串类型,animate({height: '0'})
%
:百分比单位(相对于父元素,动画时先将单位转为%
,再执行动画),animate({height: '0%'})
show|hide|toggle
:关键字,animate({height: 'hide'})
+=40px|-=40px
:相对值,animate({height: '+=40px'})
示例:动画-隐藏/显示/切换 box
JS 实现:
常见动画方法
$els.hide():
(options|duration,easing?,complete?)
,动画,用于隐藏匹配的元素集合。$els.hide():
()
,立即隐藏(无动画效果)。$els.hide():
(duration,easing?,complete?)
,以动画方式隐藏。$els.hide():
(options)
,高级动画控制。
$els.show():
(options|duration,easing?,complete?)
,动画,用于显示匹配的元素集合。$els.show():
()
,立即显示(无动画效果)。$els.show():
(duration,easing?,complete?)
,以动画方式显示。$els.show():
(options)
,高级动画控制。
$els.toggle():
(showOrHide|options|duration,easing?,complete?)
,动画,用于切换元素的可见性。$els.toggle():
()
,立即切换可见性(无动画效果)。$els.toggle():
(duration,easing?,complete?)
,以动画方式切换可见性。$els.toggle():
(showOrHide)
,带 Boolean 对象参数:精确控制。$els.toggle():
(options)
,带 options 对象参数:精确控制。
$els.fadeIn():
(options|duration,easing?,complete?)
,动画,用于创建淡入动画效果的方法,通过平滑地增加元素的不透明度来显示匹配的元素。$els.fadeIn():
()
,无参数:使用默认动画(默认:400ms
,swing
)。$els.fadeIn():
(duration,easing?,complete?)
,带 Duration 和 Easing 参数:自定义动画。$els.fadeIn():
(options)
,带 Options 对象参数:高级动画控制。
$els.fadeOut():
()
,动画,用于创建淡出动画效果的方法。通过逐渐改变匹配元素的不透明度来实现。$els.fadeToggle():
()
,动画,通过动态调整元素的不透明度来切换元素的显示状态。$els.fadeTo():
()
,动画,用于将匹配元素的不透明度逐渐调整到一个指定的目标值。
示例:hide()/show()/toggle()
动画队列【
- $els.queue():
(queueName?, newQueue|callback)
,动画队列,用于获取或设置附加在元素上的动画队列。 - $els.stop():
(queue?,clearQueue?,jumpToEnd?)
,动画队列,用于立即停止当前正在匹配元素上运行的动画,并可选择性的清空队列或跳转到结束状态。 - $els.delay():
(duration, queueName?)
,动画队列,用于在动画队列中设置一个定时器,延迟后续队列项目的执行。 - $els.dequeue():
(queueName?)
,动画队列,用于手动执行匹配元素队列中的下一个函数。常用于手动执行自定义队列。 - $els.clearQueue():
(queueName?)
,动画队列,用于移除匹配元素队列中所有尚未执行的函数,但不会停止当前正在执行的函数。
jQuery 匹配元素中的 animate 和 delay 动画是通过一个动画队列(queue)来维护的。以下动画会添加到动画队列中:
- .hide() 、 .show()
- .fadeIn() 、.fadeOut()
- .animate()、delay()
- ......
.queue():查看当前选中元素中的动画队列。
.stop( [clearQueue ] [, jumpToEnd ] ):停止匹配元素上当前正在运行的动画。
- clearQueue :一个布尔值,指示是否也删除排队中的动画。默认为 false
- jumpToEnd :一个布尔值,指示是否立即完成当前动画。默认为 false
示例:
动画队列-基本使用
animate()
、hide()
等动画方法都是通过动画队列来维护的,队列中的动画会依次执行。查看动画队列
停止动画队列
案例:隐藏侧边栏广告
HTML 结构
JS 实现
效果:
工具函数
jQuery 遍历
- $els.each():
(callback)
,遍历方法,用于遍历一个 jQuery 对象中的所有 DOM 元素,并对每个元素执行一个指定的回调函数。 - jQuery.each():
(collection, callback)
,遍历方法,用于遍历任何集合,无论是数组、类数组对象还是普通对象。是一种通用遍历方法。
对比 .each()
和 jQuery.each()
.each()
:是 jQuery 对象上的方法,用于遍历 jQuery 对象。- 底层调用的是
jQuery.each()
。
- 底层调用的是
jQuery.each()
:是 jQuery 函数上的方法,可以遍历对象、数组、类数组等,它是一个通用的工具函数。
示例:
.each()
基本使用jQuery.each()
基本使用
源码:.each()
.each()
对象实例的 .each() 方法本质上是调用的 jQuery.each() 方法
jQuery.each()
如果是类数组类型,使用 for 遍历
如果是对象类型,使用 for in 遍历
jQuery AJAX
AJAX
jQuery 中的 AJAX:
jQuery 中也有 AJAX 模块,该模块是在 XMLHttpRequest 的基础上进行了封装。
$.ajax():(url?, settings?)
,用于执行异步 HTTP 请求(Ajax)的底层接口。所有其他 jQuery Ajax 方法在内部都是调用此方法。
$.ajax():
(url, settings?)
,传入一个 URL 和配置对象(较少用)。$.ajax():
(settings)
,传入一个配置对象(最常用、最强大)。
初体验 jQuery 中的 AJAX:
- https://httpbin.org:是一个专门提供免费测试 http 服务的网站。
请求参数 settings:
- settings:
object
,一个用于配置 Ajax 请求的键值对集合。核心参数:
url:
string
,默认:window.location
,发送请求的地址。type/method:
string
,默认:GET
,请求方式。method 是 jQuery 1.9.0+ 的别名。data:
object|string|array
,默认:undefined
,发送到服务器的数据。如果是对象,jQuery 会将其转换为查询字符串(对于 GET 请求)或请求体(对于 POST 请求)。
如果是数组或字符串,则直接使用。
dataType:
text|xml|json|script|html
,默认:智能推导
,期望服务器返回的数据类型。jQuery 会根据此类型来解析返回的数据。contentType:
string
,默认:application/x-www-form-urlencoded; charset=UTF-8
,发送信息至服务器时内容编码类型。告诉服务器请求体的格式。设置false
跳过默认设置。headers:
object
,默认:{}
, 一个额外的{键: 值}
对对象,随请求一起发送。常用于设置认证令牌等请求头(如Authorization: Bearer ...
)。timeout:
number
,默认:0
,设置请求超时时间(毫秒)。超过该时间后,请求会自动终止并触发error
回调。回调函数:
success:
(data,textStatus,$xhr)=>void
,请求成功后的回调函数。error:
($xhr,textStatus,errorThrown)=>void
,请求失败时的回调函数。complete:
($xhr,textStatus)=>void
,请求完成后的回调函数(无论成功或失败都会执行)。beforeSend:
($xhr,settins)=>boolean
,发送请求之前的回调函数。可用于修改 $xhr 对象或添加自定义头信息。如果此函数返回false
,将取消本次请求。其他参数:
async:
boolean
,默认:true
,是否为异步请求。默认情况下,所有请求均为异步。
如果需要发送同步请求,请将此选项设置为
false
(强烈不推荐,会导致浏览器界面锁定)。
cache:
boolean
,默认:true (对于 dataType 为 'script' 和 'jsonp' 时,为 false)
,是否强制浏览器缓存请求页面。- 如果设置为
false
,它将强制浏览器不缓存请求页面。对于 GET 请求,通过在 URL 后附加时间戳参数实现。
- 如果设置为
context:
object
,指定所有回调函数(如success
,error
)中this
的指向。crossDomain:
boolean
,默认:false
,是否强制将请求视为跨域请求(即使在同一域下)。服务器重定向到其他域的情况下设为true
。jsonp:
string
,在一个 JSONP 请求中重写回调函数的名字。
AJAX 默认配置:
示例:formData 模拟表单提交
注意:
- 避免将 data 中的 formData 对象转换为查询字符串格式
- contentType 值为 false 时,contentType 值为 multipart/form-data 格式
jQuery 插件开发
插件开发
在我们开发时,有时候 jQuery 提供的方法并不能满足我们的需求。如果我们想给 jQuery 扩展一些其它的方法,那这种情况下,可能需要编写一个插件。
jQuery 插件:就是编写一些新增的方法,并将这些方法添加到 jQuery 的原型对象上。
编写 jQuery 插件的步骤:
- 新建文件:新建一个插件对应的 JS 文件(命名规范:
jquery.插件名.js
) - 编写插件:在立即执行函数中编写插件,这样可以避免插件中的变量与全局变量冲突。
- 新增方法:在 jQuery 的原型对象上新增一些的方法。
- 导入插件:最后在 html 中导入就可以像使用其他 jQuery 对象方法一样使用了。
- 完成:到此就开发完一个 jQuery 的插件了。
案例:开发 jquery.showlinklocation.js
插件
功能:让网页上所有的 a 标签文本的后面追加对应的域名地址。
使用插件
插件实现:
手写 jQuery
MiniJQuery
整体架构
init()
jQuery 共享原型设计:
jQuery 和 jQuery.prototype.init 共享一个原型对象:
调用
$()
因为共享一个原型对象,所以可以通过
new jQuery.prototype.init()
返回一个 jQuery 对象实例
$.fn
等价于 $.prototype
,都是 jQuery 的原型对象:
extend()
$.extend()
的用法:
extend()
可以给任意对象、jQuery、jQuery.fn 扩展
$.extend()
和 $.fn.extend()
的实现:
jQuery.extend
和 jQuery.fn.extend
指向同一个匿名函数。如何区分扩展的目标:
- 任意对象:需要传第二个参数
- jQuery:只需传一个参数
- jQuery.fn:只需传一个参数
1、实现浅拷贝扩展
2、实现深拷贝扩展
浅拷贝问题:后者覆盖了前者,而非追加
深拷贝使用:
- 第一个参数为 true 表示深拷贝,为 false 表示浅拷贝
使用 extend()
扩展工具方法:判断纯对象类型、判断数据类型