一.JQuery 简介
1.JQuery 概述
- JavaScript库:一个 对 原生JS代码 进行封装 的 JS 文件,快速高效的使用封装好的功能
- 常见的 JavaScript库 :JQuery 、Prototype 、YUI 、Dojo 、Ext JS 、移动端的 zepto
- JQuery:封装了 JavaScript 常用的功能代码,优化 DOM 操作、事件处理、动画设计 和 Ajax 交互
- J:JavaScript; Query:查询JS
- 优点:轻量级、速度快、兼容主流浏览器、链式编程、隐式迭代、简化 DOM 操作、支持各种插件
- 版本介绍:
- 1x :兼容 IE 678 等低版本浏览器, 官网不再更新
- 2x :不兼容 IE 678 等低版本浏览器, 官网不再更新
- 3x :不兼容 IE 678 等低版本浏览器, 是官方主要更新维护的版本
2.JQuery 的基本使用
2.1 JQuery 入口函数:$(function(){ ... });
- 相当于原生 JS 中的 DOMContentLoaded:不必等 外部的 js 文件、css文件、图片加载完毕 就执行内部代码
- ① $(function(){ ... });(推荐!!) ②$(document.ready(function(){ ... }));
2.2 JQuery 的顶级对象 $
- $ 是 JQuery 的别称,代码中可用 JQuery 代替 $
- $ 是 JQuery 的顶级对象, 相当于 原生JS 中的 window
- DOM 对象:用 原生JS 获取的对象,DOM 对象用 原生JS 方法
- JQuery 对象:用 JQuery 获取的对象,只有 JQuery 对象才能用 JQuery 方法
JQuery 对象本质: 伪数组形式存储, 利用 $ 对 DOM对象 包装后产生的对象// 1. DOM 对象: 用原生js获取的对象就是DOM对象 var myDiv = document.querySelector('div'); // myDiv 是DOM对象 // 2. jQuery对象: 用jquery方式获取的对象是jQuery对象。 本质:通过$把DOM元素进行了包装 $('div'); // $('div')是一个jQuery 对象
- DOM 对象 与 JQuery 对象 可以相互转换
DOM 对象 转换为 JQuery 对象: $('DOM对象'),如:$('div') JQuery 对象 转换为 DOM 对象(两种方式)
$('div')[index] $('div').get(index)<video src="mov.mp4" muted></video> // ... $('video')[0].play() // jquery里面没有play 这个方法,需要转换为 DOM 元素 $('video').get(0).play()
二.JQuery 常用 API
1.JQuery 选择器
- 原生 JS 获取元素,方式多,且容性不一致,因此 JQuery 做了封装,使 获取元素 统一标准
1.1 选择器、筛选方法
- JQuery 选择器: $(“CSS选择器”) :一定要加 "引号"!
- 基础选择器:
- 层级选择器:
- 筛选选择器:
// 新浪下拉菜单 ul>4li li>ul>3li>a $(function() { $(".nav>li").mousenter(function() { // 给nav 亲儿子li 添加鼠标经过事件 $(this).children("ul").show(); // this 不要加引号 表示选取 li的亲儿子ul }); $(".nav>li").mouseout(function() { $(this).children("ul").hide(); }) })
- JQuery 筛选方法(重点):parent() children() find() siblings() eq()
1.2 隐式迭代、排他思想、链式编程
隐式迭代:遍历内部 DOM 元素(伪数组形式存储)的过程 JQuery 排他思想:多选一效果,当前元素设置样式,兄弟元素清除样式 链式编程(以排他思想为例):$(this).css('color', 'red').sibling().css('color', '');$(function() { $("button").click(function() { // 1. 隐式迭代 给所有的按钮都绑定了点击事件 $(this).css("background", "pink"); // 2. 当前的元素变化背景颜色 $(this).siblings("button").css("background", ""); // 3. 其余兄弟去掉背景颜色 隐式迭代 }); })
1.3 淘宝精品案例分析
- 核心原理:鼠标经过 左侧盒子 某个 li,就让 内容区盒子 相对应图片 显示,其余图片隐藏
- 需要当前 li 的索引号,JQuery 得到当前元素索引号: $(this).index()
- 对应的图片盒子,可用 eq(index) 方法选择
<script> $(function() { $("#left li").mouseover(function() { // 鼠标经过 左侧导航栏的 li var index = $(this).index(); // 得到当前小li 的索引号 // 链式编程 显示对应索引号的图片盒子 其兄弟盒子隐藏 $("#content div").eq(index).show().siblings().hide(); }) }) </script> <body> <div class="wrapper"> <ul id="left"> <li><a href="#">女靴</a></li> // 此处是不同的导航栏按钮 // ... </ul> <div id="content"> // 此处是不同的图片内容盒子 <div> <a href="#"><img src="images/女靴.jpg" width="200" height="250" /></a> </div> // ... </div> </body>
2.JQuery 样式操作
2.1 操作 css 方法
- 返回属性值:"属性名"
- 设置一组样式:“属性名”,“属性值”,逗号分隔,值 如果是 数字 可不跟 单位引号
- 设置多组样式:{"属性名":"属性值","属性名":"属性值"},参数是对象,属性可不加引号
$("div").css("width", 300); // 可以不写单位 那就不要加引号 $("div").css(height, "300px"); // 这个写法不对 因为属性名一定要加引号 $("div").css({ width: 400, height: 400, backgroundColor: "red" // 复合属性须采取 驼峰命名法,值不是数字,则加引号 })
2.2 设置类样式方法
- 操作类样式:作用 = classList,注意 操作类 里面的参数 不要加点!
- 添加类:$(“div”).addClass(''current'');
- 移除类:$(“div”).removeClass(''current'');
- 切换类: $(“div”).toggleClass(''current'');
- 类操作 VS className:原生 JS 中 className 覆盖原类名;JQuery 类操作 不影响原类名效果
$("div").click(function() { $(this).toggleClass("current"); // 这里的参数类不要加点 });
2.3 tab 栏切换分析
- 点击上部 li,当前 li 添加 current类,兄弟移除 current类
- 点击的同时,得到当前 li 的索引号
- 让下部相应索引号的 item 显示,其余 item 隐藏
<div class="tab"> <div class="tab_list"> // 导航栏 <ul> <li class="current"> 商品介绍 </li> // 被选中后 改变背景颜色 // <li> ... </ul> </div> <div class="tab_con"> // 导航栏具体内容 <div class="item" style="display: block;"> 商品介绍模块内容 </div> // <div class="item"> ... </div> </div> // ... $(function() { $(".tab_list li").click(function() { // 点击导航栏li 触发事件 // 当前被点击的li 添加被选中的类样式 他的兄弟 移除被选中的类样式 $(this).addClass("current").siblings().removeClass("current"); var index = $(this).index(); // 获得被点击 li 的索引号 // 让相应索引号的 导航栏具体内容 显示,其余m隐藏 $(".tab_con .item").eq(index).show().siblings().hide(); }); })
3.JQuery 效果
3.1 显示隐藏效果
- show([speed,[easing],[fn]]) 显示
- hide([speed,[easing],[fn]]) 隐藏
- toggle([speed,[easing],[fn]]) 切换
- 参数都可省略,平时一般不带参数,直接显示隐藏
- speed:速度(“slow”,“normal”, or “fast”) 或 毫秒数
- easing:指切换效果,默认是“swing”,可用参数“linear”
- fn: 回调函数,动画完成时执行的函数,每个元素执行一次
$("button").eq(1).click(function() { $("div").hide(1000, function() { alert(1); }); }) $("button").eq(2).click(function() { $("div").toggle(1000); // 切换效果 一般不加参数 直接显示隐藏 })
3.2 滑动效果
- slideDown([speed,[easing],[fn]]) 下滑效果
- slideUp([speed,[easing],[fn]]) 上滑效果
- slideToggle([speed,[easing],[fn]]) 滑动切换
$("button").eq(2).click(function() { $("div").slideToggle(500); });
3.3 事件切换
- hover([over,]out)
- over:鼠标移到元素上触发的函数(相当于mouseenter)
- out:鼠标移出元素要触发的函数(相当于mouseleave)
- 只写一个函数,则 鼠标 经过和离开 都会触发
// 事件切换 hover 鼠标经过和离开的复合写法 // $(".nav>li").hover(function() { // 鼠标经过的函数 // $(this).children("ul").slideDown(200); // 向下滑出 // }, function() { // 鼠标离开的函数 // $(this).children("ul").slideUp(200); // 向上滑动 // }); // 事件切换 hover 只写一个函数,那么鼠标经过和离开都会触发这个函数 $(".nav>li").hover(function() { $(this).children("ul").stop().slideToggle(); // 滑动切换 });
3.4 动画队列 / 停止排队
动画队列:多次触发 造成 多个动画排队执行
stop() 停止排队:写到动画的 前面,立刻开始当前操作,忽略之前操作
3.5 淡入淡出效果
- fadeIn([speed,[easing],[fn]]) 淡入效果
- fadeOut([speed,[easing],[fn]]) 淡出效果
- fadeToggle([speed,[easing],[fn]]) 淡入淡出切换效果
- fadeTo([[speed],opacity,[easing],[fn]]) 渐进调整到 指定的不透明度
- 渐进调整到 指定的不透明度的参数 opacity(0-1) 透明度、speed 必须写
- 高亮显示分析:
$(".wrap li").hover(function() { //鼠标经过时,其他li 透明度:0.5 $(this).siblings().stop().fadeTo(400, 0.5); }, function() { // 鼠标离开,其他li 透明度改为 1 $(this).siblings().stop().fadeTo(400, 1); })
3.6 自定义动画 animate
- animate(params,[speed],[easing],[fn])
- params:想要更改的样式属性,以 对象形式 传递,必写,其余参数可省略
- speed:速度(“slow”,“normal”, or “fast”) 或 毫秒数
- easing:指切换效果,默认是“swing”,可用参数“linear”
- fn: 回调函数,动画完成时执行的函数,每个元素执行一次
$("button").click(function() { $("div").animate({ // 想要更改的样式属性 用对象存储 必写 left: 500, top: 300, opacity: .4, width: 500 }, 500); // 速度 }))
3.7 王者手风琴效果分析
- 鼠标经过某个 li 有两步操作:
- 当前小 li 宽度变为 224px,同时里面的小图片淡出,大图片淡入
- 兄弟小 li 宽度变为 69px,小图片淡入, 大图片淡出
<script type="text/javascript"> $(function() { $(".king li").mouseenter(function() { // 鼠标经过某个小li 有两步操作: // 1.当前小li 宽度变为 224px, 同时里面的小图片淡出,大图片淡入 $(this).stop().animate({ width: 224 }).find(".small").stop().fadeOut().siblings(".big").stop().fadeIn(); // 2.其余兄弟小li宽度变为69px, 小图片淡入, 大图片淡出 $(this).siblings("li").stop().animate({ width: 69 }).find(".small").stop().fadeIn().siblings(".big").stop().fadeOut(); })}); </script> <div class="king"> <ul> <li class="current"> <a href="#"> <img src="images/m1.jpg" alt="" class="small"> <img src="images/m.png" alt="" class="big"> </a> </li> // ... </ul> </div>
4.JQuery 属性操作
4.1 元素固有属性值 prop()
- 元素固有属性:元素本身自带的属性,比如 <a> 元素的 href ,比如 <input> 元素的 type
- 获取属性:prop(''属性'')
- 设置属性:prop(''属性'', ''属性值'')
$("a").prop("title", "特特喜欢茶茶"); // 修改元素固有属性 $("input").change(function() { // input框 内容改变事件 console.log($(this).prop("checked")); // 获取元素固有属性(获取选中状态) });
4.2 元素自定义属性值 attr()
- 元素自定义属性:用户自己添加的属性,比如给 div 添加 index =“1”
- 获取属性:attr(''属性''),类似原生 getAttribute(),如果获取 H5自定义属性 需要添加 data-
- 设置属性:attr(''属性'', ''属性值''),类似原生 setAttribute()
$("div").attr("index", 4); // 设置自定义属性的值 console.log($("div").attr("data-index")); // 获取自定义属性的值 如果获取 H5自定义属性 需要添加 data-
4.3 数据缓存 data()
- data() :在指定元素上存取数据,不会修改 DOM 元素结构,一旦页面刷新,之前的数据将被移除
- data("index") 可以读取 HTML5 自定义属性 data-index ,可以不加"data-",且得到的是 数字型
- 获取数据:date(''name'')
- 附加数据:data(''name'',''value'')
$("span").data("uname", "meow"); // 设置数据缓存 刷新后消失 console.log($("span").data("uname")); // 读取数据缓存
5.JQuery 文本属性值
5.1 针对 元素的内容 / 表单的值 操作
- 普通元素内容 html()( 相当于原生 innerHTML)
- 普通元素文本内容 text() (相当于原生 innerText)
- 表单的值 val()( 相当于原生 value)
6.JQuery 元素操作
- 遍历、创建、添加、删除元素操作
6.1 遍历元素
- 隐式迭代是对 相同元素 做 相同操作,想要给 相同元素 做 不同操作,需要 遍历
- $("div").each(function (index, domEle) {...})
- each() 方法用于遍历元素,用 DOM 处理
- 回调函数有 2 个参数: index 是元素索引号; demEle 是 DOM元素对象,不是 JQuery对象,只能用 DOM 方法
- 要想使用 JQuery方法,需要转换为 JQuery对象: $(domEle)
<div>1</div> <div>2</div> <div>3</div> <script> $(function() { var sum = 0; var arr = ["red", "green", "blue"]; // 指定要添加的颜色数组 $("div").each(function(i, domEle) { // 遍历 div元素 获取 div编号 和每个 div本身 $(domEle).css("color", arr[i]); // 将 每个div 转换为 jQuery元素 调用jQuery方法添加样式 sum += parseInt($(domEle).text()); // 获取元素字符串内容 转换为整数格式相加 }) console.log(sum);
- $.each(object,function (index, element) {...})
- $.each()方法用于遍历对象,用于数据处理,比如数组,对象
- 回调函数有 2 个参数: index 是元素索引号; element 遍历内容
$.each({ name: "TeaMeow", age: 20 }, function(i, ele) { console.log(i); // 输出的是 name age 属性名 console.log(ele); // 输出的是 TeaMeow 20 属性值 })})
6.2 创建、添加、删除元素
6.2.1 创建元素:
- $(''<li></li>'');
6.2.2 添加元素:
- 内部添加:是父子关系
- element.append(''内容'') :把内容放入 元素内部 后面,类似原生 appendChild
- element.prepend(''内容'') :把内容放入 元素内部 前面
- 外部添加:是兄弟关系
- element.after(''内容'') :元素外部后面
- element.before(''内容''):元素外部前面
- 返回指定祖先:parents("")
<div class="one"> <div class="two"> <div class="three"> <div class="four"> 特特养茶不易QAQ </div> </div></div></div> <script> console.log($(".four").parent().parent().parent()); console.log($(".four").parents(".one")); </script>
6.2.3 删除元素:
element.remove():删除元素本身
- element.empty():删除元素内容(子节点)
- element.html(''''):清空元素内容(子节点)
- empt() 和 html('''') 作用等价,都可删除元素内容,只不过 html 还可以设置内容
<ul> <li> 原先的li </li> </ul> <div class="test"> 原先的div </div> <script> $(function() { // 1. 创建元素 var li = $("<li> 我是后来创建的li </li>"); var div = $("<div> 我是后来创建的div </div>"); // 2. 添加元素 // $("ul").append(li); 内部添加并且放到内容的最后面 $("ul").prepend(li); // 内部添加并且放到内容的最前面 // $(".test").after(div); $(".test").before(div); // 3. 删除元素 // $("ul").remove(); 可以删除匹配的元素 自杀 // $("ul").empty(); // 可以删除匹配的元素里面的子节点 孩子 不可以写入 $("ul").html(""); // 可以删除匹配的元素里面的子节点 孩子 可以写入 })
6.3 购物车分析
6.3.1 购全选模块分析:
- 全选思路:小复选按钮(j-checkbox)选中状态(checked)跟着全选按钮(checkall)走
- checked 是复选框的 固有属性,需要用 prop()方法 获取和设置该属性
- 把 全选按钮状态 赋值给 小复选框 即可
- 每次点击小复选框按钮,就判断:小复选框被选中的个数 = ?,以此决定是否选择全选按钮
- checked 选择器 :checked 查找被选中的表单元素
6.3.2 购物车增减商品数目 / 修改商品小计分析:
- 增减商品数量分析:
- 核心思路:声明一个变量,当点击+号(increment),就让这变量++,然后赋值给 数目文本框
- 注意1: 只能增加本商品的数量, 就是当前+号的兄弟文本框(itxt)的值
- 注意2: 这个变量初始值 是 数目文本框的值,在数目文本框值的基础上++,用 val()方法修改表单的值
- 减号(decrement)思路同理,但是要判断文本框的值是否是 1,是就不能再减了
- 修改商品小计分析:
- 核心思路:每次点击+号或-号,文本框的值 x 当前商品的价格 = 商品小计
- 注意1: 只能增加 当前商品的小计(p-sum),修改普通元素的内容用 text()方法
- 注意2: 当前商品的价格,要把¥符号去掉再相乘,截取字符串 substr(从第几个字符开始截取,截取多长)
- parents(‘选择器’) 可以返回 指定祖先元素
- 最后计算的结果,通过 toFixed(2) 方法,保留 2 位小数
- 用户如果直接修改表单值,同样要计算小计,表单 change 事件
- 用户修改的新的表单值 x 单价 = 当前商品小计
6.3.3 计算总计和总和分析:
- 核心思路:所有文本框的值相加 就是总计,总额同理
- 文本框里面的值不同,相加用 each 遍历,声明一个和变量,相加即可
- 点击+号-号,会改变总计和总额;用户修改文本框的值,同样会改变总计和总额
- 因此可以封装函数求总计总额, 以上操作调用此函数即可
- 总计是文本框的值,相加用 val() ,总额是普通元素的内容,相加用text()
- 普通元素的内容要去掉¥,并且转换为数字型,才能相加
6.3.4 购物车删除商品 / 选中商品添加背景分析:
- 有三个删除: ① 商品后面的删除按钮 ②删除选中的商品 ③清理购物车
- 商品后面的删除按钮: 是删除当前的商品,所以从 $(this) 出发
- 删除选中的商品: 先判断小复选框按钮是否选中,如果选中,则删除对应的商品
- 清理购物车:把所有商品全部删掉
$(function() { // 1. 全选模块 把全选按钮(checkall)的状态赋值给 三个小的按钮(j-checkbox) $(".checkall").change(function() { // 全选按钮状态改变事件 // 给小按钮 下方全选按钮 设置元素自带属性checked ,设置值是上面全选按钮的自带属性 checked状态 $(".j-checkbox, .checkall").prop("checked", $(this).prop("checked")); if ($(this).prop("checked")) { // 如果已经全选 $(".cart-item").addClass("check-cart-item"); // 让所有商品加 check-cart-item 类 } else { $(".cart-item").removeClass("check-cart-item"); // check-cart-item 移除 } }); // 2. 如果小复选框被选中的个数等于3 就把全选按钮选上,否则全选按钮不选 $(".j-checkbox").change(function() { // $(".j-checkbox:checked").length 被选中的个数, $(".j-checkbox").length 所有小复选框个数 if ($(".j-checkbox:checked").length === $(".j-checkbox").length) { $(".checkall").prop("checked", true); // 如果被选中个数=总个数 那么选定全选 } else { $(".checkall").prop("checked", false); } if ($(this).prop("checked")) { // 如果当前小复选框被选中 小复选框的父亲=当前商品 $(this).parents(".cart-item").addClass("check-cart-item");// 让当前商品添加特殊样式类 } else { $(this).parents(".cart-item").removeClass("check-cart-item"); } }); // 3. 增减商品数量模块 首先声明一个变量,点击+号(increment),就让这个值++,然后赋值给表单框(商品数目) $(".increment").click(function() { // 加号被点击事件 var n = $(this).siblings(".itxt").val(); // 得到+号的兄弟元素:表单框的值(商品数目) n++; // 点击一次 商品数目就+1 $(this).siblings(".itxt").val(n); // 将处理后的 n 重新赋值给 表单框(商品数目) // 3. 计算小计模块 表单框的值 x 当前商品的价格 = 商品的小计 // 当前商品的价格 p +号的父亲(数目盒子)的兄弟(价格盒子)的值 var p = $(this).parents(".p-num").siblings(".p-price").html(); p = p.substr(1); // 将单价的第一个字符¥ 截掉到最后 var price = (p * n).toFixed(2); // 价格保留两位小数 // 小计模块 把价格赋值给小计 记得添加¥ 符号 $(this).parents(".p-num").siblings(".p-sum").html("¥" + price); getSum(); // 每次计算小计后 都要 重新计算总计 }); $(".decrement").click(function() { // 点击-号 原理看+号 var n = $(this).siblings(".itxt").val(); if (n == 1) { // 当数目是1 时 不可以继续点-号 所以返回false 阻止后面代码的执行 return false; } n--; $(this).siblings(".itxt").val(n); var p = $(this).parents(".p-num").siblings(".p-price").html(); p = p.substr(1); $(this).parents(".p-num").siblings(".p-sum").html("¥" + (p * n).toFixed(2)); getSum(); }); // 4. 用户修改表单框(商品数目)的值 计算小计模块 $(".itxt").change(function() { var n = $(this).val(); // 当前表单值(商品数目) var p = $(this).parents(".p-num").siblings(".p-price").html();// 当前商品单价 p = p.substr(1); $(this).parents(".p-num").siblings(".p-sum").html("¥" + (p * n).toFixed(2)); // 小计 getSum(); // 此时更改小计 要重新计算总计 }); getSum(); // 页面加载就计算总计 function getSum() { var count = 0; // 计算总件数 var money = 0; // 计算总价钱 $(".itxt").each(function(i, ele) { // 遍历表单框(商品数目) count += parseInt($(ele).val()); // 获取每个表单框的内容 并转换为 整数形式 求和 }); $(".amount-sum em").text(count); // 修改总计商品数目为 count $(".p-sum").each(function(i, ele) { // 遍历 商品小计 money += parseFloat($(ele).text().substr(1)); // 获取小计截取¥后的内容 转换为浮点 求和 }); $(".price-sum em").text("¥" + money.toFixed(2)); // 修改商品总计 保留两位小数 } // 6. 删除商品模块 // (1) 商品后面的删除按钮 $(".p-action a").click(function() { $(this).parents(".cart-item").remove(); // 删除的是当前商品模块(删除按钮的祖先元素) getSum(); // 删除后要重新计算总计 }); // (2) 删除选中的商品 $(".remove-batch").click(function() { $(".j-checkbox:checked").parents(".cart-item").remove();// 删除的是小复选框的祖先 getSum(); // 删除后要重新计算总计 }); // (3) 清空购物车 删除全部商品 $(".clear-all").click(function() { $(".cart-item").remove(); getSum(); // 删除后要重新计算总计 })})
效果展示:
7.JQuery 尺寸、位置操作
7.1 JQuery 尺寸
- 以上参数为空,则获取相应值,返回数字型
如果参数为数字,则修改相应值, 参数可以不写单位7.2 JQuery 位置
- 位置主要有三个: offset()、position()、scrollTop()/scrollLeft()
- offset() 设置或获取 元素偏移
- offset() 方法:设置或返回 被选元素相对于 文档 的偏移坐标,跟父级没关系
- offset().top:获取距离文档 顶部的 距离,offset().left:获取距离文档 左侧的 距离
- 可以设置元素的偏移:offset({ top: 10, left: 30 });
console.log($(".son").offset()); console.log($(".son").offset().top); // $(".son").offset({ top: 200, left: 200 });
- position() 获取 元素偏移
- position() 方法:返回(不能设置) 被选元素相对于 带有定位的父级 偏移坐标,如果父级没定位,则以文档为准
- position().top:获取距离定位父级顶部的距离,position().left:获取距离定位父级左侧的距离
- scrollTop()/scrollLeft() 设置或获取 元素被卷去的部分
- scrollTop() 方法:设置或返回 被选元素被卷去的头部
7.3 带有动画的返回顶部分析
- 核心原理: 使用 animate动画 返回顶部
- animate动画函数里面的 scrollTop属性,可以设置位置
- 是元素做动画,不可以写成 document!因此 $(“body,html”).animate({scrollTop: 0})
$(function() { $(document).scrollTop(100); // 页面滚动事件 var boxTop = $(".container").offset().top; $(window).scroll(function() { if ($(document).scrollTop() >= boxTop) { $(".back").fadeIn(); } else { $(".back").fadeOut(); }}); // 返回顶部 $(".back").click(function() { $("body, html").stop().animate({ // 不是 document做动画 而是 html和body元素做动画 scrollTop: 0 });})})
7.4 品优购电梯导航
- 滚动到 今日推荐 模块,电梯导航显示,点击电梯导航可以滚动到相应内容区域
- 核心算法:电梯导航模块 和 内容区模块 一一对应
- 点击电梯导航某个小模块,就可以拿到当前小模块的 索引号
- animate 要移动的距离:当前索引号对应的内容区模块的offset().top
- 点击电梯导航某个小 li, 当前小 li 添加 current类,兄弟移除类名
- 页面滚动到内容区域某个模块, 左侧电梯导航相对应的小 li 模块,也会添加 current类, 兄弟移除 current类
- 触发的事件是 页面滚动,因此这个功能要写到页面滚动事件里面
- 需要用到 each,遍历内容区域大模块,拿到内容区域每一个模块元素和索引号
- 判断条件: 被卷去的头部 >= 内容区域每个模块的offset().top
- 利用这个索引号 找到相应的电梯导航 给对应小 li 添加类
$(function() { // 点击小li 此时不需要执行 页面滚动事件里的 li 的背景选择 添加 current // 节流阀 互斥锁 var flag = true; // 1.显示隐藏电梯导航 var toolTop = $(".recommend").offset().top; toggleTool(); // 页面加载进来就要判断一下是否能显示电梯 function toggleTool() { if ($(document).scrollTop() >= toolTop) { $(".fixedtool").fadeIn(); } else { $(".fixedtool").fadeOut(); };} $(window).scroll(function() { toggleTool(); // 窗口滚动也要判断是否可以显示电梯 // 3. 页面滚动到某个内容区域,左侧电梯导航小li 相应添加删除 current类 if (flag) { $(".floor .w").each(function(i, ele) { // 遍历主页.W部分的模块 if ($(document).scrollTop() >= $(ele).offset().top) { $(".fixedtool li").eq(i).addClass("current").siblings().removeClass(); }})}}); // 2. 点击电梯导航页面可以滚动到相应内容区域 $(".fixedtool li").click(function() { flag = false; // 点击电梯导航导致页面滚动 页面滚动就会不断顺序添加 current 此时不需要此效果 $("body, html").stop().animate({ // 点击 li 后给 bodyhtml做动画到相应索引号位置 scrollTop: $(".floor .w").eq($(this).index()).offset().top; }, function() { flag = true; // 打开节流阀 利用回调函数 点击动画做完后 页面滚动时添加current类 效果继续触发 }); $(this).addClass("current").siblings().removeClass(); })})
三.jQuery 事件
1.JQuery 事件注册
- 单个事件注册 :$(“div”).click(function(){ 事件处理程序 })
2.JQuery 事件处理
2.1 事件处理 on() 绑定事件
- element.on(events,[selector],fn):绑定一个或多个事件的事件处理函数
- on() 方法优势1:可以绑定多个事件,多个处理事件处理程序
// on() 方法优势1:可以绑定多个事件,多个处理事件处理程序 $(“div”).on({ mouseover: function(){}, mouseout: function(){}, click: function(){} }); // 如果事件处理程序相同 $(“div”).on(“mouseover mouseout”, function() { $(this).toggleClass(“current”); });
- on() 方法优势2:事件委派,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素
// on() 方法优势2:事件委派,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素 $('ul').on('click', 'li', function() { alert('hello world!'); });
- on() 方法优势3:动态创建的元素,click() 没办法给动态创建的元素绑定事件, on() 可以
// on() 方法优势3:动态创建的元素,click() 没办法给动态创建的元素绑定事件, on() 可以 $(“div").on("click",”p”, function(){ alert("我可以给动态生成的元素绑定事件") }); $("div").append($("<p>我是动态创建的p</p>"));
2.2 发布微博案例分析
- 点击发布按钮,动态创建一个小li,放入文本框内容和删除按钮, 并且添加到 ul 中
- 点击删除按钮,删除当前的微博留言
$(function() { // 1.点击发布按钮, 动态创建一个小li,放入文本框的内容和删除按钮, 并且添加到ul 中 $(".btn").on("click", function() { var li = $("<li></li>"); li.html($(".txt").val() + "<a href='javascript:;'> 删除</a>"); $("ul").prepend(li); li.slideDown(); // 向下滑出显示 $(".txt").val(""); // 清空文本内容 }) // 2.删除当前的微博留言li on 可以给 动态创建的元素 绑定事件 $("ul").on("click", "a", function() { $(this).parent().slideUp(function() { // a 的父亲li,先向上滑动,再删除 $(this).remove(); });})}) <div class="box" id="weibo"> <span>微博发布</span> <textarea name="" class="txt" cols="30" rows="10"></textarea> <button class="btn">发布</button> <ul></ul> </div>
2.3 事件处理 off() 解绑事件
- off() 方法:移除通过 on() 方法添加的事件处理程序
- $("p").off():解绑元素 所有 事件处理程序
- $("p").off( "click"):解绑元素上面的 指定 事件
- $("ul").off("click", "li"):解绑 事件委托
- one() 方法:有的事件只想触发一次
$("div").on({ click: function() { console.log("我点击了"); }, mouseover: function() { console.log('我鼠标经过了'); }}); $("ul").on("click", "li", function() { alert("清除事件委托"); }); // $("div").off(); // 解除 div的所有事件 $("div").off("click"); // 解除 div的点击事件 $("ul").off("click", "li");// 解除事件委托 $("p").one("click", function() { // one() 只能触发事件一次 alert("我只能出现一次"); })
2.4 自动触发事件 trigger()
- 有些事件希望自动触发, 如轮播图的 自动播放功能 跟点击右侧按钮实现的功能一致
- 可以利用 定时器 自动触发 右侧按钮点击事件,而不必点击鼠标触发
- element.click():第一种简写形式
- element.trigger("type"):第二种自动触发模式
- element.triggerHandler(type):第三种自动触发模式(不会触发默认行为)
$("div").trigger("click"); // 会触发元素的默认行为 $("div").triggerHandler("click"); // 不会触发元素的默认行为
3.JQuery 事件对象
- 事件被触发,就会产生事件对象
- 阻止默认行为:event.preventDefault() 或者 return false
- 阻止冒泡: event.stopPropagation()
$(function() { $(document).on("click", function() { console.log("点击了document"); }) $("div").on("click", function(event) { console.log("点击了div"); event.stopPropagation(); // 组织事件冒泡 只会显示"点击了 div" })})
四.jQuery 其他方法
1.JQuery 拷贝对象
- $.extend([deep], target, object1, [objectN])
- 1. deep: 如果设为 true 为深拷贝, 默认为 false 浅拷贝
- 2. target: 要拷贝的目标对象
- 3. object1:待拷贝到第一个对象的对象
- 4. objectN:待拷贝到第N个对象的对象
- 5. 浅拷贝,引用被拷贝的对象地址,修改目标对象,会影响 被拷贝对象
- 6. 深拷贝,完全克隆,新开辟了空间存储,修改目标对象,不会影响 被拷贝对象
var targetObj = { // 原品 id: 0, msg: { sex: '男' } }; var obj = { // 复制品 id: 1, name: "andy", msg: { age: 18 } }; // // 1. 浅拷贝 把原来对象 复杂数据类型地址 拷贝给目标对象 // targetObj.msg.age = 20; 设置原来对象的msg age=20 // 2. 深拷贝 把数据完全复制一份,若有不冲突的属性,会合并 $.extend(true, targetObj, obj);
2.多库共存
- 多库共存:让 JQuery 和其他的 JS库 不存在冲突
- 把 $ 符号 统一改为 jQuery。 比如 jQuery(''div'')
- jQuery 变量规定新的名称:$.noConflict() var xx = $.noConflict();
// 1. 如果$ 符号冲突 我们就使用 jQuery jQuery.each(); // 2. 让jquery 释放对$ 控制权 让用自己决定 var suibian = jQuery.noConflict(); suibian.each();
3.JQuery 插件
- jQuery 插件常用的网站:
- jQuery 插件库: http://www.jq22.com/
- jQuery 之家: http://www.htmleaf.com/
- 图片懒加载:当页面滑动到可视区域,再显示图片,可提高网页速度,减轻服务器负载
- 使用 jQuery插件库 EasyLazyload,此时 JS引入文件 和 JS调用 必须写到 DOM元素(图片)最后
- 全屏滚动(fullpage.js)
- gitHub: https://github.com/alvarotrigo/fullPage.js
- 中文翻译网站: http://www.dowebok.com/demo/2014/77/
4.toDoList 分析
- 文本框输入内容,按下回车,生成待办事项。
- 点击待办事项复选框,把当前数据 添加到 已完成事项
- 点击已完成事项复选框,把当前数据 添加到 待办事项
4.1 页面内容刷新后不会丢失(localStorage)
- 核心思路: 按下回车 / 点击复选框,都是把 本地存储数据 加载到 待办事项
- 存储数据格式:var todolist = [{ title : ‘xxx’, done: false}]
- 本地存储 localStorage 只能存储 字符串格式 ,因此需要 把对象转换为字符串: JSON.stringify(data)
- 获取本地存储数据,需要 把字符串转换为对象格式:JSON.parse()
4.2 按下回车把新数据添加到本地存储
- 页面中的数据,都要从本地存储里面获取,这样刷新页面不会丢失,所以先要把数据保存到本地存储
- 利用事件对象.keyCode,判断用户按下回车键(13)
- 声明一个数组,保存数据
- 先 读取 本地存储的数据(声明函数 getData()),放到数组里
- 之后把从表单获取的最新数据,追加到数组里
- 最后把数组 存储 到本地存储 (声明函数 savaDate())
4.3 本地存储数据渲染加载到页面
- 因为后面会经常渲染 加载,所以声明一个函数 load(),方便后面调用
- 先要读取本地存储数据(数据不要忘记转换为对象格式)
- 之后遍历这个数据($.each()),有几条数据,就生成几个小 li 添加到 ol 里
- 每次渲染之前,先把原先 ol 的 内容清空,然后渲染加载最新数据,不这么做会加载很多重复内容
4.4 toDoList 删除操作
- 点击 a链接,不是删除 li,而是删除本地存储对应数据
- 核心原理:先获取本地存储,删除对应数据,保存给本地存储,重新渲染列表 li
- 可以给 a链接 自定义属性 记录当前索引号
- 根据索引号删除相关的数据:数组的splice(i, 1)方法
- 存储修改后的数据,存储给本地存储
- 重新渲染加载数据列表
- 因为 a是动态创建的,使用 on方法绑定事件
4.5 正在进行和已完成选项操作
- 点击复选框,获取本地存储,修改对应数据属性 done 为当前复选框的 checked状态
- 之后保存数据到本地存储,重新渲染加载数据列表
- load 加载函数新增条件:如果当前数据的 done为 true 就是已经完成的,就把列表渲染到 ul 里
- 如果当前数据的 done 为 false,则是待办事项,就把列表渲染到 ol 里
4.6 统计正在进行个数和已经完成个数
- 在 load 函数里声明 2 个变量 :todoCount:待办个数,doneCount:已完成个数
- 遍历本地存储数据时, 如果数据 done为 false,则 todoCount++,否则 doneCount++
- 最后修改相应的元素 text()