事件流
很多时候,一个事件可能会被多个元素监听。那么这些元素应该按什么顺序响应呢?从父到子称为捕获,从子到父称为冒泡。
事件捕获
可选参数,true or fause,带true代表按捕获方式响应
obj.addEventListener('click',function(){},true)
事件冒泡
默认为false,即按冒泡的方式相应
obj.addEventListener('click',function(){})
阻止流动
obj.addEventListener('click',function(e){e.stopPropagation()
})//事件在当前阶段停止流动,冒泡 or 捕获均可
阻止默认行为
有时候跳转链接,提交表单时可能出错,此种情况下不应该跳转,可以阻止默认行为
form.addEventListener('submit',function(e){e.preventDefault()
})
解绑事件
解除事件的绑定
- L0
btn.onclick() = function(){alert('clicked!')
}
// 解绑
btn.onclick = null
- L2
L2的匿名函数无法解绑
btn.addEventListener(‘click’, fun)
btn.removeEventListener('click', fun)
L0 和 L2两种注册方式的区别
事件委托
说白了,通过给父级元素注册监听器,产生事件的对象会含有若干信息,通过信息确定对父级元素内部哪个元素进行操作。好处是:减少了注册次数,提高了程序性能。将原先循环为每一个子对象进行监听,转为对父对象监听 ,然后内部通过分支语句选择操作的对象。
ul.addEventListener('click', function(e){if(e.target.tagName == 'LI') this.style.color = pink // this -> ul
})
其他事件
- 页面加载事件
可以将<script> <script>标签放在head里,等待页面加载完毕再执行
<script>window.addEventListener('load',function(){...all codes here...})})
</script>
// 另一种,只需要等待DOM结点加载完毕即可
<script>document.addEventListener('DOMContentLoaded',function(){...some codes here...})})
</script>
- 页面滚动事件
document.documentElement 指的是整个HTML
<script>window.addEventListener('scroll',function(){// 获取整个网页的滚动长度console.log(document.documentElement.scrollTop);})})
</script>
- 页面尺寸事件
当页面尺寸发生变换时触发
window.addEventListener('resize',function(){// codes
})
元素尺寸与位置
- 获取元素尺寸
- clientWidth,clientHeight
内容 + padding。 不加border值
- clientWidth,clientHeight
<script>const div = document.querySelector('div')console.log(div.clientHeight);</script>
- offsetWidth, offsetHeight
内容 + padding + border
<script>const div = document.querySelector('div')console.log(div.offsetWidth);</script>
- 获取元素相对位置
- offsetLeft、Height
获得的数值是子元素相距最近的带有定位的父元素的偏移量。如果都没有,以文档左上角为准 - 总结