DOM-事件基础
事件
本质:事件是在编程系统内发生的动作或者说是发生的事情
例如:我点了一下按键,我把鼠标移入了某个地方 都叫做事件
事件监听
作用:让程序检测是否有事件发生,根据发生的事件做出响应 也叫注册事件
语法:元素.addEventListener("事件",要执行的函数)
事件三要素:
事件源:那个DOM元素要事件触发? 先获取DOM
事件:用什么方式触发,鼠标点击click 鼠标经过mouseover等
调用函数:当事件触发,做什么样的行为?
<script>
let btn = document.querySelector(`button`)
btn.addEventListener(`click`,function(){
console.log(`开摆`)
})
let div =document.querySelector(`div`)
div.addEventListener(`mouseover`,function(){
console.log(`快进来`)
})
</script>
注意点:
1.事件类型要加引号
2.函数是事件发生之后再去执行,每触发一次事件,函数就执行一次
点击数字案例
<script>
let btn = document.querySelector(`button`)
let index = 1000
btn.addEventListener(`click`,function(){
// btn.innerText -= 7 第一种
// ++btn.innerText OK ++ -- 会做隐式转换
// btn.innerText += 1 不OK 数据类型是字符串不会隐式转换
// 第三种
index--
index -=6
btn.innerText = `(${index})`
if (index===-1){
alert(`没了,别点了`)
}
})
</script>
点击隐藏案例
<body>
<div>
<img src="./image/pic01.jpg" alt="">
</div>
<script>
let div = document.querySelector(`div`)
div.addEventListener(`click`,function(){
div.style.display = `none`
})
</script>
</body>
点击-随机点名案例(重要)
<script>
let h1 = document.querySelector(`h1`)
let but = document.querySelector(`button`)
let but1 = document.querySelector(`.button1`)
let arr = [`刘备`,`关羽`,`张飞`,`赵云`,`黄盖`,`黄忠`]
let timer //先是一个空篮子
// 定时器疯狂点击,疯狂开启多个定时器
/* 节流!!! (让我们程序一个一个一次一次执行 不要同时执行多个)
在一个定时器没有执行结束的时候 不能开启另外一个定时器 */
but.addEventListener(`click`,function(){
//在教timer的空篮子放了东西
timer= setInterval(function(){
/* 优化:
1.数组放里面,每跑一次就执行一次 用let都占据内存空间,所以放到外边
2.如果定时器业务多,可以提取出去封装
这里如何解决:
1.开启定时器 就禁用 不给你点击
2.清除定时器 就启用
1.在每一次开启定时器之前 都停止一次定时器*/
let index = Math.round( Math.random()*(arr.length-1) )
h1.innerHTML=arr[index]
},68)
but.disabled = true
but1.disabled = false
})
but1.addEventListener(`click`,function(){
//清除timer 篮子里的东西
clearInterval(timer)
but1.disabled = true
but.disabled = false
})
</script>
我的初步思路:
1.首先想到数组配合随机数
2.想到定时器
3.套上事件
总结:虽然做出,可是没有总体结构,思路尚不清晰 只是根据需求一步一步从上到下
优化点:
1.疯狂点击定时器,会疯狂生成定时器。引出节流知识点(让我们程序一个一个一次一次执行 不要同时执行多个)
解决方法:
点击就禁用按钮 .disable
在定时器最开始添加清除定时器 (实现原理)
2.把index随机值封装函数
优化后代码:
<script>
let h1 = document.querySelector(`h1`)
let but = document.querySelector(`button`)
let but1 = document.querySelector(`.but`)
let arr = [`刘备`,`关羽`,`张飞`,`赵云`,`黄盖`,`黄忠`]
let timeId
// 封装了随机index的函数
function geiRandom() {
let index = Math.round( Math.random()*(arr.length-1) )
h1.innerText = arr[index]
}
but.addEventListener(`click`,function(){
//一开始是undefined 所以来个判断 优雅!
if(timeId!==undefined){clearInterval(timeId)}
// 把封装函数拿进来,注意是函数,不是调用函数
timeId=setInterval(geiRandom,100)
})
but1.addEventListener(`click`,function(){
clearInterval(timeId)
})
</script>
老师思路:
1.不是从上到下一口气
2.而是从大体结构开始入手,分别测试功能
3.再在两个按钮中
点击-表单全选案例 (重要)
我的初步代码
<script>
let fick = document.querySelector(`#checkAll`)
let check = document.querySelector(`.ck`)
let check1 = document.querySelector(`.ck1`)
let check2 = document.querySelector(`.ck2`)
fick.addEventListener(`click`,function(){
if(fick.checked != false){
check.checked = true
check1.checked = true
check2.checked = true
}else if (fick.checked != true) {
check.checked = false
check1.checked = false
check2.checked = false
}
})
</script>
解题思路:
1.获取多个对面
2.监听事件
3.根据需求写 发现当全选框勾选时,我取消勾选框,也会全选
4.加条件判断
缺点:太不优雅,太低级
老师初步代码
<script>
let fick = document.querySelector(`#checkAll`)
let check = document.querySelector(`.ck`)
let check1 = document.querySelector(`.ck1`)
let check2 = document.querySelector(`.ck2`)
fick.addEventListener(`click`,function(){
check.checked=fick.checked
check1.checked=fick.checked
check2.checked=fick.checked
})
</script>
解题思路:
直接让列表中要选中的等于全选框选中的
缺点:当列表多,每一个都获取一下,麻烦,不优雅
老师优化后代码
<script>
let fick = document.querySelector(`#checkAll`)
let checkAll = document.querySelectorAll(`.ck`)
fick.addEventListener(`click`,function(){
for (let index = 0; index < checkAll.length; index++) {
checkAll[index].checked = fick.checked
}
})
// 老师最终思路,用数组配合循环,不管有多少列表,都能一步到位
</script>
优化案例
思考:如何实现当单选框全选时,全选框自动选上。取消一个单选框,全选框自动取消
<script>
let ck = document.querySelectorAll(`.ck`)
let checkAll = document.querySelector(`#checkAll`)
checkAll.addEventListener(`click`,function(){
for (let index = 0; index < ck.length; index++) {
ck[index].checked=checkAll.checked
}
})
for (let index = 0; index < ck.length; index++) {
ck[index].addEventListener(`click`,function(){
let checked = geic()
checkAll.checked = checked
})
}
function geic() {
let num = 0
for (let index = 0; index < ck.length; index++) {
if(ck[index].checked){
num++
}
}
if(num === ck.length){
return true
}else {
return false
}
}
</script>
思路:
1.给每一个单独的复选框绑定点击事件
2.什么时候需要让 全选 选中 /每一个都选择
什么时候需要让 全选 不选中/只要一个没选中
实现:
1.定义一个变量 就是选择的商品数量
一开始 num = 0
2.开始对商品循环
3.判断每一个商品选择状态
如果选择,让num++
4.循环结束 判断num 是不是和商品数组长度相同
相同就是全选上了 返回true
不相同 就是没有达到 返回false
最后整合代码
<script>
let ck = document.querySelectorAll(`.ck`)
let checkAll = document.querySelector(`#checkAll`)
checkAll.addEventListener(`click`,function(){
for (let index = 0; index < ck.length; index++) {
ck[index].checked=checkAll.checked
}
})
for (let index = 0; index < ck.length; index++) {
ck[index].addEventListener(`click`,function(){
let checked = geic()
checkAll.checked = checked
})
}
function geic() {
let num = 0
for (let index = 0; index < ck.length; index++) {
if(ck[index].checked){
num++
}
}
if(num === ck.length){
return true
}else {
return false
}
}
</script>
环境对象
本质:环境对象指的是函数内部特殊的变量this
作用与细节:
弄清楚this的方向,能让代码简洁
1.在前端的JS中,全局变量可以理解为windows的一个属性
2.谁调用,this就是谁
<script>
function show() {
console.log(this);
}
show()//输出windows
let huangmou = {
name:`黄某`,
function () {
console.log(this)
}
}
huangmou.function() //输出huangmou对象
</script>
3.小补充
编程思想
排他思想
本质:当前元素为A状态,其他为B状态
使用:
1.干掉所有
使用for循环
2.复活自己
通过this或下标找到自己或者对应的元素
<script>
let li = document.querySelectorAll(`li`)
// 第一种做法
for (let index = 0; index < li.length; index++) {
li[index].addEventListener(`click`,function(){
for (let index = 0; index < li.length; index++) {
li[index].classList.remove(`color`)
}
this.classList.add(`color`)
})
}
// 第二种做法
for (let index = 0; index < li.length; index++) {
li[index].addEventListener(`click`,function(){
// 把所有标签干成白色
for (let index = 0; index < li.length; index++) {
li[index].style.backgroundColor = `#fff`
}
// 给自己加红色
this.style.backgroundColor = `red`
})
}
</script>
综合案例
<script>
let lis =document.querySelectorAll(`li`)
let divs = document.querySelectorAll(`.products .main`)
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener(`click`,function(){
for (let index = 0; index < lis.length; index++) {
lis[index].classList.remove(`active`)
}
this.classList.add(`active`)
for (let index = 0; index < divs.length; index++) {
divs[index].classList.remove(`active`)
}
divs[index].classList.add(`active`)
})
}
</script>
解题思路:
1.确认点击事件
2.获取对象,循环遍历点击事件
3.排他思想的运用