1. 无缝轮播
实现方法一:
<head>
<meta charset="UTF-8">
<title>轮播</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="window">
<div class="images" id="images">
<img src="./image/1.png" alt="图片" width=400>
<img src="./image/2.png" alt="图片" width=400>
<img src="./image/3.png" width=400 alt="图片">
<img src="./image/4.png" alt="图片" width=400>
<img src="./image/5.png" alt="图片" width=400>
</div>
<div class="slideArray"></div> //知识点---1
</div>
<span id="button">
<button>第1张</button>
<button>第2张</button>
<button>第3张</button>
<button>第4张</button>
</span>
<script src="./jquery-3.3.1.js"></script>
<script src="./main.js"></script>
</body>
.images{
position: absolute;
display: none;
}
.window{
border: 1px solid blue;
width: 400px;
height: 280px;
margin: 20px auto;
overflow: hidden;
position: relative;
}
.window .slideArray{
position: relative;
width: 300%;
height: 100%;
top: 0;
left: -400px;
z-index: 1;
}
.window .slideArray img{
position: absolute;
top: 0;
transition: all 1s;
}
.window .slideArray img:nth-child(1){
left: 0px;
}
.window .slideArray img:nth-child(2){
left: 400px;
}
.window .slideArray img:nth-child(3){
left: 800px;
}
// setTimeout(function(){
// $slideArray.children().eq(0).remove()
// i_current += 1
// console.log(i_current)
// console.log(i_right)
// $slideArray.append($images.eq(i_right()).clone())
// },3000)
var $slideArray
var $images
var i_current
initialize()
var timerId = setInterval(function(){
makeCurrent()
i_current += 1
makeEnter()
},3000)
function initialize(){
$slideArray = $('.slideArray')
$images = $('#images').children()
i_current = 0
$slideArray.append($images.eq(i_left()).clone()) //知识点---2
$slideArray.append($images.eq(0).clone())
$slideArray.append($images.eq(i_right()).clone())
}
function i_left(){
return (i_current-1 >= 0) ? i_current : 4
}
function i_right(){
return (i_current+1)%5
}
function makeCurrent(){
$slideArray.children().eq(0).remove() //知识点---3
}
function makeEnter(){
$slideArray.append($images.eq(i_right()).clone())
}
知识点---1
知识点---2
知识点---3
2. DOM事件模型
DOM事件的开始:
在W3C指定DOM标准之前的各浏览器DOM事件统一算入 DOM Level 0。
关于DOM Leve 0 的一个小测试,下面代码中,哪些语法是正确的:
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script>
function print(){
console.log('hi')
}
</script>
</head>
<body>
<button id=X onclick="print">A</button> <!-- 1 -->
<button id=Y onclick="print()">B</button> <!-- 2 -->
<button id=Z onclick="print.call()">C</button> <!-- 3 -->
</body>
</html>
X.onclick = print // --- 4
Y.onclick = print() // --- 5
Z.onclick = print.call() // --- 6
答:2、3、4 可以实现。
解析:HTML 与 JS 是不同的语言,因此写法有可能不一样;
HTML 中:
onclick = "要执行的代码" // 一段代码,类型为字符串。
一旦用户点击,浏览器就 eval("要执行的代码").
------
关于eval:
function print(){
console.log('hi')
}
undefined
eval(print)
ƒ print(){
console.log('hi')
}
eval(print())
hi
JS 中:
X.onclick = print // 值的类型为 函数对象
Y.onclick = print() // 值的类型为 undefined
Z.onclick = print.call() // 值的类型为 undefined
一旦用户点击,那么浏览器就执行:
X.onclick.call(X,{}),.onclick 是对象 X 的一个属性,
X.onclick = print 就是一对键值,
2.1 DOM Leve 1
DOM Leve 1有两个版本,1998年与2000年;
DOM Leve 1(2000) 中只有两个章节,Events 并没有单独作为一章说明。
2.2 DOM Leve 2
DOM Leve 2 对 Events 做了单独的说明,并且说明的特别详细,在DOM Leve 3 中没有在单独成章再次说明,因此,目前的DOM Events 主要还是以DOM Leve 2的标准为主。
DOM Leve 2 小测试,两种 Event 语法的区别:
<body>
<button id=xxx onclick="print">xxx</button>
</body>
// DOM Leve 2 语法
xxx.addEventListener('click',function(){
console.log(1)
})
xxx.addEventListener('click',function(){
console.log(2)
})
//xxx 拥有一个队列 addEventListener ,队列里面可以随时增加 Event 而不会覆盖之前已有的 Event。
---------------------------------------------------------------------------------------
// DOM Leve 0 语法
xxx.onclick = function(){
console.log(3)
}
xxx.onclick = function(){
console.log(4)
}
// onclick 只是 xxx 的一个属性,而属性的值只会指向一个,后来的会覆盖以前的。
addEventListener 用法的进一步演示:
function f1(){
console.log(1)
}
function f2(){
console.log(2)
}
function f3(){
console.log(3)
}
xxx.addEventListener('click',f1)
xxx.addEventListener('click',f2)
xxx.removeEventListener('click',f1)
xxx.addEventListener('click',f3)
xxx.removeEventListener('click',f3)
----------------------------------
点击时,打印结果为:2。
每一种事件都有一个自己的单独的队列,click 有自己的;mouseLeave 也有自己的;
.one('click',function(){}) 是怎么实现的?
function f1(){
console.log(1)
xxx.removeEventListener('click',f1)
}
xxx.addEventListener('click',f1)
多层容器下,事件的执行,例:
<body>
<div id="grand1">
爷爷
<div id="father1">
爸爸
<div id="child1">儿子</div>
</div>
</div>
</body>
grand1.addEventListener('click',function f1(){
console.log('爷爷')
},undefined)
father1.addEventListener('click',function f2(){
console.log('爸爸')
},)
child1.addEventListener('click',function f3(){
console.log('儿子')
},)
1. 点击儿子时,是否也点击了爸爸和爷爷???
答:是。
2. 点击儿子时,三个函数是否调用???
答:是。
3. 点击儿子时,三个函数的调用顺序是 1 2 3 or 3 2 1???
答:默认情况下是 3 2 1。
w3c: 都可以。有第3个参数决定
false: undefined null '' 0 NaN
当第3个参数为 false值 时,顺序为 3 2 1,为true 时,顺序 1 2 3 。
child1.addEventListener('click',function f3(){
console.log('儿子1')
},)
child1.addEventListener('click',function f4(){
console.log('儿子2')
},)
4. 对同一个元素,执行顺序按队列来,先进先出。
画个图来理解:
事件模型:先捕获,后冒泡;即从 捕获 -> 冒泡;
哪一次事件的 第3个 参数为 true 则在捕获阶段执行,为 false 则在冒泡阶段执行。
那么,看下例:
方式1:
child1.addEventListener('click',function f3(){
console.log('儿子-捕获')
},true)
child1.addEventListener('click',function f3(){
console.log('儿子-冒泡')
},false)
--------------------------------------
方式2:
child1.addEventListener('click',function f3(){
console.log('儿子-冒泡')
},false)
child1.addEventListener('click',function f3(){
console.log('儿子-捕获')
},true)
方式1 与方式2 的执行顺序相同吗????
答:不同,What the fuck......
w3c:在事件的最内层元素上,不区分 捕获 与 冒泡,按队列规则来干。