事件处理
<button class="btn">按钮</button>
<script>
var btnEl = document.querySelector('.btn')
btnEl.addEventListener('click',function () {
console.log('第一个事件监听');
})
btnEl.addEventListener('click',function () {
console.log('第二个事件监听');
})
</script>
事件冒泡、捕获
事件是从最内层向外依次传递,这个顺序称之为
事件冒泡, 从外层到内层这种称之为事件捕获
<div class="box">
<span class="word"></span>
</div>
<script>
var bodyEl = document.body
var divEl = document.querySelector('.box')
var spanEl = document.querySelector('.word')
// true:设置监听事件捕获的过程,默认是事件冒泡
bodyEl.addEventListener('click',function () {
console.log('body被点击了');
},true)
divEl.addEventListener('click',function () {
console.log('div被点击了');
},true)
spanEl.addEventListener('click',function () {
console.log('span被点击了');
},true)
</script>
当一个事件发生时,就会有和这个事件相关的很多信息:这些信息会被封装到一个Event对象中,这个对象由浏览器创建,称之为event对象
<div class="box">
<button class="btn">按钮</button>
</div>
<script>
var divEl = document.querySelector('.box')
var btnEl = document.querySelector('.btn')
// 获取event对象
divEl.onclick = function (event) {
console.log(event);
}
</script>
event常见的属性和方法:
<div class="box">
<button class="btn">按钮</button>
</div>
<script>
var divEl = document.querySelector('.box')
var btnEl = document.querySelector('.btn')
divEl.onclick = function (event) {
console.log(event.type); // 事件类型: click
console.log(event.offsetX,event.offsetY); // 事件发生在元素内的位置
console.log(event.screenX, event.screenY); // 事件发生相对于屏幕的位置
// currentTarget/target
console.log(event.target); // 事件发生的对象
console.log(event.currentTarget); // 当前处理的对象
console.log(event.target === event.currentTarget); // 当事件冒泡时就会有区别
}
divEl.addEventListener('click',function (event) {
event.preventDefault() // 阻止默认行为
event.stopPropagation() // 阻止事件的进一步传递(冒泡或者捕获都可以阻止)
console.log(this === event.target); // true
})
</script>
EventTarget类:
EventTarget是一个DOM接口,主要用于添加、删除、派发Event事件
<button class="btn">按钮</button>
<script>
var btnEl = document.querySelector('button')
var foo = function () {
console.log('监听按钮的点击');
}
btnEl.addEventListener('click', foo)
// 过5秒后将事件监听移除
setTimeout(function () {
console.log('将事件监听移除');
btnEl.removeEventListener('click', foo)
}, 5000)
// eventTarget本身就可以实现类似于事件总线的效果
window.addEventListener('www', function () {
console.log('监听www的事件');
})
setTimeout(() => {
window.dispatchEvent(new Event('www')) // 自己派发一个事件
}, 2000)
</script>
事件委托
当子元素被点击时,父元素可以通过冒泡可以监听到子元素的点击;并可以通过
event.target获取到当前监听的元素
- 一个ul中存放多个li,点击某一个li会变成红色
<style>
.active {
color: orange;
font-size: 15px;
}
</style>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 需求一:一个ul中存放多个li,点击某一个li会变成红色
var liEls = document.querySelectorAll("li")
// 每一个li都箭头自己的点击
for (var liEl of liEls) {
liEl.onclick = function() {
this.classList.add('active')
// event.currentTarget.classList.add('active')
}
}
// 事件委托:统一在ul中监听
var ulEl = document.querySelector('ul')
ulEl.onclick = function (event) {
event.target.classList.add('active')
}
// 需求二:点击li变成active样式,其他的取消active样式
var ulEl = document.querySelector('ul')
var activeLiEl = null
ulEl.onclick = function (event) {
// 写法一:1.将之前的active移除
for (var i = 0; i < ulEl.children.length; i++) {
if (ulEl.classList.contains('active')) { // 有active才移除
ulEl.children[i].classList.remove('active')
}
}
// 写法二:1. 找到active之前,移除掉active
var activeEl = ulEl.querySelector('.active')
activeEl && activeEl.classList.remove('active') // 有值才会调用
// 写法三: 1.变量的记录方式(常用)
if (activeLiEl && event.target !== ulEl) {
activeLiEl.classList.remove('active')
}
// 2.给点击的元素添加active
if (event.target !== ulEl) {
event.target.classList.add('active')
}
// 3.记录最新的active对应的li
activeLiEl = event.target
}
</script>
</body>
- 多个按钮的点击,区分点击了哪一个按钮
<div class="btnList">
<button data-active="create">新建</button>
<button data-active="del">删除</button>
</div>
<script>
var btnList = document.querySelector('.btnList')
btnList.addEventListener('click',function (event) {
var active = event.target.dataset.active // 拿到active
switch (active) {
case 'create':
console.log('点击了新建按钮');
break
case 'del':
console.log('点击了删除按钮');
break
}
})
</script>
常见的鼠标事件
常见的表单事件
案例
- 定时器
setTimeout:n秒后再执行函数
setInterval: 重复运行一个函数,每过n秒调用一次函数
clearTimeout:取消setTimeout的定时器;
clearInterval:取消setInterval的定时器
<button class="out">取消setTimeout定时器</button>
<button class="itv">取消setInterval定时器</button>
<script>
function foo(name,age) {
console.log('执行函数',name,age);
}
var timeId = setTimeout(foo,2000,'www',19) // 2秒后再执行函数,可以传递参数
var timeClearEl = document.querySelector('.out')
timeClearEl.onclick = function () {
clearTimeout(timeId) // 取消调度
}
function bar() {
console.log('执行函数');
}
var itvId = setInterval(bar,3000) // 每过三秒调用一次函数
var itvEl = document.querySelector('.itv')
itvEl.onclick = function () {
clearInterval(itvId)
}
</script>