day12事件下
事件流的传播流程
三个阶段
捕获阶段
从最外层找到事件执行元素
window--document--body--div--button
目标阶段
找到button 执行button对应的事件
冒泡阶段
逐层向上冒泡执行对应的事件
事件流的两种模式
冒泡模式 (从里到外 组成执行对应的事件)
冒泡模式是常用的模式 默认设计的就是冒泡模式
示例
<div onclick='alert'>
<button onclick='alert(2)'>
</button>
</div>
<script>
document.body.onclick = function(){
alert(3)
}
document.onclick = function(){
alert(4)
}
window.onclick = function(){
alert(5)
}
//以上的这个示例 会从button开始不断向上执行 直到window停止 所以对应的执行结果为 2 1 3 4 5
</script>
以上示例会从button开始不断向上执行 直到window停止所以对应的执行结果为 2 1 3 4 5
如果我们不想触发对应外层的事件 只想触发本身的事件,那么我们需要禁止事件冒泡
!禁止事件冒泡的处理
stopPropagation event对象方法 对于低版本ie浏览器不支持
<button></button>
<script>
document.querySelector('button').onclick = function(e){
//事件源对象
e == e || window.event
//禁止事件冒泡的方法
e.stopPropagation()
alert(2)
}
</script>
cancelBubble event对象属性 兼容ie
//cancelBubble 取消冒泡 默认为false
e.cancelBubble = true
兼容写法
e.stopPropagation?e.stopPropagation():e.cancelBubble = true
捕获模式 (从外到里 组成执行对应的事件)
捕获模式是火狐提出来的模式 ie6 7 8 没有捕获模式 现在的模式很少使用捕获模式
默认行为
元素标签有默认行为(a标签会跳转页面),对于的事件也有默认行为(contextmenu会出现菜单栏)
defaultPrevent检测当前是否禁止默认行为
console.log(e.defaultPrevented)//是否阻止默认行为 只读 默认为false
禁止默认行为
preventDefault event对象方法 阻止默认行为(有兼容问题)
e.preventDefault() //preventDefault
returnValue event对象属性
e.returnValue = false //兼容ie
兼容写法
e.preventDefault?e.preventDefault():e.returnValue = false
return false 要放在最后
//右键点击 window.onmousemenu = function(e){ console.log('右键点击') //e.preventDefault?e.preventDefault():e.returnValue = false return false //一定要放在最后 }
!事件监听器
eventListener 他是一个标准的观察者模式 通过对应的监听器来监听事件的触发和执行
主要的两个方法
addEventListener
传入对应的事件名 处理函数 是否冒泡
主要事项
-
addEventListener 可以在一个事件中传入多个处理函数(一个事件对应多个处理函数数组)
-
EventListener 支持自定义事件名
-
属性事件(onclick)赋值不支持多个处理函数(会被覆盖)
var btn = document.querySelector('button') //添加事件监听器 传入事件名 处理函数 是否捕获(默认的事件模式 冒泡 false 捕获 true) /* btn.addEventListener('click',function(){ console.log('按钮点击了') },false) btn.addEventListener('click',function(){ console.log('按钮点击了1') },true) //指定为捕获先执行 btn.addEventListener('click',function(){ console.log('按钮点击了2') }) btn.addEventListener('dblclick',function(){ console.log('双击') }) //直接使用onclick 进行赋值的操作他会被后写的覆盖因为他只有一个处理函数 document.querySelector('div').onclick = function(){ console.log('div被点击了') } */ btn.addEventListener('click',handler,flase)//指定为冒泡模式
removeEventListener
移出对应的添加的事件监听器,传入事件名 处理函数 是否冒泡 每个都必须和添加的事件监听器一致,不然不能被移出
btn.addEventListener('click',handler,false) //指定为冒泡模式 //要移除的事件名 处理函数都要一致(如果是匿名函数就被你被移出 对象对比的是地址) btn.removeEventListener('click',handler,false) function handler(){ console.log('按钮点击了') }
注意事项
如果添加事件监听器的时候传入处理函数为匿名函数 那么不能被移除(对象比对地址)
拖拽
拖拽原理
-
给对应需要拖拽的元素添加鼠标按下事件
-
在按下事件内添加给区间的元素对应鼠标移动事件
-
在鼠标按下事件内添加对应的弹起事件 在弹起事件中释放移动事件 释放弹起事件
基础拖拽
思路
-
获取对应的拖拽的元素
-
在给拖拽元素添加鼠标按下事件并且记录按下坐标(在对应盒子里的坐标)
-
给区间元素添加鼠标移动事件 并且记录每次移动的坐标
-
在区间元素的鼠标移动事件中 设置对应的拖拽元素的坐标(移动的坐标 = 当前坐标 - 鼠标点击位置的坐标 + 'px')
-
在按下事件document中添加鼠标弹起事件 并且释放之前的移动事件以及自身的弹起事件
<div></div> <script> var div = document.querySelector('div') div.onmousedown = function(e){ e == e || window.event //记录在盒子上面的坐标 var x = e.offsetX var y = e.offsetY document.onmousemove = function(e){ e == e || window.event //获取页面上的坐标 var currx = e.pageX var curry = e.pageY //移动的坐标 = 当前坐标 - 鼠标点击位置的坐标 + 'px' div.style.left = currx-x+'px' div.style.top = curry-y+'px' } //释放之前的移动事件以及自身的弹起事件 document.onmouseup = function(){ document.onmousemove = null document.onmouseup = null } } </script>
区间拖拽
offset家族(属于元素对象 element对象)
-
offsetParent 偏移的父元素(从里到外 找有定位的父元素 如果没有就找body)
-
offsetLeft 左偏移 (不包含本身的margin 包含偏移的父元素本身的padding border)
-
offsetTop 上偏移
-
offsetWidth 偏移元素的宽度(包含padding和border)
-
offsetHeight 偏移元素的高度
思路
-
获取对应的拖拽的元素
-
在给拖拽元素添加鼠标按下事件并且记录按下坐标(在对应盒子里的坐标)
-
给区间元素添加鼠标移动事件 并且记录每次移动的坐标
-
在区间元素的鼠标移动事件中 获取对应父元素的位置以及能够移动的宽度 (父元素的宽/高度 - 自身的宽/高度)
-
设置移动元素处于区间元素的位置 页面的位置 - 父元素离页面的位置 - 鼠标的位置 = 移动位置父元素的坐标
-
对坐标位置进行区间判断
-
在按下事件document中添加鼠标弹起事件 并且释放之前的移动事件以及自身的弹起事件
<div> <button>移动按钮</button> </div> <script> var button = document.querySelector('button') var box = document.querySelector('div') button.onmousedown = function(e){ e == e || window.event //记录在盒子上的坐标 var x = e.offsetX var y = e.offsetY //在box中移动 box.onmousemove = function(e){ e == e || window.event //获取区间元素的位置 var bx = this.offsetLeft var by = this.offsetTop //获取能够移动的最大距离 var maxX = this.offsetWidth - button.offsetWidth var maxY = this.offsetHeight - button.offsetHeight //移动位置在父元素的坐标 = 页面的位置 - 父元素离页面的位置 - 鼠标点击的位置 var targetX = e.pageX - bx - x var targetY = e.pageY - by - y //进行区间判断 if(targetX<0){ targetX = 0 } if(targetY<0){ targetY = 0 } if(targetX>maxX){ targetX=maxX } if(targetY>maxY){ targetY=maxY } button.style.left = targetX + 'px' button.style.top = targetY + 'px' } document.onmouseup = function(){ box.onmousemove=null document.onmouseup=null } } </script>
封装一个方法找盒子到页面的距离
function getBoxToPageDistance(element){ var distance = { x:0, y:0 }//距离对象 while(element.offsetParent){ distance.x += element.offsetLeft distance.y += element.offsetTop element = element.offsetParent } return distance }标签:function,button,元素,事件,day12,var,document From: https://www.cnblogs.com/buyAVnub/p/17177152.html