本系列笔记大概分为三篇,已完结。 参考:jQuery API 3.5.1 速查表;黑马 pink 老师前端入门
系列笔记:
jQuery(一)—— jQuery 概述 / jQuery 选择器 / jQuery 样式操作 / jQuery 效果
jQuery(二)—— jQuery 属性操作 / jQuery 内容文本值 / jQuery 尺寸、位置操作
文末给出了瀑布流效果、全屏滚动、以及 todolist待办事项 案例的讲解,推荐阅读👍👍👍!!!
文章目录
一、jQuery 事件注册
- 单个事件注册
element.事件(function) () {...})
$("div").click(function () {...})
jQuery 单个事件注册写法和原生 JS 基本一致。如 mouseover
、mouseout
、blur
、focus
、change
、keydown
、keyup
、resize
、scroll
等。
- 示例
$("div").click(function () {
$(this).css("display", "none");
});
$("div").mouseenter(function () {
$(this).css("background-color", "tomato");
});
二、jQuery 事件处理
1. on() 绑定事件
on()
方法在匹配元素上绑定一个或多个事件的处理函数。
element.on(events,[selector],fn)
event
:一个或多个用空格分隔的事件类型,如click
或keydown
selector
:元素的子元素选择器fn
:该事件被触发时执行的函数
- on() 绑定一个或多个事件
用此方法,可以将上述示例代码进行合并,如下:
$("div").on({
click: function () {
$(this).css("display", "none");
},
mouseenter: function () {
$(this).css("background-color", "tomato");
}
})
如果多个事件所指向的处理函数相同,还可以采用下面的写法
$("div").on("mouseenter mouseleave", function () {
$(this).toggleClass("current");
})
- on() 进行事件委派
on()
可以进行事件委派操作。事件委派的定义就是,把原来绑定在子元素身上的事件绑定到父元素身上。
不是每个子节点单独设置事件监听器,而是将事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
$("ul").on("click", "li", function () {
$(this).addClass("current");
})
- on() 为动态创建的元素绑定事件
通过之前绑定事件的方法创建出的事件无法对动态创建出来的元素起效果。如下:
$("ul li").click(function () {
$(this).addClass("current");
})
var li = $("<li>好好学习,天天向上</li>");
$("ul").append(li);
无论如何点击都没有反应,也就是说动态创建出的元素没有绑定上点击事件。
而通过 on()
绑定的点击事件,是会绑定到动态生成的元素身上的。我的理解是,因为事件委派到了父元素身上,新创建的子元素会触发父元素的事件。如下:
$("ul").on("click", "li", function () {
$(this).addClass("current");
})
var li = $("<li>好好学习,天天向上</li>");
$("ul").append(li);
- 案例:微博发布
简单说明一下,新创建 li 标签,采取 html()
设置 li 标签内容,prepend()
追加到 ul 子元素最前面。此外,将 li 设置为 display:none
不显示,每创建一条 li 则采取 slideDown()
使得隐藏元素滑动显示出来。同样删除操作可以通过 sideDown()
配合回调函数中执行 remove()
将其删除。
// 点击后发布内容
$(".btn").on("click", function () {
var li = $("<li></li>");
li.html($(".txt").val() + "<a href='javascript:;'> 删除 </a>");
$("ul").prepend(li);
li.slideDown();
$(".txt").val("");
})
// 删除留言
$("ul").on("click", "a", function () {
$(this).parent().slideUp(function () {
$(this).remove();
});
})
2. off() 解绑事件
off()
方法可以移除通过 on()
方法添加的事件处理程序。
$("div").off(); // 解除绑定的所有事件
$("div").off("click"); // 解除绑定的 div 事件
$("ul").off("click", "li") // 解除事件委派
此外,有些事件可能只想被触发一次,如果用 on()
配合 off()
来操作显得有些多余,jQuery 为此提供了 one()
绑定事件的方法。此方法语法和 on()
是一样的,只不过只能触发执行一次。
3. 自动触发事件 trigger()
有些事件希望自动触发,比如轮播图自动播放功能(定时点击右侧按钮)。jQuery 自动触发事件可以有以下 3 种方式:
element.click()
element.trigger("事件")
element.triggerHandler("事件")
triggerHandler()
方法触发被选元素的指定事件类型。但不会执行浏览器默认动作,也不会产生事件冒泡。
triggerHandler()
方法与 trigger()
方法类似。不同的是它不会触发事件(比如表单提交)的默认行为,而且只影响第一个匹配元素。下面对比说明一下:
$("input").on("focus", function () {
$(this).val("你好");
})
$("input").trigger("focus"); // 表单显示 “你好” ,表单中光标且持续闪烁
$("input").triggerHandler("focus"); // 表单显示 “你好” ,表单中没有光标
三、jQuery 事件对象
只要事件被触发,就会有事件对象的产生。
element.on(events, [selector], function(event) {})
有了事件对象 event 就可以进行一系列操作,如
- 阻止默认行为:
event.preventDefault()
或者return false
- 阻止冒泡:
event.stopPropagation()
四、jQuery 拷贝对象
如果想要把某个对象拷贝(合并)给另一个对象使用,此时可以使用 $.extend()
方法。
$.extend([deep], target, object1 [, objectN ] )
deep
:如果设为 true ,则为深拷贝;为 false,则为浅拷贝(默认)。target
:目标对象,其他对象的成员属性将被附加到该对象上object1
:第一个被合并的对象
var targetObj = {};
var obj = {
id: 1,
name: "andy"
};
$.extend(targetObj, obj);
console.log(targetObj); // {id: 1, name: 'andy'}
如果原来对象中就有相同的属性,那么合并后的属性值会将之前的属性值覆盖。
此外,关于深拷贝浅拷贝问题,可以查看此文章 JavaScript 进阶 —— 函数,该文章文末给出了关系图介绍直接赋值、深拷贝、浅拷贝关系,此处不再过多介绍。
五、多库共存
jQuery 使用 $
作为标识符,随着 jQuery 的流行,其他 JS 库也使用到了 $
作为标识符,这样一来便会产生冲突。如何解决呢?也就是说,如何才能多库共存呢?
jQuery 给出的解决方案:
- 把里面的
$
统一改为 jQuery,如jQuery("div")
- 更干脆的方法,让用户自定义:利用
noConflict()
可返回对 jQuery 的引用,可以把它存入变量,以供稍后使用。如var jq = $.noConflict()
那么,此处jq
即可代替$
的作用。
var jq = $.noConflict();
jq("div").click(function () {
alert(11);
})
六、jQuery 插件
jQuery 功能比较有限,想要更复杂的特效效果,可以借助于 jQuery 插件完成。
注意:这些插件也是依赖于 jQuery 来完成的,所以使用前必须引入 jQuery 文件。
jQuery 插件常用网站:
- jQuery 插件库: http://www.jq22.com/
- jQuery 之家(免费开源):http://www.htmleaf.com/
jQuery 插件使用步骤:
- 引入相关文件(jQuery文件 和 插件文件)
- 复制相关 html、css、js(调用插件)代码到目标文件夹
一般来说网站下面都会有对应步骤说明,使用时,修改部分代码即可。
1. 瀑布流效果
下载插件后,进行如下操作(代码仅针对此案例)
- 在页面中引入 CSS 和 JS 文件
<link rel="stylesheet" href="path/to/sortable.min.css">
<script src="path/to/sortable.min.js"></script>
- 基本HTML结构
<main class="sortable">
<div class="container">
<div class="wrapper">
<ul class="sortable__nav nav">
<li>...</li>
...
</ul>
<!--其中一个图片板块-->
<div id="sortable" class="sjs-default">
<div data-sjsel="flatty">
<div class="card">
<img class="card__picture" src="./images/item-1.jpg" alt="">
<div class="card-infos">
<h2 class="card__title">标题</h2>
<p class="card__text">描述</p>
</div>
</div>
</div>
</div>
</div>
</main>
- 最后,在页面 DOM 元素加载完毕之后,通过 sortablejs() 方法来初始化插件
<script type="text/javascript">
document.querySelector('#sortable').sortablejs()
</script>
2. 全屏滚动(fullpage.js)
效果图内存太大,不方便展示。
插件下载地址: https://github.com/alvarotrigo/fullPage.js
具体的 JS、css 代码在 dist 文件夹中,具体操作说明(HTML结构、jQuery 初始化代码)可以查看 README.md 文件。
HTML结构
<div id="fullpage">
<div class="section">Some section</div>
<div class="section">Some section</div>
<div class="section">Some section</div>
<div class="section">Some section</div>
</div>
其中每个 section中 可以添加小的滑动板块
<div class="section">
<div class="slide"> Slide 1 </div>
<div class="slide"> Slide 2 </div>
<div class="slide"> Slide 3 </div>
<div class="slide"> Slide 4 </div>
</div>
jQuery 初始化代码
$(document).ready(function() {
$('#fullpage').fullpage({
//options here
autoScrolling:true,
scrollHorizontally: true
// 更多页面相关设置写在此处
});
});
3. bootstrap 组件、JS 插件
Bootstrap 网址:https://v3.bootcss.com/
JS 插件
jQuery 插件为 Bootstrap 的组件赋予了“生命”。可以简单地一次性引入所有插件,或者逐个引入到页面中。利用 Bootstrap 中的 JavaScript 插件,可以便捷地实现如 模态框、标签页、轮播图等待页面效果。
下面举几个简单示例:
- 模态框
CSS、JS 文件引入
<link rel="stylesheet" href="css/bootstrap.css">
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
HTML 结构
<button class="btn btn-primary btn-lg" id="my-Modal">我不想努力了</button>
<div class="modal fade" tabindex="-1" role="dialog" id="myModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title">温馨提醒</h4>
</div>
<div class="modal-body">
<p>少壮不努力,老大徒伤悲</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">滚去学习</button>
<button type="button" class="btn btn-primary">继续努力</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
JS 代码
<script>
$("#my-Modal").on("click", function () {
$('#myModal').modal();
})
</script>
上面是利用 JS $('#myModal').modal();
来调用的模态框。除此方法外,也可以通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码。
具体方法:为起控制器的按钮(button
)添加 data-toggle="modal"
告诉浏览器要切换模态框组件,还要添加data-target="#myModal"
用于指定具体是哪个模态框。这是 Bootstrap 中的一等 API,也应该是首选方式。
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">我不想努力了</button>
此方式无需额外添加 JS 代码,设置完 data 属性即可。
- Tab 栏切换
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab"
data-toggle="tab">Home</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Profile</a>
</li>
<li role="presentation"><a href="#messages" aria-controls="messages" role="tab"
data-toggle="tab">Messages</a></li>
<li role="presentation"><a href="#settings" aria-controls="settings" role="tab"
data-toggle="tab">Settings</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">欢迎回家</div>
<div role="tabpanel" class="tab-pane" id="profile">没什么好说的</div>
<div role="tabpanel" class="tab-pane" id="messages">今天没有任何信息哦</div>
<div role="tabpanel" class="tab-pane" id="settings">设置点啥好呢</div>
</div>
</div>
组件
Bootstrap 自带了大量可复用的组件,包括字体图标、下拉菜单、导航、警告框、弹出框等更多功能。
展示几个示例:
- 单按钮下拉菜单
只要改变一些基本的标记,就能把按钮变成下拉菜单的开关。
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
Action <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
- 导航条
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
综合案例:todolist
这个案例主要是用到本地存储 localStorage
,无论是按下回车还是点击复选框,都要先将数据存储然后将本地存储的数据加载到页面,保证即使关闭页面数据也不会丢失。
采用数组的形式进行存储,如下代码为两条信息的存储示例
var todolist = [{
title: '明天一定要早起!', // 事项
done: true // 是否完成
}, {
title: '晚上不能熬夜了!',
done: false
}]
注意:
- 本地存储 localStorage 里面只能存储字符串格式数据,因此需要将对象转换为字符串,利用
JSON.stringify(data)
。 - 获得本地存储的数据,需要把字符串数据转换为对象格式,利用
JSON.parse(data)
JS 代码
$(function () {
// 打开页面时就要进行数据渲染
load();
// 1. 添加待办事项
$("#title").on("keydown", function (event) {
if (event.keyCode === 13 && $(this).val()) {
var local = getData();
// 将最新数据追加给数组
local.push({ title: $(this).val(), done: false });
// 将此数组存储下来
saveDate(local);
// 将本地存储数据渲染至页面
load(local);
$(this).blur().val("");
}
})
// 2. 删除待办事项
$("ol, ul").on("click", "a", function () {
var data = getData();
// 获取 a 标签,自定义索引
var index = $(this).attr("data-id");
// 删除对应元素数据
data.splice(index, 1);
// 保存数据到本地存储
saveDate(data);
// 重新渲染
load();
})
// 3. 点击完成按钮
$("ol, ul").on("click", "input", function () {
// 获取本地数据
var data = getData();
// 利用 a 标签的自定义属性获取索引
var index = $(this).siblings("a").attr("data-id");
// 找到当前复选框,修改 done 属性
data[index].done = $(this).prop("checked");
// 保存数据
saveDate(data);
// 重新渲染
load();
})
// 封装函数:读取本地存储的数据
function getData() {
var data = localStorage.getItem("todolist");
if (data !== null) {
return JSON.parse(data); // 返回对象格式
} else {
return [];
}
}
// 封装函数:保存本地存储数据
function saveDate(data) {
localStorage.setItem("todolist", JSON.stringify(data));
}
// 封装函数:数据渲染
function load() {
var data = getData();
// 渲染前将元素内容清除,再用 each 遍历
$("ol, ul").empty();
// 声明变量记录个数
var todoCount = 0;
var doneCount = 0;
$.each(data, function (i, ele) {
if (ele.done) {
$("ul").prepend("<li><input type='checkbox' checked='checked'> <p>" + ele.title + "</p> <a href='javascript:;' data-id=" + i + " ></a ></li > ");
doneCount++;
} else {
$("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' data-id=" + i + " ></a ></li > ");
todoCount++;
}
});
// 修改事项个数
$("#todocount").text(todoCount);
$("#donecount").text(doneCount);
}
})