事件(下)
事件的传播行为
- 捕获阶段(从最外层的元素(body)找到目标元素)
- 目标阶段(执行对应的对应的目标元素的事件)
- 冒泡阶段 (逐层向上冒泡 直到找到body为止)
事件的触发模式
冒泡模式 (默认)
<!--打印流程 button -> div -> body -->
<body onclick="console.log('body的事件')">
<div onclick="console.log('div的事件')">
<button onclick="console.log('button的事件')">点击</button>
</div>
</body>
禁止事件冒泡(event对象的方法)
-
stopPropagation 方法
e.stopPropagation() -
cancelBubble 属性
//cancelBubble属性 取消冒泡 默认为false e.cancelBubble = true -
兼容写法
e.stopPropagation? e.stopPropagation() : e.cancelBubble = true
捕获模式
默认行为
在某些内容中自带一些行为,这些被称为默认行为(a 标签跳转行为 form表单中的submit按钮提交行为 图片的拖动行为...)
默认行为默认是拥有的,也就是没有被禁止。
禁止默认行为的方法
-
preventDefault 方法
//禁止默认行为 e.preventDefault() //禁止默认行为 存储兼容问题 -
returnValue 属性
//兼容ie的写法 e.returnValue = false -
return false
//放到最后 解决禁止默认行为 return false -
兼容写法
e.preventDefault ? e.preventDefault() : e.returnValue = false
事件监听器(有兼容问题)
eventlistener (对象的俩个方法)
-
添加事件监听器 addEventListener
//添加事件监听器 给它进行一个监听 //第一个传入的是对应的事件名(任意事件名) 第二个传入是对应的处理函数 第三个参数为是否为捕获模式 //一个事件可以有多个处理函数 (发布者订阅者 观察者(observer)) btn.addEventListener('click',handler) btn.addEventListener('dblclick',handler,true) btn.addEventListener('click',function(){ console.log('你好事件') },true) btn.addEventListener('click',function(){ console.log('世界那么大') },true) function handler(){ console.log('你好') } -
移除事件监听器 removeEventListener
//removeEventListener 移除监听器 通过对应的处理函数和事件名 优先比对事件名 比对对应的处理函数及是否捕获 //只能移除对应的addEventListenter添加的 btn.removeEventListener('click',handler) //不能被移除 处理函数不是同一个 btn.removeEventListener('click',function(){ console.log('你好事件') },true)
注意事项
- 添加事件监听器必须传入俩个参数 一个为事件名一个为对应的处理函数 还可以传入第三个参数为是否捕获
- 移除事件监听器 必须保证传入的事件名一致 及对应的传入的处理函数为一个对象 以及第三个参数一致 才能移除
- removeEventListener只能移除addEventListener添加的事件监听
拖拽
全局拖拽
实现步骤
- 给需要拖拽的元素添加鼠标按下事件 (mousedown)
- 记录按下的位置 (记录当前元素内按下的坐标 e.offsetX, e.offsetY)
- 给document添加鼠标移动事件 (mousemove)
- 获取移动的位置 (e.pageX,e.pageY)
- 设置对应的拖拽元素的位置 (用页面的位置 - 当前的盒子内点击的位置 当前盒子在页面上的坐标)
- 给document弹起事件 (mouseup)
- 取消移动事件及弹起事件 (赋值为null)
<div></div>
<script>
//获取div
var div = document.querySelector('div')
//给div添加鼠标按下事件
div.onmousedown = function (e) {
e = e || window.event
//记录按下的位置 位于按下元素内的位置
var x = e.offsetX
var y = e.offsetY
//给document添加鼠标移动事件
document.onmousemove = function (e) {
e = e || window.event
//用页面的位置 - 当前的盒子内点击的位置 当前盒子在页面上的坐标
div.style.left = e.pageX - x + 'px'
div.style.top = e.pageY - y + 'px'
}
document.onmouseup = function () {
//取消移动事件及弹起事件
document.onmousemove = document.onmouseup = null
}
}
</script>
局部拖拽思路
实现思路
- 给需要拖拽的元素添加鼠标按下事件 (mousedown)
- 记录按下的位置 (记录当前元素内按下的坐标 e.offsetX, e.offsetY)
- 给外面的大盒子添加鼠标移动事件 (mousemove)
- 获取移动的位置 (e.pageX,e.pageY)
- 得到对应的拖拽元素的位置 (鼠标在页面的位置 - 大盒子离页面的位置 - 按下的位置)
- 区间判断 (不能小于0 不能大于(大盒子的大小-小盒子的大小)的距离)
- 设置位置
- 给document弹起事件 (mouseup)
- 取消移动事件及弹起事件 (赋值为null)
<div class="warp">
<div class="inner"></div>
</div>
<script>
var warp = document.querySelector('.warp')
var inner = document.querySelector('.inner')
//给需要拖拽的元素添加鼠标按下事件 (mousedown)
inner.onmousedown = function(e){
e = e || window.event
//记录当前元素内按下的坐标
var x = e.offsetX
var y = e.offsetY
//给外层盒子添加移动事件
warp.onmousemove = function(e){
e = e || window.event
//得到对应的拖拽元素的位置
var targetX = e.pageX - warp.offsetLeft - x
var targetY = e.pageY - warp.offsetTop - y
//区间判断
if(targetX < 0){
targetX = 0
}
if(targetY < 0){
targetY = 0
}
if(targetX > warp.clientWidth-inner.clientWidth){
targetX = warp.clientWidth-inner.clientWidth
}
if(targetY > warp.clientHeight -inner.clientHeight){
targetY = warp.clientHeight -inner.clientHeight
}
//设置位置
inner.style.top = targetY + 'px'
inner.style.left = targetX + 'px'
}
//给document添加弹起事件
document.onmouseup = function(){
warp.onmousemove = document.onmouseup = null
}
}
</script>
拖拽的方法封装
//设计一个方法来计算对应的盒子在页面的位置
function getPointToPage(element) {
//offset家族
//offsetParent 偏移的父元素
//offsetWidth 偏移元素的宽度
//offsetHeight 偏移元素的高度
//offsetLeft 基于偏移的父元素的左偏移量
//offsetTop 基于偏移的父元素的上偏移量
//如果对应的offsetParent没有值为null的时候停止 element为body
var point = {
x: 0,
y: 0
}
while (element.offsetParent) {
point.x += element.offsetLeft
point.y += element.offsetTop
//不断向上
element = element.offsetParent
}
return point
}
//拖拽的方法封装
function drag(dragElement,target) {
//给需要拖拽的元素添加鼠标按下事件 (mousedown)
dragElement.onmousedown = function (e) {
e = e || window.event
//记录当前元素内按下的坐标
var x = e.offsetX
var y = e.offsetY
//给外层盒子添加移动事件
target.onmousemove = function (e) {
e = e || window.event
//得到对应的拖拽元素的位置
var targetX = e.pageX - getPointToPage(target).x - x
var targetY = e.pageY - getPointToPage(target).y - y
//区间判断
if (targetX < 0) {
targetX = 0
}
if (targetY < 0) {
targetY = 0
}
if (targetX > target.clientWidth - dragElement.clientWidth) {
targetX = target.clientWidth - dragElement.clientWidth
}
if (targetY > target.clientHeight - dragElement.clientHeight) {
targetY = target.clientHeight - dragElement.clientHeight
}
//设置位置
dragElement.style.top = targetY + 'px'
dragElement.style.left = targetX + 'px'
}
//给document添加弹起事件
document.onmouseup = function () {
target.onmousemove = document.onmouseup = null
}
}
}