1. 无缝的轮播怎么做
什么是无缝轮播?
有缝轮播.png
从第一张到倒数第二张图片还好,但是从最后一张图片到第一张图片就有问题了,并没有从最后一张图片直接切换到第一张图片,而是经过了中间的图片慢慢过渡到第一张图片(第一张图片到最后一张图片也同理),这显然不是预期的效果。问题既然已经发现了,就要去解决它,那么如何才能达到从最后一张图片直接切换到第一张图片(或第一张到最后一张),也就是无缝的效果,答案很简单,我们需要多一张图片(这张图片和第一张图片是相同的)放在图片列表的最后!为什么需要这样一张图片,请往下看。
我们在上面已经清楚要解决的就是首尾图片间的切换问题,所以在引入多一张图片之后,可以让轮播从倒数第二张图片(在没有引入图片之前的最后一张图片)切换到最后一张图片(新引入的图片)的动画完成之后,再瞬间跳转到第一张图片,请看下图(我把外面容器的overflow:hidden去掉了以便大家理解):
无缝轮播原理.png
-
把overflow:hidden加上,利用视觉差之后
无缝轮播.png
开始实现
Emmet.png
img[src="./$.png"][width=400[height=300][alert=图片]*5
Emmet 语法
image.png
image.png
box-sizing:border-box;//???什么意思
box-sizing.png
3s6s.png
9s12s.png
on('transitionend') 监听动画结束,让img回到可视window的右边
one('transitionend') 只监听最近的一次,监听执行完一次后就把这个监听器给删了
具体分析,拿3张图片测试要怎么移动,然后进行分析和抽象。
进行分析和抽象,图片有3种状态:current,leave,enter(状态机的概念)
- current:图片在当前可视window中
- leave:图片离开可视window,在window的左侧
- enter:图片进入可视window,在window的右侧
有3种状态,对应可以写3个类
css定义这3个类的位置等
js负责改变每个img的类↓
imgCss.png imgJs.png
- 优化1-使用setInterval定时器↓
$('.images > img:nth-child(1)').addClass('current')
$('.images > img:nth-child(2)').addClass('enter')
$('.images > img:nth-child(3)').addClass('enter')
let n = 1
setInterval(()=>{
$(`.images > img:nth-child(${x(n)})`).removeClass('current').addClass('leave')
.one('transitionend', (e)=>{
$(e.currentTarget).removeClass('leave').addClass('enter')
})
$(`.images > img:nth-child(${x(n+1)})`).removeClass('enter').addClass('current')
n += 1
},3000)
function x(n){
if(n>3){
n = n%3
if (n===0){
n =3
}
} // n = 1 2 3
return n
}
- 优化2-封装成函数
let n
初始化()
setInterval(()=>{
makeLeave(getImage(n))
.one('transitionend', (e)=>{
makeEnter($(e.currentTarget))
})
makeCurrent(getImage(n+1))
n += 1
},3000)
// 下面可以不看
function getImage(n){
return $(`.images > img:nth-child(${x(n)})`)
}
function x(n){
if(n>3){
n = n%3
if (n===0){
n =3
}
} // n = 1 2 3
return n
}
function 初始化(){
n = 1
$(`.images > img:nth-child(${n})`).addClass('current')
.siblings().addClass('enter')
}
function makeCurrent($node){
return $node.removeClass('enter leave').addClass('current')
}
function makeLeave($node){
return $node.removeClass('enter current').addClass('leave')
}
function makeEnter($node){
return $node.removeClass('leave current').addClass('enter')
}
一个注意事项:current的z-index要比其他的大,因为从leave改变位置到enter位置会从current的区域经过
.carouselWrapper .carouselBox > img.current{
transform: translateX(0);
z-index: 2;
}
2. DOM Events 知识
事件的历史.pngdomLevel的版本
dom level 2中的事件
image.png
https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html image.png
event flow, event capture, event bubbling(事件冒泡), mouse event, key events这些概念都是dom level 2中提出的,dom level3基本上没做修改,dom level 4还在草案阶段
dom level 1的知识
一道题,哪一个可以打印出hi?
image.png
答案:bcx
为什么bc是对的?
image.png
为什么x是对的?
image.png
在html中的onclick要加括号'()'
在js中的onclick不要加括号'()'
dom level2的知识
dom level1中的onclick和dom level 2中的addEventListener区别
-
onclick是一个属性,唯一的,会被覆盖
onclick.png
——只会打印3
-
addEventListener是一个队列,先进先出
addEventListener.png
——会打印出1和2,而且一定是先打印1再打印2,有顺序的
removeEventListener.png
——只会打印出2,因为f1和f3在add后被remove掉了,xxx的click事件只剩f2监听了
-
jquery中的one是怎么实现的?
image.png
——只会第一次点击的时候打印1,后面再次点击就不会打印1了(一次事件监听的实现)
-
另一个例子,关于冒泡?
image.png
复杂的需要画图理解
image.png
image.png
事件模型
-
true的走左边的队列(从上到下阶段,捕获阶段),false或不传的走右边的队列(从下到上阶段,冒泡阶段)
-
先捕获,后冒泡
-
如下,fn1是true,走左边,先执行。顺序是爷爷-儿子-爸爸
事件模型.png -
最后一个结点是先捕获还是先冒泡??
写的顺序 ???特例!!!就是写在点的元素本身上的event listener,不是按照先捕获后冒泡的顺序执行,而是按照写的顺序来执行
image.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>事件模型</title>
<style>
div{
padding: 30px;
border: 1px solid salmon;
}
</style>
</head>
<body>
<div id="grand1">
爷爷
<div id="parent1">
爸爸
<div id="child1">
儿子
</div>
</div>
</div>
<script>
// 1 当我点击儿子的时候,我是否点击了父亲和爷爷
// yes
// 2 当我点击儿子的时候,三个函数是否调用
grand1.addEventListener('click',function fn1(){
console.log('爷爷')
})
parent1.addEventListener('click',function fn2(){
console.log('爸爸')
})
child1.addEventListener('click',function fn3(){
console.log('儿子冒泡')
},false)
child1.addEventListener('click',function fn3(){
console.log('儿子捕获')
},true)
// yes
// 3 请问fn1,fn2,fn3的执行顺序
// 1-2-3 or 3-2-1?
// W3C 都可以
// falsy值: false, 0, NaN, '', null, undefined
// addEventListener不传第三个参数/传false 儿子-爸爸-爷爷
// addEventListener第三个参数传true 爷爷-爸爸-儿子
// 总结事件模型
// true的走左边的队列(从上到下阶段,捕获阶段),
// false或不传的走右边的队列(从下到上阶段,冒泡阶段)
// 先捕获,后冒泡
// 最后一个结点是先捕获还是先冒泡??
// 写的顺序 ???特例!!!就是写在点的元素本身上的event listener,不是按照先捕获后冒泡的顺序执行,而是按照写的顺序来执行
</script>
</body>
</html>
网友评论