事件绑定
利用on开头的时间 如onclick等
addEventListener
两者区别:同一个元素同一个事件,设置多个函数,以on开头的后面的会把前面的覆盖掉,addEventListener不会
html <button>传统注册事件</button> <button>方法监听注册事件</button> <script> var btns = document.querySelectorAll('button'); btns[0].onclick = function () { alert('hh') } btns[0].onclick = function () { alert('enen') } //弹出 'enen' btns[1].addEventListener('click', function () { console.log(1); }) btns[1].addEventListener('click', function () { console.log(2); })//分别弹出1 2
删除事件
传统将事件赋值为null
removeEventListener ,这里的函数要是具名函数
<div>1</div> <div>2</div> <div>3</div> //只打印一次 var divs = document.querySelectorAll('div'); divs[0].onclick = function () { console.log(1); divs[0].onclick = null; } divs[1].addEventListener('click', fn) function fn() { console.log(22); divs[1].removeEventListener('click', fn) }
DOM事件流
事件的传播分为三个阶段
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
先来一张图 捕获阶段

<div class="father">
father
<div class="son">son</div>
</div>
<script>
var son = document.querySelector('.son');
var father = document.querySelector('.father');
son.addEventListener('click', function () {
console.log(11)
}, true)
father.addEventListener('click', function () {
console.log(22)
}, true)
// 先输出22 在输出11
</script>
捕获阶段的原理:事件按照 document html body father son传播 ,当son点击时,从document开始捕获 ,father 有点击事件则触发 ,输出了22 ,然后son有点击事件输出了 11
js 中只能执行捕获或者冒泡其中的一个阶段
onclick 只到冒泡阶段
addEventListener的第三个参数为true表示在捕获阶段触发该程序,默认是false,
表示只能在冒泡阶段调用该程序
有些事件没有冒泡,如onblur , onfocus, onmouseenter, onmouseleave
事件对象 event
| 事件方法 | 说明 |
|---|---|
| e.target | 返回触发事件的对象 |
| e.type | 返回事件的类型,比如click mouseover |
| e.preventDefault( ) | 阻止默认行为 ,比如不让链接跳转 |
| e.stopPropagation | 阻止冒泡 |
事件委托
假如有如下场景:
<ul>
<li>改革春风吹满地</li>
<li>改革春风吹满地</li>
<li>改革春风吹满地</li>
<li>改革春风吹满地</li>
<li>改革春风吹满地</li>
</ul>
要求点击每个li都会弹出对话框,
//传统做法是这样的
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
alert('hhh')
}
}
事件委托的原理:不是每个子节点单独设置事件监听器, 将事件监听器设置在父节点上,利用冒泡的原理 ,每个子节点发生行为的时候,就会触发父节点相应行为
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
e.target.style.backgroundColor = 'pink'
})
动画函数封装
原理 :通过定时器 setInterval 不断移动盒子位置
步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上一个移动距离
- 使用定时器不断重复这个动作
- 加一个定时器结束的条件
- 注意此元素要添加定位,才能使用element.style.left
缓慢动画
让盒子每次移动的距离减小
思路:(目标值 - 现在的位置)/10
停止的条件是: 让当前盒子位置等于目标位置就停止定时器
加个回调函数 : 盒子停止运动的时候,执行回调函数
function animate(obj, target, callback) {
clearInterval(obj.time)
obj.time = setInterval(function () {
if (obj.offsetLeft == target) {
clearInterval(obj.time)
// if (callback) {
// callback()
// }
callback && callback();
}
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step)
obj.style.left = obj.offsetLeft + step + 'px'
}, 30)
}