目录
一、事件高级
1. 注册事件(绑定事件)
- 传统方式
- 方法监听注册方式
1.1 方法监听注册方式
- addEventListener()
eventTarget.addEventListener(type,listener[, useCapture])
特点:同一个元素同一个事件可以注册多个监听器
1.2 注册事件兼容性解决方案
function addEventListener(element, eventName, fn) {
//判断当前浏览器是否支持 addEventListener 方法
if(element.addEventListener){
element.addEventener(eventName, fn);
} else if(element.attchEvent){
element.attchEvent('on', + eventName, fn);
} else {
//相当于 element.onclick = fn;
element['on' + eventName] = fn;
}
}
1.3 删除事件
传统注册方式:元素.onclick = null;
方法监听注册方式:eventTarget.removeEventListener(type,listener[, useCapture])
2. DOM事件流
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流
事件流三个阶段
- 捕获阶段 document -> html -> body -> father -> son,第三个参数为true
- 当前目标阶段
- 冒泡阶段 son -> father -> body -> html -> document,第三个参数为false
3. 事件对象
div.onclick = function(event) {}
event就是一个事件对象,写到侦听函数的小括号内,当做形参来看。事件对象包含了什么内容与事件相关
3.1 event.target
event.target 返回触发事件的对象(元素)
与 this 不同,this 返回的是绑定事件的对象
4. 阻止事件冒泡
- 标准写法:利用事件对象里面的 stopPropagation() 方法
- 非标准写法(针对低版本浏览器):cancelBubble = true
5. 事件委托(代理、委派)
-
事件委托
事件委托也称为事件代理,在jQ中称为事件委派
-
原理
事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){//给父节点ul添加侦听器
e.target.style.background = 'pink'//点击li后背景颜色变为粉色
})
6. 常用鼠标事件
6.1.1.禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
doucument.addEventListener('contextmenu', function(e){
e.preventDefault();
})
6.1.2.禁止鼠标选中(selectstart开始选中)
doucument.addEventListener('selectstart', function(e){
e.preventDefault();
})
6.2 跟随鼠标的天使(案例)
分析:
- 鼠标不断移动,使用鼠标移动事件:mousemove
- 在页面内移动,给document注册事件
- 图片要移动距离,且不占位置,使用绝对定位
核心原理:
每次鼠标移动都会获得最新的鼠标坐标,把这个x,y坐标作为图片的top&left值就可移动图片
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e){
var x = e.pageX;//获取鼠标坐标
var y = e.pageY;
pic.style.left = x + 'px';//将鼠标坐标作为图片的top & left值,一定要加上单位 px
pic.style.right = y + 'px';
})
</script>
7. 常用键盘事件
键盘事件 | 触发条件 |
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 但不能识别功能键 |
1、keyup 按键弹起时触发
document.addEventListener('keyup', function(){
console.log('我弹起了');
})
2、keydown 按键按下的时候触发
document.addEventListener('keydown', function(){
console.log('我按下了down');
})
3、keypress 按键按下的时候触发 不能识别 ctrl、shift、左右箭头
document.addEventListener('keypress', function(){
console.log('我按下了press');
})
执行顺序:keydown -> keypress -> keyup
7.1 模拟京东按键输入内容案例
核心思路:检测用户是否按下了s键,如果按下了s,就把光标定位到搜索框内
方法:1. 使用键盘事件对象内 keyCode 判断用户按下的是否是s键
2. 搜索框获得焦点:使用js里面的 focus() 方法
<body>
<input type="text">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function(e) {
if (e.keyCode === 83) {
search.focus();
}
})
</script>
</body>
二、BOM
1. BOM概述
BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,核心对象是window
2. window对象的常见事件
2.1 窗口加载事件 onload
window.onload = function( ){ }
window.addEventListener('load', function( ){ });
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等),就调用的处理函数。可以将JS写在任意地方。
window.onload传统注册方式只能写一次,addEventListener没有限制。
<head>
<script>
window.onload = function(){
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
alert('点击我')
})
}
window.addEventListener('load', function(){
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
alert('点击我')
})
})
window.addEventListener('DOMContentLoaded', function(){
alter('1')
})
</script>
</head>
<body>
<button>点击</button>
</body>
拓展:DOMContentLoaded 是DOM 加载完毕,不包含图片、falsh、css等就可以执行,加载速度比 load 更快
2.2 调整窗口大小事件 onresize
window.onresize = function( ){ }
window.addEventListener('resize', function( ){ });
- 只要窗口大小发生像素变化,就会触发这个事件
- 经常利用这个事件完成响应式布局。window.innerWidth 当前屏幕的宽度
3. 定时器
- setTimeout() 时间到后就结束了这个定时器
window.setTimeout(调用函数/函数名, [延迟的毫秒数(默认0)] );
- setInterval() 每隔一个延时时间重复调用这个函数
window.setInterval(调用函数/函数名, [延迟的毫秒数(默认0)] );
- 清除定时器
setTimeout() -> window.clearTimeout(已定义的定时器名字) 取消了先前的定时器
setInterval() -> window.clearInterval(已定义的定时器名字)
3.1 5秒后自动关闭广告案例
核心思路:5秒后将广告隐藏起来
<body>
<img class="a">
<script>
var a = document.querySelector('.a');
setTimeout(function(){
a.style.dispaly = 'none';
},5000);
</script>
</body>
3.2 倒计时
核心思路:获取 当前时间-截止时间 = 所剩时间,开启定时器 setInterval(countDown , 1000),每隔一秒刷新
3.3 发送短信案例
分析:
- 按钮点击后,会禁用 disabled 为 true
- 同时按钮的内容会变化,button的内容通过 innerHTML 修改
- 按钮内秒数会变化需要用到定时器,定义一个变量
- 等到0时停止定时器,恢复按钮状态
<body>
手机号码 <input type="number"> <button>发送</button>
<script>
var btn = document.querySelector('button');
var time = 10; //剩余的秒数
btn.addEventListener('click', function() {
btn.disabled = true;
var timer = setInterval(function() { //定时器
if (time == 0) {//到时间恢复按钮
clearInterval(timer);//清除定时器
btn.disabled = false;
btn.innerHTML = '发送';
time = 10;
} else {//开始倒计时
btn.innerHTML = '还剩下' + time + '秒'; //button要用 innerHTML 修改
time--;
}
}, 1000);
})
</script>
</body>
3.4 this 指向问题
- 全局作用域或者普通函数中 this 指向全局对象 window
- 方法调用中谁调用 this 指向谁
- 构造函数中 this 指向构造函数的实例
4. JS执行机制
JS的最大特点是单线程,同一时间只能做一件事。
4.1 同步&异步
同步:前一个任务结束后再执行后一个任务
异步:在做这件事的同时还可以去处理其他事情。三种类型:普通事件、资源加载、定时器
4.2 执行机制
主线程执行栈分成了同步、异步两部分,先执行完全部同步任务,后执行异步任务放到任务队列最后。由于主线程不断的重复获取任务、执行任务...,所以这种机制被称为事件循环
5. location 对象
window对象提供了一个location属性用于获取或设置窗体的URL,并可以用于解析URL
URL:统一资源定位符,是互联网上标准资源的地址
语法格式:protocol://host[:port]/path/[?query]#fragment 协议-域名-路径
5.1 location 对象的属性
location对象属性 | 返回值 |
location.href | 获取或者设置整个URL |
.host | 返回主机(域名) |
.port | 返回端口号 如果未写返回 空字符串 |
.pathname | 返回路径 |
.search | 返回参数 |
.hash | 返回片段 #后面内容常见于链接 锚点 |
5.2 五秒后自动跳转页面
分析:
- 利用定时器做倒计时效果
- 时间到跳转页面
<body>
<button>点击</button>
<div>
您将在5秒内跳转到首页
</div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
var time = 4;
btn.addEventListener('click', function() {
location.href = 'http://www.bilibili.com'
})
setInterval(function() {
if (time == 0) {
location.href = 'http://www.bilibili.com';
} else {
div.innerHTML = '您将在' + time + '秒内跳转到首页';
time--;
}
}, 1000)
</script>
</body>
5.3 获取URL的数据
分析:
- 第一个页面有提交表单,action提交到index.html页面
- 利用URL的location.search参数,第二个页面使用第一个页面的参数,就实现了一个数据在不同页面之间传递的效果
- 第二个页面获取到了参数后需要提取参数
第一个页面
<body>
<form action="index.html">
用户名 <input type="text" name="uname">
<input type="submit" value="登录">
</form>
</body>
第二个页面
<body>
<div></div>
<script>
//1.去掉? 得到username=... ——> substr('起始的位置'.截取几个字符);
var params = location.search.substr(1);
//2.利用=号分割键和值 得到数组 ——> split('=')
var array = params.split('=');
var div = document.querySelector('div');
div.innerHTML = 'array[1]';
</script>
</body>
-
去掉? ——> substr('起始的位置'.截取几个字符);
-
利用=号分割键和值 ——> split('=')
5.4 location 对象的方法
方法 | 返回值 |
location.assign() | 跟href一样,可以跳转页面 |
.replace() | 替换当前页面,不记录历史,无法后退 |
.reload() | 重新加载页面,相当于刷新按钮 参数为true强制刷新 ctrl+f5 |
6. navigator 对象
navigator对象包含有关浏览器的信息,它有很多属性,最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值,可以判断用户使用哪个终端打开的页面。
7. history 对象
history对象方法 | 作用 |
back() | 后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能 1:前进一个页面 / -1:后退一个页面 |
三、PC端网页特效
1. 元素偏移量 offset 系列
使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等
offset系列属性 | 作用 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父级元素 如果父级都没有定位则返回body |
elemen.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 |
element.offsetWidth | 返回自身包括padding、边框、内容区宽度,返回数值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区高度,返回数值不带单位 |
1.2 offset 与 style 区别
offset | style |
可以得到任意样式表中的样式值 | 只能得到行内样式表中的样式值 |
offset 系列获得的数值没有单位 | style.width 获得带有单位的字符串 |
offsetWidth 包含 padding+border+width | style.width 获得不包含 padding 和 border 的值 |
offsetWidth 等属性是只读属性,只能获取不能赋值 | style.width 是可读写属性,可以获取也可以赋值 |
要获取元素大小位置用offset更适合 | 给元素更改值则需要用style改变 |
1.3 获取鼠标在页面中的坐标
思路:首先得到鼠标在页面中的坐标,其次得到盒子在页面中的坐标
鼠标的距离-盒子的距离=鼠标在盒子内的坐标
x坐标:x = e.pageX - this.offsetLeft y坐标:y = e.pageY - this.offsetTop
<body>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x:' + x + 'y:' + y;
})
</script>
</body>
1.4 模态框拖拽
<script>
//1.获取元素
var login = document.querySelector('.login');
var mark = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
//2.点击弹出层这个链接 link 让 mask和login显示出来
link.addEventListener('click', function() {
mask.style.display = 'block';
login.style.display = 'block';
})
//3.点击closeBtn就隐藏mask和login
closeBtn.addEventListener('click', function() {
mask.style.display = 'none';
login.style.display = 'none';
})
//4.开始拖拽 鼠标按下 mousedown、鼠标移动 mousemove、鼠标松开 mouseup
//(1) 当我们鼠标按下,就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', function(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
//(2) 鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener('mousemove', move)
function move() {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
//(3) 鼠标弹起就让鼠标移动事件移除
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove',move);
})
})
</script>
1.5 仿京东放大镜效果遮挡层跟随鼠标
.js代码
window.addEventLister('load', function() {
var preview_img = document.querySelector('.preview_img'); //商品图
var mask = document.querySelector('.mask'); //黄色遮罩层
var big = document.querySelector('.big'); //big大盒子
//1.当我们鼠标经过preview_img就显示 mask 遮挡层和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
//2.鼠标离开隐藏 mask 遮挡层和 big 大盒子
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
//3.鼠标移动的时候让黄色的盒子跟着鼠标移动
preview_img.addEventListener('mousemove', function() {
//(1)获得鼠标坐标
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
//(2)将鼠标坐标赋值给 mask 并让鼠标在mask中间
//(3) mask移动的距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
//(4) 给遮挡层一个限定范围:如果x坐标小于了 0 就让他停在 0 的位置
// 遮挡层的最大移动距离 maskMax
var maskMax = preview_img.offsetWidth - mask.offsetWidth
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= pmaskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 大图片移动的距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
var bigIMg = document.querySelector('.bigImg'); //商品大图片
// 大图片最大移动距离
var bigMax = bigIMg.offsetWidth - big.offsetWidth;
// 大图片移动距离
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';//注意大图是移动值为 负
bigIMg.style.top = -bigY + 'px';
})
})
总结:
- 左边的商品框内的遮罩层需要有限定范围,不能超过商品框
- 右边大细节图的移动距离也要有限定范围,按遮罩层的移动比例来移动
-
大图片移动的距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
-
大图片的移动距离为 负值
2. client 系列
client翻译过来就是客户端,使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等
client系列属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框大小 |
element.clientLeft | 返回元素左边框大小 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不包含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区的高度,不包含边框,返回数值不带单位 |
2.1 client和offset比较
返回包含边框的大小用offset,返回不包含边框的大小用clientWidth
2.2 淘宝 flexible.js 源码分析
立即执行函数:不需要调用,能立马自己执行的函数
(function() {})() / (function(){}()) ——作用:创建一个独立的作用域
// (1)
(function(a, b){
concole.log(a + b);
})(1, 2);
// (2)
(function sum(a, b){
console.log(a + b);
}(1, 2));
作用:独立创建了一个作用域,里面所有的变量都是局部变量,不会发生命名冲突的情况
- document.documentElement——获取 html 的根元素
- window.devicePixelRatio || 1——dpr 物理像素比 1:pc端 2:移动端
- pageshow——重新加载页面触发的事件,给windows添加
- a标签的超链接、F5或刷新按钮和前进后退按钮都会触发load事件
- e.persisted 返回true 说明如果这个页面是从缓存取过来的页面,也需要重新计算rem大小
3. scroll 滚动系列
使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等
3.1 仿淘宝固定右侧侧边栏
分析:
- 需要用到页面滚动时间scroll因为是页面滚动,所以事件源是document
- 滚动到某个位置,就是判断页面被卷上去的部值
- 页面被卷去的头部:可以通过window.pageYOffset获得,被卷去的左侧.pageXOffset
- 元素被卷去的头部:element.scrollTop
<script>
//1. 获取元素
var sliderbar = document.querySelector('.slider-bar'); //侧边栏
var banner = document.querySelector('.banner'); //头部区域
// banner.offsetTop就是被卷去头部的大小 一定要写到滚动的外面
var bannerTop = banner.offsetTop;
// 当侧边栏固定定位之后应该变化的数值
var sliderbarTop = sliderbar.offsetTop - bannerTop;
//获取main主体元素
var main = document.querySelector('.main'); //main模块
var goBack = document.querySelector('.goBack'); //返回顶部模块
var mainTop = main.offsetTop; //main到顶部的距离
//2. 页面滚动事件 scroll
document.addEventListener('scroll', function() {
//3. 当页面被卷去的头部≥bannerTop 此时侧边栏更改为固定定位
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed'; //固定
sliderbar.style.top = sliderbarTop + 'px';
} else {
sliderbar.style.position = 'absolute'; //滚动
sliderbar.style.top = '300px';
}
// 当页面滚动到 main 盒子,就显示返回顶部模块
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
</script>
小结:
- 不要写死,用 盒子到顶部的距离 与 页面被卷入头部的距离 来比较大小判断
div.offsetTop window.pageYOffset
4. 三大系列总结
- offset 系列经常用于获得元素位置 offsetLeft offsetTop
- client 用于获取元素大小 clientWidth clientHeight
- scroll 用于获取滚动距离 scrollTop scrollLeft
- 页面滚动的距离通过 window.pageYOffset 获得
5. mouseenter 和 mouseover 的区别
mouseenter | mouseover |
只会经过自身盒子触发 | 鼠标经过自身盒子会触发,经过子盒子还会触发 |
不会冒泡 | 单独会冒泡,和 mouseleave 搭配不会冒泡 |
6. 动画函数封装
6.1 动画实现原理
核心原理:通过定时器 setInterval() 不断移动盒子位置
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位才能使用 element.style.left
<body>
<div></div>
<script>
var div = document.querySelector('div');
var timer = setInterval(function() {
if (div.offsetLeft >= 400) {
//停止动画 本质是停止定时器
clearInterval(timer);
} else {
div.style.left = div.offsetLeft + 1 + 'px';
}
}, 30);
</script>
</body>
6.2 动画函数简单封装
函数需要传递2个参数,动画对象和移动到的距离
<body>
<div></div>
<span></span>
<script>
var div = document.querySelector('div');
var span = document.querySelector('span');
//封装动画函数 obj:标对象 target:目标位置
function animate(obj, target) {
var timer = setInterval(function() {
if (obj.offsetLeft >= target) {
//停止动画 本质是停止定时器
clearInterval(timer);
} else {
obj.style.left = obj.offsetLeft + 1 + 'px';
}
}, 30);
}
//调用函数
animate(div, 300);
animate(span, 200);
</script>
</body>
6.3 给不同元素记录不同定时器
将 var timer = ...更改为 obj.timer = setInterval(function() {}, 30);
每次调用该动画函数时,obj都会发生变化
6.4 缓动效果原理
让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路:
- 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
- 缓动动画公式:(目标值 - 现在的位置) / 10 作为每次移动的距离步长
- 停止的条件:让当前盒子位置等于目标位置就停止定时器
var step = Math.ceil((target - obj.offsetLeft) / 10);
obj.style.left = obj.offsetLeft + step + 'px';
6.5 缓动动画多个目标值之间移动
<body>
<span></span>
<button class="btn500">500</button>//点击移动到500
<button class="btn800">800</button>//点击移动到800
<script>
var div = document.querySelector('div');
var span = document.querySelector('span');
var button500 = document.querySelector('.btn500');
var button800 = document.querySelector('.btn800');
//封装动画函数 obj:标对象 target:目标位置
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;//计算步长值
step = step > 0 ? Math.ceil(step) : Math.floor(step);//判断步长值的正负
if (obj.offsetLeft == target) {
//停止动画 本质是停止定时器
clearInterval(obj.timer);
} else {
obj.style.left = obj.offsetLeft + step + 'px';
}
}, 40);
}
//按钮添加点击事件
button500.addEventListener('click', function() {
animate(span, 500);
})
button800.addEventListener('click', function() {
animate(span, 800);
})
</script>
</body>
小结:
- 来回移动需要对步长值进行判定:是正值步长往大取整,负值步长往小取整
6.6 动画函数添加回调函数
函数可以作为一个参数。将这个参数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调
function animate(obj, target, callback) {//callback形参
......
if (obj.offsetLeft == target) {
//停止动画 本质是停止定时器
clearInterval(obj.timer);
//回调函数写到定时器结束里面
if (callback) {//判断是否有回调函数
callback();//有回调函数执行回调函数
}
} ......
}, 40);
}
//调用函数
button800.addEventListener('click', function() {
animate(span, 800, function() {//callback实参为一个函数
span.style.backgroundColor = 'red';//当定时器结束后改变颜色
});
})
6.7 动画函数封装到单独JS文件内
- 单独新建一个JS文件,将函数保存到JS文件内
- 在HTML文件中引入.js文件,便可直接调用函数
- 若要添加回调函数要在.html文件调用函数地方写回调函数
7. 常见网页特效案例
7.1 网页轮播图
分析:
- 由左右按钮,底下小圆圈和轮播图片四个区域组成,轮播图区域为<ul>,每张图片再由<li>包裹
- 鼠标经过轮播图区域,左右按钮才显示出来;鼠标不点击左右按钮,轮播图也会自动切换;轮播图切换小圆圈也会变换
- 利用循环动态生成小圆圈,圆圈个数与图片张数一致,创建&插入节点
- 小圆圈的排他思想:点击当前小圆圈就添加current类,其余小圆圈移除该current类
- 点击小圆圈滚动图片,用到animate动画函数,注意:移动的是ul;核心算法:让图片滚动小圆圈的 索引号乘以图片的宽度 作为ul移动距离,是负值
- 图片无缝滚动原理:当图片滚动到克隆的最后一张图片时,让ul快速的、不做动画的跳到最左侧,left为0,同时num赋值为0,重新开始滚动图片
- 克隆第一张图片:克隆ul第一个li (深克隆:cloneNode(true)),添加到ul最后面; 注意:克隆图片要写在生成小圆圈之后,才不会出现多一个小圆圈的情况
- 左右按钮与小圆圈一起变化:定义变量circle
- 自动播放图片:添加定时器,使用手动调用右侧按钮点击事件 arrow_r.click()
- 节流阀:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数
代码:
- index.html
<body>
<div class="w">
<div class="main">
<div class="focus fl">
<!-- 左侧按钮 -->
<a href="javascript:;" class="arrow-l">
<
</a>
<!-- 右侧按钮 -->
<a href="javascript:;" class="arrow-r"> </a>
<!-- 核心的滚动区域 -->
<ul>
<li>
<a href="#"><img src="img/fn3.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="img/fn4.JPG" alt=""></a>
</li>
<li>
<a href="#"><img src="img/fn5.JPG" alt=""></a>
</li>
<li>
<a href="#"><img src="img/fn10.JPG" alt=""></a>
</li>
</ul>
<!-- 小圆圈 -->
<ol class="circle">
</ol>
</div>
</div>
</div>
</body>
- index.js
window.addEventListener('load', function() {
// 1. 获取元素
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
var focusWidth = focus.offsetWidth;
// 2. 鼠标经过focus 就显示隐藏左右按钮
focus.addEventListener('mouseenter', function() {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
clearInterval(timer);
timer = null; // 清除定时器变量
});
focus.addEventListener('mouseleave', function() {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function() {
//手动调用点击事件
arrow_r.click();
}, 2000);
});
// 3. 动态生成小圆圈 有几张图片,我就生成几个小圆圈
var ul = focus.querySelector('ul');
var ol = focus.querySelector('.circle');
// console.log(ul.children.length);
for (var i = 0; i < ul.children.length; i++) {
// 创建一个小li
var li = document.createElement('li');
// 记录当前小圆圈的索引号 通过自定义属性来做
li.setAttribute('index', i);
// 把小li插入到ol 里面
ol.appendChild(li);
// 4. 小圆圈的排他思想 我们可以直接在生成小圆圈的同时直接绑定点击事件
li.addEventListener('click', function() {
// 干掉所有人 把所有的小li 清除 current 类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下我自己 当前的小li 设置current 类名
this.className = 'current';
// 5. 点击小圆圈,移动图片 当然移动的是 ul
// ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是负值
// 当我们点击了某个小li 就拿到当前小li 的索引号
var index = this.getAttribute('index');
// 当我们点击了某个小li 就要把这个li 的索引号给 num
num = index;
// 当我们点击了某个小li 就要把这个li 的索引号给 circle
circle = index;
// num = circle = index;
console.log(focusWidth);
console.log(index);
animate(ul, -index * focusWidth);
})
}
// 把ol里面的第一个小li设置类名为 current
ol.children[0].className = 'current';
// 6. 克隆第一张图片(li)放到ul 最后面
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
// 7. 点击右侧按钮, 图片滚动一张
var num = 0;
// circle 控制小圆圈的播放
var circle = 0;
// flag 节流阀
var flag = true;
arrow_r.addEventListener('click', function() {
if (flag) {
flag = false; // 关闭节流阀
// 如果走到了最后复制的一张图片,此时 我们的ul 要快速复原 left 改为 0
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function() {
flag = true; // 打开节流阀
});
// 8. 点击右侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放
circle++;
// 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原
if (circle == ol.children.length) {
circle = 0;
}
// 调用函数
circleChange();
}
});
// 9. 左侧按钮做法
arrow_l.addEventListener('click', function() {
if (flag) {
flag = false;
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function() {
flag = true;
});
// 点击左侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放
circle--;
// 如果circle < 0 说明第一张图片,则小圆圈要改为第4个小圆圈(3)
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
circle = circle < 0 ? ol.children.length - 1 : circle;
// 调用函数
circleChange();
}
});
function circleChange() {
// 先清除其余小圆圈的current类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className = 'current';
}
// 10. 自动播放轮播图
var timer = setInterval(function() {
//手动调用点击事件
arrow_r.click();
}, 2000);
})
- animate.js
function animate(obj, target, callback) {
// console.log(callback); callback = function() {} 调用的时候 callback()
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 步长值写到定时器的里面
// 把我们步长值改为整数 不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
// 回调函数写到定时器结束里面
// if (callback) {
// // 调用函数
// callback();
// }
callback && callback();
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
7.2 返回顶部
滚动窗口至文档中的特定位置,页面滚动多少通过 window.pageYOffset 得到
将animate函数内跟left相关的变量替换为window.pageYOffset即可
goBack.addEventListener('click', function() {
// 里面的x和y 不跟单位的 直接写数字即可
// window.scroll(0, 0);
// 因为是窗口滚动 所以对象是window
animate(window, 0);
});
// 动画函数
function animate(obj, target, callback) {
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 步长值写到定时器的里面
var step = (target - window.pageYOffset) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (window.pageYOffset == target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
callback && callback();
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
window.scroll(0, window.pageYOffset + step);
}, 15);
}
7.3 筋斗云案例
鼠标经过某个li,筋斗云跟到当前li的位置;鼠标离开li后,筋斗云恢复到原来的位置;鼠标点击了某个li,筋斗云就留在了点击的这个li的位置
分析:
- 利用动画函数做动画效果
- 原先筋斗云的起始位置是0
- 鼠标经过某个li,把当前li的 offsetLeft 位置作为目标值即可,离开时把目标值设为0
- 点击某个li,就把li当前的位置存储起来,作为筋斗云的起始位置
<script>
window.addEventListener('load', function() {
var cloud = document.querySelector('.cloud');
var c_nav = document.querySelector('.c-nav');
var lis = c_nav.querySelectorAll('li');
var current = 0;//记录筋斗云的起始位置
for (var i = 0; i < lis.length; i++) {
//筋斗云移动到当前li的位置
lis[i].addEventListener('mouseenter', function() {
animate(cloud, this.offsetLeft);
})
//筋斗云离开后回到原位
lis[i].addEventListener('mouseleave', function() {
animate(cloud, current);
})
//点击li后筋斗云留在li上
lis[i].addEventListener('click', function() {
current = this.offsetLeft;
})
}
})
</script>
四、移动端网页特效
1. 触屏事件touch
touch对象代表一个触摸点
触屏touch事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在一个DOM元素上滑动时触发 |
touchend | 手指从一个DOM元素上移开时触发 |
<script>
// 1. 获取元素
// 2. 手指触摸DOM元素事件
var div = document.querySelector('div');
div.addEventListener('touchstart', function() {
console.log('我摸了你');
});
// 3. 手指在DOM元素身上移动事件
div.addEventListener('touchmove', function() {
console.log('我继续摸');
});
// 4. 手指离开DOM元素事件
div.addEventListener('touchend', function() {
console.log('轻轻的我走了');
});
</script>
1.1 触摸事件对象(TouchEvent)
TouchEvent 是一类描述手指在触摸平面的状态变化的事件,用于描述一个或多个触点,可以检测触点的移动、触点的增减
touchstart、touchmove、touchend三个事件都会各自有事件对象
触摸列表 | 说明 |
---|---|
touches | 正在触摸屏幕的所有手指的一个列表 |
targetTouches | 正在触摸当前DOM元素上的手指的列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
1.2 移动端拖动元素
- touchstart、touchmove、touchend可以实现拖动元素
- 拖动元素需要当前手指的坐标值,使用targetTouches[0]里面的pageX和pageY
- 移动端拖动原理:手指移动中,计算出手指移动的距离,用盒子原来的位置+手指移动的距离
- 手指移动的距离:手指滑动中的位置 - 手指刚开始触摸的位置
(1)触摸元素 touchstart:获取手指和盒子的初始坐标
(2)移动手指 touchmove:计算手指的滑动距离,并且移动盒子
<body>
<div></div>
<script>
var div = document.querySelector('div');
var startX = 0; //获取手指初始坐标
var startY = 0;
var x = 0; //获得盒子原来的位置
var y = 0;
div.addEventListener('touchstart', function(e) {
// 获取手指初始坐标
startX = e.targetTouches[0].pageX;
startY = e.targetTouches[0].pageY;
x = this.offsetLeft;
y = this.offsetTop;
});
div.addEventListener('touchmove', function(e) {
// 计算手指的移动距离: 手指移动之后的坐标减去手指初始的坐标
var moveX = e.targetTouches[0].pageX - startX;
var moveY = e.targetTouches[0].pageY - startY;
// 移动我们的盒子 盒子原来的位置 + 手指移动的距离
this.style.left = x + moveX + 'px';
this.style.top = y + moveY + 'px';
e.preventDefault(); // 阻止屏幕滚动的默认行为
});
</script>
</body>
2. 移动端常见特效
2.1 移动端轮播图
分析:
- ul宽度设定为图片数量*100%,图片宽度设定为100%
- 自动播放功能:开启定时器、使用 translate 移动、添加过渡效果
- 基础
var timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s';//过渡效果
ul.style.transform = 'translateX(' + translatex + 'px)';//移动
}, 2000);
- 无缝滚动
判断条件:等到图片滚动完毕再去判断,此时需要添加检测过渡完成事件 transitionend,此时图片去掉过渡效果
ul.addEventListener('transitionend', function() {
// 无缝滚动
if (index >= 3) {
index = 0;
// console.log(index);
// 去掉过渡效果 这样让我们的ul 快速的跳到目标位置
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度 去滚动图片
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
} else if (index < 0) {//索引号小于0,相当于倒着走,跳转到2
index = 2;
ul.style.transition = 'none';
// 利用最新的索引号乘以宽度 去滚动图片
var translatex = -index * w;
ul.style.transform = 'translateX(' + translatex + 'px)';
}
});
- 小圆点跟随移动新方法
classList属性,返回元素的类名、用于在元素中添加、移除及切换CSS类
添加类名:.classList.add('...')
删除类名:.classList.remove('...')
切换类名:.classList.toggle('...')
将ol里面li带有current类名的选出来去掉类名,让当前索引号的li加上 current
// 把ol里面li带有current类名的选出来去掉类名 remove
ol.querySelector('.current').classList.remove('current');
// 让当前索引号 的小li 加上 current add
ol.children[index].classList.add('current');
- 手指滑动轮播图(touchstart&touchmove)
本质就是移动端拖动元素,拖动时停止定时器,没有过渡效果
// 触摸元素 touchstart: 获取手指初始坐标
var startX = 0;
var moveX = 0; // 后面我们会使用这个移动距离所以要定义一个全局变量
var flag = false;
ul.addEventListener('touchstart', function(e) {
startX = e.targetTouches[0].pageX;
// 手指触摸的时候就停止定时器
clearInterval(timer);
});
// 移动手指 touchmove: 计算手指的滑动距离, 并且移动盒子
ul.addEventListener('touchmove', function(e) {
// 计算移动距离
moveX = e.targetTouches[0].pageX - startX;
// 移动盒子: 盒子原来的位置 + 手指移动的距离
var translatex = -index * w + moveX;
// 手指拖动的时候,不需要动画效果所以要取消过渡效果
ul.style.transition = 'none';
ul.style.transform = 'translateX(' + translatex + 'px)';
flag = true; // 如果用户手指移动过我们再去判断否则不做判断效果
e.preventDefault(); // 阻止滚动屏幕的行为
});
- 判断回弹方向(touchend)
移动距离大于某个像素就上下移动,小于某个距离就回弹到原来的位置
// 手指离开 根据移动距离去判断是回弹还是播放上一张下一张
ul.addEventListener('touchend', function(e) {
if (flag) {
// (1) 如果移动距离大于50像素我们就播放上一张或者下一张
if (Math.abs(moveX) > 50) {
// 如果是右滑就是 播放上一张 moveX 是正值
if (moveX > 0) {
index--;
} else {
// 如果是左滑就是 播放下一张 moveX 是负值
index++;
}
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
} else {
// (2) 如果移动距离小于50像素我们就回弹
var translatex = -index * w;
ul.style.transition = 'all .1s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}
}
// 手指离开的时候就重新开启定时器
clearInterval(timer);
timer = setInterval(function() {
index++;
var translatex = -index * w;
ul.style.transition = 'all .3s';
ul.style.transform = 'translateX(' + translatex + 'px)';
}, 2000);
});
2.2 返回顶部
滚动到某部分显示按钮,点击返回到顶部,scroll 页面滚动事件
var goBack = document.querySelector('.goBack');
var nav = document.querySelector('nav');
window.addEventListener('scroll', function() {
if (window.pageYOffset >= nav.offsetTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
});
goBack.addEventListener('click', function() {
window.scroll(0, 0);
})
2.3 click延时解决方案
原因:移动端屏幕双击会缩放页面
解决方案:
- 禁止缩放 <meta name="viewport" content="user-scalable=no">
- 利用touch事件自己封装这个事件解决300ms延迟
- 使用fastclick插件,(JS插件就是一个.js文件)
3. 移动端常用开发插件
3.1 fastclick插件
3.2 Swiper插件
3.3 superslide
http://www.superslide2.com/http://www.superslide2.com/
3.4 iscroll
https://github.com/cubiq/iscrollhttps://github.com/cubiq/iscroll
3.5 插件使用总结
- 确认插件实现的功能
- 去官网查看使用说明
- 下载插件
- 打开demo实例文件,查看需要引入的相关文件,并且引入
- 复制demo实例文件中的结构html,样式css以及js代码
3.6 移动端视频插件 zy.media.js
<body>
<div class="playvideo">
<div class="zy_media">
<video data-config='{"mediaTitle": "小蝴蝶"}'>
<source src="mov.mp4" type="video/mp4">
您的浏览器不支持HTML5视频
</video>
</div>
<div id="modelView"> </div>
</div>
<script>
zymedia('video', {
autoplay: false
});
</script>
</body>
4. 移动端常用开发框架
框架,顾名思义就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发
前端常用框架:Vue、Angular、React... (PC端、移动端都能开发)
前端常用移动端插件:swiper、superlide、iscroll...
五、本地存储
为了满足网页应用的各种需求,会经常在本地存储大量的数据,HTML5规范提出了相关解决方案
1. window.sessionStorage
- 生命周期为关闭浏览器窗口
- 在同一个页面下数据可以共享
- 以键值对的形式存储使用
1.1 存储数据
sessionStorage.setItem(key , value)
1.2 获取数据
sessionStorage.getItem(key)
1.3 删除数据
sessionStorage.removeItem(key)
1.4 删除所有数据
sessionStorage.clear( )
2. window.localStorage
- 生命周期永久生效,除非手动删除否则关闭页面也会存在
- 可以多窗口共享(同一浏览器可以共享)
- 以键值对的形式存储使用
2.1 存储数据
localStorage.setItem(key , value)
2.2 获取数据
localStorage.getItem(key)
2.3 删除数据
localStorage.removeItem(key)
2.4 删除所有数据
localStorage.clear( )
六、jQuery入门
1. jQuery概述
1.1 JavaScript库
即library,是一个封装好的特定的集合(方法和函数)。从封装一大堆函数的角度理解库,就是在这个库中,封装了很多预先定义好的函数在里面,比如动画animate、hide、show,比如获取元素等。
简单理解:就是一个JS文件,里面对我们原生js代码进行了封装,存放到里面。这样我们可以快速高效的使用这些封装好的功能,jQuery就是为了快速方便的操作DOM。
1.2 jQuery概念
是一个快速的、简洁的JavaScript库,提倡写更少的代码,做更多的事情
jQuery封装了JavaScript常用的功能代码,优化了DOM操作、事件处理、动画设计和Ajax交互
学习jQuery本质:就是学习调用这些函数(方法)
2. jQuery基本使用
2.1 下载
jQueryjQuery: The Write Less, Do More, JavaScript Libraryhttps://jquery.com/① 进入官网
② 选择想要的版本下载
③ 全选后复制粘贴将代码导入到vscode中
2.2 使用方式
- 在.html文件导入刚刚保存的jQuery文件,<script src="jquery.min.js"></script>
- 使用jQuery入口函数,写上要使用的jQuery的相应代码
2.3 jQuery入口函数
等着页面DOM加载完毕再去执行js代码
1. $(document).ready(function() {
$('div').hide();
})
2. $(function() {
$('div').hide();
})
2.4 jQuery的顶级对象 $
$ <=> jQuery,$是jQuery的别称,也是jQuery的顶级对象
2.5 jQuery对象和DOM对象
- DOM 对象: 用原生js获取过来的对象就是DOM对象
var myDiv = document.querySelector('div'); // myDiv 是DOM对象
- jQuery对象: 用jQuery方式获取过来的对象是jQuery对象。 本质:通过$把DOM元素进行了包装
$('div'); // $('div')是一个jQuery 对象
jQuery 对象只能使用 jQuery 方法,DOM 对象则使用原生的 JavaScirpt 属性和方法
- jQuery和DOM相互转换:要想使用js属性和方法需要把jQuery对象转换为DOM对象才能用
-
DOM对象转换为 jQuery对象:$(DOM对象)
-
jQuery对象转换为DOM对象:$('div')[index] / $('div').get(index) index是索引号
七、jQuery常用API
1. jQuery选择器
1.1 jQuery基础选择器
$("选择器") //里面选择器直接写CSS选择器即可,但是要加引号
名称 | 用法 | 描述 |
---|---|---|
ID选择器 | $("#id") | 获取指定ID的元素 |
全选选择器 | $("*") | 匹配所有元素 |
类选择器 | $(".class") | 获取同一类class的元素 |
标签选择器 | $("div") | 获取同一类标签的所有元素 |
并集选择器 | $("div, p, li") | 选取多个元素 |
交集选择器 | $("li.current") | 交集元素 |
1.2 隐式迭代
遍历内部DOM元素(伪数组形式存储)的过程就叫做隐式迭代
1.3 jQuery筛选选择器
语法 | 用法 | 描述 |
---|---|---|
:first | $('li:first') | 获取第一个li元素 |
:last | $('li:last) | 获取最后一个li元素 |
:eq(index) | $("li:eq(2)") | 获取到的li元素中,选择索引号为2的元素,索引号index从0开始 |
:odd | $("li:odd") | 获取到的li元素中,选择索引号为奇数的元素 |
:even | $("li:even") | 获取到的li元素中,选择索引号为偶数的元素 |
1.4 jQuery筛选方法
语法 | 用法 | 说明 |
---|---|---|
parent() | $("li").parent(); | 查找父级 |
children(selector) | $("ul").children("li"); | 相当于$("ul>li"),最近一级(亲儿子) |
find(selector) | $("ul").find("li"); | 相当于$("ul li"),后代选择器 |
siblings(selector) | $(".first").siblings("li"); | 查找兄弟节点,不包括自己本身 |
nextAll([expr]) | $(".first").nextAll() | 查找当前元素之后所有的同辈元素 |
prevAll([expr]) | $(".last").prevAll() | 查找当前元素之前所有的同辈元素 |
hasClass(class) | $('div').hasClass("protected") | 检查当前的元素是否含有某个特定的类,如果有,则返回true |
eq(index) | $("li").eq(2); | 相当于$("li:eq(2)"),index从0开始 |
1.5 排他思想
siblings(selector)=>查找兄弟节点,不包括自己本身
<body>
<button>快速</button>
<button>快速</button>
<button>快速</button>
<button>快速</button>
<button>快速</button>
<button>快速</button>
<button>快速</button>
<script>
$(function() {
// 1. 隐式迭代 给所有的按钮都绑定了点击事件
$("button").click(function() {
// 2. 当前的元素变化背景颜色
$(this).css("background", "pink");
// 3. 其余的兄弟去掉背景颜色 隐式迭代
$(this).siblings("button").css("background", "");
});
})
</script>
</body>
1.6 淘宝服饰精品案例
核心原理:鼠标经过左侧盒子某个li,就让内容盒子相对应图片显示,其余的图片隐藏
<script>
$(function() {
// 1. 鼠标经过左侧的小li
$("#left li").mouseover(function() {
// 2. 得到当前小li 的索引号
var index = $(this).index();
console.log(index);
// 3. 让我们右侧的盒子相应索引号的图片显示出来就好了
// $("#content div").eq(index).show();
// 4. 让其余的图片(就是其他的兄弟)隐藏起来
// $("#content div").eq(index).siblings().hide();
// 链式编程
$("#content div").eq(index).show().siblings().hide();
})
})
</script>
- jQuery得到当前元素索引号 $(this).index()
- 中间对应的图片可以通过 eq(index) 方法去选择
- 显示元素 show() 隐藏元素 hide()
- 运用排他思想siblings(selector),对应索引号图片显示,其他兄弟图片隐藏
- 运用链式编程节省代码量
2. jQuery样式操作
jQuery可以使用css方法来修改简单元素样式,也可以操作类,修改多个样式
2.1 修改样式css方法
- 参数只写属性名,则返回属性值
- 参数是属性名,属性值,逗号分隔,是设置一组样式。属性必须加引号,值是数字可以不用加单位和引号
- 参数可以是对象形式,方便设置多组样式。属性名和属性值用冒号隔开,属性可以不加引号
2.2 修改样式操作类
- 添加类 addClass()
- 删除类 removeClass()
- 切换类 toggleClass()
2.3 tab栏切换案例
<script>
$(function() {
// 1.点击上部的li,当前li 添加current类,其余兄弟移除类
$(".tab_list li").click(function() {
// 链式编程操作
$(this).addClass("current").siblings().removeClass("current");
// 2.点击的同时,得到当前li 的索引号
var index = $(this).index();
console.log(index);
// 3.让下部里面相应索引号的item显示,其余的item隐藏
$(".tab_con .item").eq(index).show().siblings().hide();
});
})
</script>
- li:给li都加上current类,其余未被点击的兄弟li移除current
- item:对应索引号的item显示,其余item隐藏
3. jQuery效果
3.1 显示隐藏效果
语法规范:
显示 show([speed, [easing], [fn]])
隐藏 hide([speed, [easing], [fn]])
切换 toggle([speed, [easing], [fn]])
speed:表示动画时长的毫秒数值
easing:用来指定切换效果
fn:回调函数,在动画完成时执行的函数,每个元素执行一次
3.2 滑动效果
语法规范:
下滑动 slideDown([speed, [easing], [fn]])
上滑动 slideUp([speed, [easing], [fn]])
切换滑动 slideToggle([speed, [easing], [fn]])
- 事件切换
事件切换 hover,鼠标经过和鼠标离开都会触发这个函数
// 事件切换 hover 如果只写一个函数,那么鼠标经过和鼠标离开都会触发这个函数
$(".nav>li").hover(function() {
$(this).children("ul").slideToggle();
});
3.3 动画队列及其停止排队方法
stop( ) —— 用于停止上一个的动画效果,注意:stop方法必须写到动画前面
$(".nav>li").hover(function() {
// stop 方法必须写到动画的前面
$(this).children("ul").stop().slideToggle();
});
3.4 淡入淡出效果
语法规范:
淡入 fadeIn([speed, [easing], [fn]])
淡出 fadeOut([speed, [easing], [fn]])
淡入淡出切换 fadeToggle([speed, [easing], [fn]])
修改透明度 fadeTo([[speed], opacity, [easing], [fn]]) 透明度必须写,取值0~1之间
3.5 自定义动画animate
语法规范:
animate(params, [speed], [easing], [fn])
参数:
- params:想要更改的样式属性,以对象形式传递,必须写。
- speed:三种预定速度之一的字符串/表示动画时长的毫秒数值
- easing:(Optional)用来指定切换效果,默认是“swing”,可用参数“linear”
- fn:回调函数
案例:向右移动500px+向下移动300px+透明度变为40%+宽度变为500px
<script>
$(function() {
$("button").click(function() {
$("div").animate({
left: 500,
top: 300,
opacity: .4,
width: 500
}, 500);
})
})
</script>
3.6 王者荣耀手风琴效果
分析:
- 每个英雄介绍由两部分组成,小图片+大图片,小图片在大图片上面,初始只显示小图片
- 鼠标移动到相应小图片,宽度变为224px,小图片淡出,大图片淡入;相反其他的兄弟li,宽度变为69px,小图片淡入,大图片淡出
- 完善:①加上动画停止排队 ②计算好父div足够的宽度 ③动画移动速度合适
<script type="text/javascript">
$(function() {
// 鼠标经过某个小li 有两步操作:
$(".king li").mouseenter(function() {
// 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>
4. jQuery属性操作
4.1 设置或获取元素固有属性值 prop()
获取:prop("属性")
4.2 设置或获取元素自定义属性值 attr()
获取:attr("属性") 设置:attr("属性", "属性值")
4.3 数据缓存 data()
这个里面的数据是存放在元素的内存里面
附加数据:data("name", "value") 获取数据:data("name")
5. jQuery内容文本值
- 获取设置元素内容 .html()
- 获取设置元素文本内容 .text()
- 获取设置表单值 .val()
6. jQuery元素操作
6.1 遍历元素
jQuery隐式迭代是对同一类元素做同样的操作;要给同一类元素做不同操作要用到遍历
语法1:
$("div").each(function(index, domEle){ xxx; }) index 索引号 domEledom 元素对象
语法2:
$.each($("div"), function(index, domEle){ xxx; })
6.2 创建元素
语法:
$("<li></li>");
6.3 添加元素
(1)内部添加
element.append("内容") / element.prepend("内容")
append(li) 把内容匹配元素添加到最后面 ; prepend(li) 把内容匹配元素添加到最前面
(2)外部添加
element.after("内容") / element.before("内容")
after(li) 把内容放入目标元素后面; before()li 把内容放入目标元素前面
内部添加元素生成后是父子关系,外部添加元素生成后是兄弟关系
6.4 删除元素
语法:
① element.remove() //删除匹配的元素(本身)
② element.empty() //删除匹配的元素集合中所有的子节点
③ element.html("") //清空匹配的元素内容
7. jQuery尺寸、位置操作
语法 | 用法 |
---|---|
width()/height() | 取得匹配元素宽度和高度值 只算width/ height |
innerWidth()/ innerHeight() | 取得匹配元素宽度和高度值 包含padding |
outerWidth()/ outerHeight() | 取得匹配元素宽度和高度值 包含padding、border |
outerWidth(true)/ outerHeight(true) | 取得匹配元素宽度和高度值 包含padding、border、margin |
7.1 jQuery位置
位置主要有三个:offset、position、scrollTop()/scrollLeft
位置 | 用法 |
---|---|
offset() | 设置或获取元素偏移 |
position() | 获取元素偏移带有定位父级位置,没有父级以文档为标准 |
scrollTop()/scrollLeft() | 设置或获取元素被卷去的头部或左侧 |
八、jQuery事件
1. jQuery事件处理
1.1 事件处理 on() 绑定事件
on() 方法在匹配元素上绑定一个或多个事件的事件处理函数
语法:
element.on(events, [selector], fn)
1.1.1 on() 事件委托
$("ul").on("click", "li", function() {
alert(11);
});
click 是绑定在ul 身上的,但是触发的对象是 ul 里面的 li
1.1.2 on() 给未来动态创建的元素绑定事件
$("ol").on("click", "li", function() {
alert(11);
})
var li = $("<li>我是后来创建的</li>");
$("ol").append(li);
1.2 事件处理 off() 解绑事件
off() 方法可以移除通过 on() 方法添加的事件处理程序
语法:
$("p").off(...)
如果有的事件只想触发一次,可以使用 one() 来绑定事件
1.3 自动触发事件trigger()
可以利用定时器自动触发右侧按钮点击事件,不必鼠标点击触发
语法:
1、element.click()
2、element.trigger("事件")
3、element.triggerHandler("事件") 不会触发元素的默认行为
2. jQuery事件对象
事件被触发,就会有事件对象的产生
element.on(events, [selector], function(event) {})
阻止默认行为:event.preventDefault() / return false
阻止冒泡:event.stopPropagation()
九、jQuery其他方法导读
1. jQuery拷贝对象
语法:
$.extend([deep], target, object1, [objectN])
- 深拷贝:把里面的数据完全复制一份给目标对象 如果里面有不冲突的属性,会合并到一起
- 浅拷贝: 把原来对象里面的复杂数据类型地址拷贝给目标对象
2. jQuery多库共存
让jQuery和其他的js库不存在冲突,可以同时存在,就叫多库共存
解决方案:
- 把里面的$符号统一改为jQuery。比如jQuery("div")
- jQuery变量规定新的名称:$noConflict() var xx = $.noConflict();