事件
语法:btn:事件源:就是触发事件的dom元素
btn.addEventListener('click', function() {
console.log(123)
})
addEventListener:事件监听机制提供的一个方法,通过它可以为元素绑定一个事件,并且在事件触发之后,调用指定的函数一定要进行处理
click事件类型,是指用户所进行的操作,click代表单击,说明用户必须单击指定的元素才会触发事件
function(){}:事件触发之后的处理函数
一:代码整体的意思是:我让事件监听机制帮我去监听用户是否进行某个操作,同时给它提供一个处理函数,告诉它,如果用户真的进行了这个操作,那么调用我给的函数进行处理。
二:1.开发者并不知道用户什么时候进行某个操作,谁知道?事件监听机制知道,但是它不知道应该如何处理
三:用户单击之后应该如何进行处理,开发者知道,但是我不知道用户是否单击了按钮
四:所以调用函数的并不是我,而是事件监听机制。
案例分享
单击关闭二维码
<style>
.erweima {
position: relative;
width: 160px;
height: 160px;
margin: 100px auto;
}
span {
position: absolute;
left: -20px;
top: 0;
display: block;
width: 20px;
text-align: center;
border: 1px solid #ccc;
/* 鼠标效果 */
cursor: pointer;
}
</style>
</head>
<body>
<div class="erweima">
<img src="./images/code.png" alt="" />
<span> X </span>
</div>
<script>
let span = document.querySelector('span')
let erweima = document.querySelector('.erweima')
span.addEventListener('click', function () {
// 关闭二维码
erweima.style.display = 'none'
})
</script>
</body>
案例分享
随机点名
<style>
p {
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
</head>
<body>
<p>这里显示名字</p>
<button class="start">开始随机点名</button>
<button class="end">结束随机点名</button>
<script>
let names = [
'彭',
'徐',
'温',
'黄',
'徐',
'陈',
'王'
]
let p = document.querySelector('p')
let start = document.querySelector('.start')
let end = document.querySelector('.end')
let timeId, index
// 添加随机点名的效果
start.addEventListener('click', function () {
timeId = setInterval(function () {
index = parseInt(Math.random() * names.length)
p.innerHTML = names[index]
}, 100)
})
// 结束本次点名
end.addEventListener('click', function () {
// 停止定时器
clearInterval(timeId)
// 删除指定的姓名
names.splice(index, 1)
// 判断是否需要禁用按钮
if (names.length == 0) {
start.disabled = true
end.disabled = true
}
})
</script>
</body>
事件的其它的绑定方式
let btn = document.querySelector('button')
btn.addEventListener('click',function(){})
on事件类型
onclick,onfocus,onblur,onmouseenter。。。
btn.onclick = function() {
console.log(123)
}
常见的事件类型
按键事件
username.addEventListener('keydown', function() {
console.log('abc')
})
username.addEventListener('keyup', function() {
console.log('1234')
})
分别对应着键盘按键按下与弹起时触发的事件。
聚集事件
聚集事件:输入框获取焦点(光标)会触发聚集事件
username.addEventListener('focus', function() {
// console.log(123)
})
失集事件:输入框失去焦点(光标)会触发失集事件
username.addEventListener('blur', function() {
// console.log(456)
})
鼠标触发事件
button.addEventListener('mouseenter', function() {
ul.style.display = 'block'
})
button.addEventListener('mouseleave', function() {
ul.style.display = 'none'
})
分别对应鼠标悬停或离开时触发的事件。
其它事件类型
失焦事件
// 失焦事件:只要失去焦点,就会触发
// phone.addEventListener('blur', function() {
// console.log('blur')
// })
失焦事件change
// // 失焦事件change:失去焦点,同时内容变化 才会触发
// phone.addEventListener('change', function() {
// console.log('change')
// })
input事件
// // 为输入框添加input事件,只要内容变化 就会触发
// phone.addEventListener('input', function() {
// console.log(phone.value)
// })
案例分享
需求1 "单击全选复选框,让列表中的所有复选框的状态和全选的一致
首先获取元素
获取元素: 全选 -querySelector 列表中的所有复选框-querySelectorAll
let chkAll = document.querySelector('#checkAll')
let chks = document.querySelectorAll('.ck') // 伪数组,需要遍历使用
let all = document.querySelector('.all') // 全选复选框对应的文本
为全选元素chkAll添加 click/change 事件,在事件处理函数中
chkAll.addEventListener('click', function() {
// 2.1 先获取全选复选框的checked状态:true/false
let state = chkAll.checked
// 2.2 遍历列表中的所有复选框,为其checked属性设置状态
chks.forEach(function(ele, index) {
ele.checked = state
})
// 2.3 修改文本内容
all.innerHTML = state ? '取消' : '全选'
})
需求2:单击列表中的复选框,影响 全选复选框
-
1。经过本次单击,如果列表中的复选框全部选中,则全选也选中 -
2。经过这次单击,如果列表中的复选框有一个没有选中,则全选也取消选中
// 1.先为列表中所有复选框添加单击事件:遍历之后,一个一个绑定事件
chks.forEach(function (ele, index) {
// 为遍历出的复选框绑定事件
ele.addEventListener('click', function () {
// :checked:获取被选中的复选框
let state = document.querySelectorAll('.ck:checked').length == chks.length
chkAll.checked = state
all.innerHTML = state ? '取消' : '全选'
})
})
方法二:
// 1.先为列表中所有复选框添加单击事件:遍历之后,一个一个绑定事件
chks.forEach(function (ele, index) {
// 为遍历出的复选框绑定事件
ele.addEventListener('click', function () {
// 我先假设是被选中的
chkAll.checked = true
// 遍历列表中的所有复选框,但凡有一个没有选中,则全选也不选中,全部 选中了全选才选中
chks.forEach(function (ele) {
if (ele.checked == false) {
chkAll.checked = false
}
})
all.innerHTML = chkAll.checked ? '取消' : '全选'
})
})
案例分享--购物车加减操作
需求:用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
<body>
<div>
<input type="text" id="total" value="4" readonly />
<input type="button" value="+" id="add" />
<input type="button" value="-" id="reduce" />
</div>
<script>
// 用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
let add = document.querySelector('#add')
let reduce = document.querySelector('#reduce')
let total = document.querySelector('#total')
// +
add.addEventListener('click', function () {
// 1.获取文本框的值
let v = total.value
// 2.自增: ++会自动的转换类型为数值
v++
// 3.重新赋值
total.value = v
// 重新启用减
reduce.disabled = false
})
// -
reduce.addEventListener('click', function () {
// 1.获取文本框的值
let v = total.value
// 2.自减:--会自动的转换类型为数值
v--
// 3.重新赋值
total.value = v
// 如果值为1,则禁用按钮
if (v == 1) {
reduce.disabled = true
}
})
</script>
</body>
this的使用介绍
<script>
let btns = document.querySelectorAll('button')
btns.forEach(function (ele) {
// 当前谁触发的事件,谁就是事件处理函数中的this
// this是一个抽象对象
ele.addEventListener('click', function () {
console.log(this)
// ele.style.color = 'red'
this.style.color = 'red'
})
})
</script>
排他思想
这是一种编成的思维。 可以理解为先取消所有的,清楚所有的,再拿到自己想要的。
有种置之死地而后生的感觉哈哈哈
案例分享
<style>
ul {
list-style: none;
width: 600px;
display: flex;
height: 50px;
}
li {
flex: 1;
background-color: #ccc;
border-right: 1px solid blue;
line-height: 50px;
text-align: center;
}
.active {
background-color: orange;
}
</style>
</head>
<body>
<ul class="list">
<li class="active">首页</li>
<li>文章列表</li>
<li>发表文章</li>
<li>关于我们</li>
</ul>
需求:
-
1.单击li元素,在事件处理函数中 -
1.1.先清除所有li元素的active样式 -
1.2 为当前被单击的li元素添加active
let lis = document.querySelectorAll('li')
// 遍历,为每一个li元素绑定事件
lis.forEach(function (ele) {
ele.addEventListener('click', function () {
// 先清除所有li元素的active样式:遍历,拿到每一个li元素,添加样式
lis.forEach(function (subele) {
// 清除所有li中的active
subele.classList.remove('active')
})
// 为当前点击触发事件的元素添加active
ele.classList.add('active')
// ele.className = 'active'
})
})
上述案例优化写法,可以简化流程
let lis = document.querySelectorAll('li')
// 遍历,为每一个li元素绑定事件
lis.forEach(function(ele) {
ele.addEventListener('click', function() {
// 找到当前有active样式的li元素,清除这个li元素的active样式
// li.active:要求找到li元素,同时li元素有active样式 -- 交集选择器
document.querySelector('.list > li.active').classList.remove('active')
// 为当前被单击的li元素添加active
ele.classList.add('active')
})
})
tab栏案例分享
页面静态结构
<div class="wrapper">
<ul class="tab">
<li class="tab-item active">国际大牌<span>◆</span></li>
<li class="tab-item">国妆名牌<span>◆</span></li>
<li class="tab-item">清洁用品<span>◆</span></li>
<li class="tab-item">男士精品</li>
</ul>
<div class="products">
<div class="main active">
<a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
</div>
</div>
</div>
最终需要实现上述效果,点击不同的分类,对应出相应的页面。利用排他思想
// 获取元素
let lis = document.querySelectorAll('.wrapper li')
let mains = document.querySelectorAll('.products .main')
// 伪数组的使用先遍历
lis.forEach(function (ele, index) {
ele.addEventListener('click', function () {
// 排他li
// 获取有active样式的li元素,干掉它的active样式
document.querySelector('.wrapper li.active').classList.remove('active')
// 为当前被单击的li元素添加active样式
// lis[index].classList.add('active')
ele.classList.add('active')
// this.classList.add('active')
console.log(index);
// 排他main
document.querySelector('.products .main.active').classList.remove('active')
mains[index].classList.add('active')
})
})
案例分享
weibo发布案例
需要实现在文本域内输入内容的时候,下面的字数可以跟着响应相应的事件。
<body>
<div class="w">
<div class="controls">
<img src="images/tip.png" alt="" /><br />
<textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
<div>
<span class="useCount">0</span>
<span>/</span>
<span>200</span>
<button id="send">发布</button>
</div>
</div>
<div class="contentList">
<ul></ul>
</div>
</div>
<script>
// 用户输入文字,可以计算用户输入的字数:input
let area = document.querySelector('#area')
let useCount = document.querySelector('.useCount')
// 为文本域添加input内容改变事件
area.addEventListener('input', function () {
// 获取文本域的内容
let content = area.value
// 获取内容的长度
let count = content.length
// 将长度赋值 给批指定的元素
useCount.innerHTML = count
})
</script>
</body>
题目及说明分享
第一题
1.下列有关 获取元素的方法 描述错误的是(B C )
- A、document.getElementById方法会返回一个元素,如果获取不到元素,返回null
- B、获取id为box的元素写法可以如下:document.querySelector(“box”)
- C、document.querySelector方法无论有没有获取到元素,返回的都是伪数组
- D、document.querySelectorAll 方法返回的是个伪数组
题目解析:
- B:id类名获取需要添加“#”
- C:
querySelector方法获取的是满足条件的第一个元素,不是伪数组,所以D是对的
第二题
2.下列有关style属性 描述错误的是( D )
- A、style属性操作的是元素的行内样式
- B、设置背景图片写法:document.body.style.backgroundImage = “1.jpg”;
- C、设置字体大小:document.body.style.fontSize = “20px”;
- D、使用style设置比如字体大小font-size,背景颜色background-color等复合样式的时候,需要采用驼峰式写法
题目解析:
- D、可以用小驼峰,也可以使用
['font-size']['background-color']
第三题
3.关于DOM中获取元素的方法,下列说法正确的是 B
- A、document.querySelector('.box') 是获取页面id为box的元素;
- B、document.querySelector('.box') 是获取页面第一个类名为box的元素;
- C、document.querySelectorAll('.box') 是获取页面所有id为box的元素;
- D、document.querySelector('.box') 是获取页面所有类名为box的元素
题目解析:
- A: 获取的是类名为“box”的第一个符合条件的元素
- C: 获取的是类名为“box”的所有的符合条件的元素
- D: 获取的是第一个符合条件的元素,不是所有。
第四题
4.关于innerText与innerHTML下列说法正确的是( D )
- A、innerText与innerHTML作用完全一致,没有任何区别
- B、innerText属性里设置的标签可以被解析
- C、innerHTML获取内容的时候,如果内容中有HTML标签,标签会被忽略
- D、innerHTML获取内容得到的是一个包含HTML标签的字符串
题目解析:
- A、区别大了,一看就是错。innerHTML属性里设置的标签会被显示出来,形成完整的字符串
- B、不可,是被浏览器页面解析,innerText只是获取了非标签的字符串
- C、不会忽略,会形成字符串显示出来。
第五题
5.以下关于DOM的说法,错误的是( C )
- A: DOM提供了操作浏览器界面元素的一套方法
- B: DOM全称是文档对象模型,是将界面上的所有元素抽象成对象,使用对象的方式处理文档。
- C: 使用DOM可以修改浏览器的地址栏。
- D: 使用DOM可以获取到页面上的按钮
题目解析:
- C: BOM才可以修改
第六题
6.请说明querySelector和querySelectorAll的区别,你会分别在什么场合使用这两个方法呢?
题目解析:
-
querySelector 是用来获取第一个符合条件的元素的方法。
-
而querySelectorAll 则可以获取所有符合条件的元素,并且形成一个伪数组。并不能直接使用。
-
当只有一个元素需要被获取且使用的时候,使用querySelector
-
而当需要批量选中元素的时候,使用querySelectorAll比较合适,但是获取的是伪数组,要遍历才可使用。这个要注意。
第七题
7、在代码中一个 box 变量对应界面上的一个 div,如下哪段代码可以将这个div的背景颜色设置成为红色( C )
- A: box.className='red';
- B: box.style.background-color='red';
- C: box.style.backgroundColor='red';
- D: 以上方法都可以实现
题目解析:
- A: 这是修改元素内容的方式,并不能修改元素属性。
- B: 其中background-color需要使用小驼峰命名法,或者添加中括号及引号。
backgroundColor或['background-color']- D:骗谁呢,扯淡。
第八题
8.下列哪些方法可以获取到界面上所有的div( B E )
- A: document.getElementsByClassName('div');
- B: document.getElementsByTagName('div');
- C: document.querySelectorAll('.div');
- D: document.querySelector('div');
- E: document.querySelectorAll('div')
题目解析:
- A: ClassName是用来获取类名的,div是标签
- C: 方法没错,但是选择上错了,用了类名选择方法选择了标签。
- D: 选择没错,但是方法错了,这个方法只能获取第一个符合条件的元素。
第九题
9.下列有关 操作文本内容属性 描述错误的是( C )
- A、innerText属性不能识别标签
- B、使用innerHTML属性设置带标签的内容,标签可以起到效果
- C、可以使用innerText属性来获取文本域中用户输入的内容
- D、使用innerText和innerHTML在设置内容的时候都会覆盖原有内容
题目解析:
- A:innerText 可以识别标签并剔除,只显示非标签内容形成字符串。
- B:标签可以生效
- C: 错了,百度如下,jq方法如下
- 1.text()相当于innerText方法只能够获取到textarea的初始化文本值。
- 2.html():相当于innerHTML
- 2.val():value 方法不仅可以获取textarea的初始化文本值,当文本值改变时,也能正常获取到。
- 3.textarea也属于表单元数
第十题
10.请简述className和classList的区别,同时能不能大致说说应用场景,或者能不能在举例的时候说明为什么使用其中一个呢?
className可以选择直接选择类名样式,引用到当前元素,但是会覆盖原先的类名样式,在明确知道此影响不会出问题的时候可以使用,例如自己敲的代码,可以考虑。- 而
classList有四种常用的方法,分别如下。 classList.add(可以添加样式,可以选多个,并且是在之前的基础上添加的。不会照成覆盖。)classList.remove(可以删除选中的样式,可以选多个。)classList.toggle(可以理解为替换,只可以一次一个。如果本身就存在,就会删除该样式,如果不存在,则添加该样式上去)classList.contains(是一种判断方法,判断该样式是否存在在该元素内,如果存在,则返回ture 如果不存在,返回false)
第十一题
11.当添加了定时器setInterval之后,代码会立刻执行。请问这句话是否正确呢?如果你认为不正确,说说理由哦!!
- 错误的,立即执行的印象是因为设置的时间过短,从而忽略了时间。
- 正确的逻辑是,先执行设置的时间,时间到了才开始执行内部函数代码。 例如:
setInterval(function(){代码内容},5000)- 页面加载完成后-等待五秒-执行代码内容-等待五秒-执行代码内容如此循环。
第十二题
12.有如下代码:doms.style.color = 'red'
-
代码运行的时候有如下错误信息:
Uncaught TypeError: Cannot read properties of null (reading 'style') -
这个错误信息传递了什么信息,你如何解决这个错误呢?重点说下你以后怎么避免这种错误呢?
-
这个错误是指,无法读取
null的属性(读取“style”)。 -
我的理解是,获取流程是没问题的,不然会使undefined。而不是null
-
产生这样的问题的原因是因为获取的过程中选择器并没有选中元素。
-
解决问题就是重新判断选择器如何选中所需元素。
-
为了避免这样的错误,要在获取元素前,将元素类名,静态结构,都写好,然后才开始获取元素,然后才是添加样式。
-
null是标签没有可以被选中的元素。 -
而
undefined的话是获取就出问题了,没有获取成功。