✊不积跬步,无以至千里;不积小流,无以成江海
DOM事件模型
先经历从上到下的捕获阶段,再经历从下到上的冒泡阶段。
addEventListener(’click’,fn,true/false) 第三个参数可以选择阶段。
- 在第三个参数中,如果true就是放到捕获阶段;如果false就是冒泡或者不传
可以使用 event.stopPropagation() 来阻止捕获或冒泡。
- stopPropagation:阻止传播
DOM事件委托
实现方式:
ul.addEventLister('click'. function(e){
//点击的目标,的标签名,转换为小写,是否等于li
if(e.target.targerName.toLowerCase() === 'li'){
fn() // 执行某个函数
}
})
进行dom事件委托的:
好处:
-
节省监听器
- 假设ui里面有100个li,那么如果我就要写一百个li的监听器,但是有了事件委托,我只需要监听父元素ul即可
-
实现动态监听
- 对父元素监听时,无论是否拥有子元素都能实现监听,后续即使添加新的子元素也可以对子元素持续保持监听
坏处:
调试比较复杂,不容易确定监听者。
e.target & e.currectTarget 的区别
target是用户触发的对象 currectTarget是我监听的对象
target会经常变化,但是currectTarget是几乎不会变
手写拖拽div
参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="xxx"></div>
<script>
var dragging = false
var position = null
xxx.addEventListener('mousedown',function(e){
dragging = true //按下鼠标后定义一个变量为dragging
position = [e.clientX, e.clientY] //定义一个位置
})
document.addEventListener('mousemove', function(e){
if(dragging === false){return} //如没拖就返回
const x = e.clientX
const y = e.clientY
const deltaX = x - position[0] //现在的x减去按下后的x的差值
const deltaY = y - position[1]
const left = parseInt(xxx.style.left || 0) //获取最开始的left
const top = parseInt(xxx.style.top || 0)
xxx.style.left = left + deltaX + 'px' //把差值加到left上
xxx.style.top = top + deltaY + 'px'
position = [x, y] //下次移动的基准点
})
document.addEventListener('mouseup', function(e){
dragging = false //松开鼠标就把变量复原到false
})
</script>
</body>
</html>