面试复习题-dom

66 阅读2分钟

✊不积跬步,无以至千里;不积小流,无以成江海

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事件委托的:

好处:

  1. 节省监听器

    • 假设ui里面有100个li,那么如果我就要写一百个li的监听器,但是有了事件委托,我只需要监听父元素ul即可
  2. 实现动态监听

    • 对父元素监听时,无论是否拥有子元素都能实现监听,后续即使添加新的子元素也可以对子元素持续保持监听

坏处:

调试比较复杂,不容易确定监听者。

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>