事件的传播行为(事件流)
冒泡模式(默认模式)
冒泡模式就是从里到外触发
event.bubbles(只读属性)
console.log(e.bubbles);//当前事件是否冒泡
<div> <button>点我</button> </div> <script> //点击按钮 先触发按钮的点击事件 然后触发div的点击事件 然后触发document的点击事件 document.onclick = function(){ console.log('文档被点击了'); } document.querySelector('div').onclick = function(){ console.log('div被点击了'); } document.querySelector('button').onclick = function(e){ console.log(e.bubbles);//当前事件是否冒泡 console.log('button被点击了'); } </script>
阻止事件冒泡
-
stopPropagation (方法)
e.stopPropagation() //阻止事件冒泡 常用的方法 兼容问题
-
兼容ie低版本的写法 cancelBubble (属性)
// 兼容写法 兼容ie8及以下 e.cancelBubble = true
-
兼容写法
//兼容写法 e.stopPropagation?e.stopPropagation():e.cancelBubble = true
捕获模式
捕获模式就从外到里触发
默认行为
某些操作或者html元素拥有的一些默认的行为(a 标签的默认行为 进行页面跳转 form里面submit行为 图片的拖动行为...)
在某些时候外面的默认行为会导致对应的代码执行出现问题,这个时候就需要禁止默认行为。
阻止默认行为
-
preventDefault (方法)
//阻止默认行为 e.preventDefault();//大部分浏览器兼容
-
兼容ie低版本的写法 returnValue 属性
//兼容ie e.returnValue = false //兼容ie
-
兼容写法
e.preventDefault?e.preventDefault():e.returnValue = false
-
return false
return false
事件监听器(兼容问题)
-
addEventListener 添加事件监听器(可以添加多个处理函数)
-
removeEventListener 移除事件监听器 (只能移除addEventListener添加的 移除根据对应的处理函数是否为一个)
//我需要俩个处理函数 事件监听器 可以有多个处理函数 //监听对应的事件执行 来执行对应的处理函数 (不会覆盖之前的事件的处理函数) //传入事件名 传入处理函数 (如果是直接传入function 就不会被移除) btn.addEventListener('click',function(){ console.log('点击了按钮'); }) btn.addEventListener('click',function fn(){ console.log('点击了按钮1'); }) btn.addEventListener('click',handler1) //移除事件监听器 必须处理函数是同一个 不然不能被移除 只能移除addEventListener添加的 btn.removeEventListener('click',function fn(){ console.log('点击了按钮1'); })//不能移除 btn.removeEventListener('click',handler1) //能 btn.removeEventListener('click',handler)//不能移除
拖拽
基础三大事件
-
鼠标按下事件 (mousedown)
-
鼠标移动事件 (mousemove)
-
鼠标弹起事件 (mouseup)
在页面进行拖拽
步骤
-
给对应的盒子添加鼠标按下事件
-
在鼠标按下事件内容获取鼠标在对应盒子里面的位置 (offsetX)
-
在鼠标按下事件中给document添加移动事件
-
在移动的时候获取鼠标在页面上的位置(pageX)
-
计算对应的定位的位置 (鼠标在页面上的位置 - 鼠标在对应盒子内的位置)
-
设置对应的盒子的位置
-
在鼠标按下事件中给document添加弹起事件
-
在弹起事件内移除对应的移动事件
<div></div> <script> //获取div var div = document.querySelector('div') //在div里面按下 div.onmousedown = function(e){ e = e || window.event //获取按下时 鼠标在对应盒子里面位置 var currentX = e.offsetX var currentY= e.offsetY //在文档里面移动 document.onmousemove = function(e){ //获取每次移动在页面上的位置 - 对应的按下时鼠标在盒子里面的位置 = 对应的定位的位置 var targetX = e.pageX - currentX var targetY = e.pageY- currentY //设置给对应的盒子 div.style.left = targetX + 'px' div.style.top = targetY + 'px' } //在文档里面弹起 document.onmouseup = function(){ document.onmousemove = null } } </script>
在区间进行拖拽
offset家族(属性 元素对象)
-
offsetParent 偏移父元素 (找离最近的定位父元素 如果没有定位就找body)
-
offsetHeight 偏移元素的高度
-
offsetWidth 偏移元素的宽度
-
offsetLeft 离父元素偏移的左边的距离 (number类型)
-
offsetTop 离父元素偏移的上边距离 (number类型)
<div class="outerBox"> <div class="box"> <div class="moveBox"></div> </div> </div> <script> //获取移动的盒子 var move = document.querySelector('.moveBox') //获取区间的大盒子 var box = document.querySelector('.box') //给移动的盒子添加按下事件 move.onmousedown = function (e) { //获取在移动的盒子里面按下的位置 e = e || window.event var currentX = e.offsetX var currentY = e.offsetY //给区间的大盒子添加移动 box.onmousemove = function (e) { e = e || window.event //设置move这个盒子在box里面定位 //鼠标在页面的位置 e.pageX - 大盒子在页面的位置 - 鼠标按下的位置 currentX var distance = computedPointElementInPage(this) //接收对应的设置的定位位置 var targetX = e.pageX - distance.left - currentX var targetY = e.pageY - distance.top - currentY //进行区间判断 //最大的移动距离X = 大盒子宽度 - 小盒子的宽度 var maxX = this.offsetWidth - move.offsetWidth var maxY = this.offsetHeight - move.offsetHeight //如果当前的定位位置比0还小 设置为0 if(targetX < 0){ targetX = 0 } if(targetY < 0){ targetY = 0 } //如果比最大值还大 就设置最大值 if(targetX > maxX){ targetX = maxX } if(targetY > maxY){ targetY = maxY } //位置设置 move.style.left = targetX + 'px' move.style.top = targetY + 'px' } document.onmouseup = function(){ //清除大盒子的移动事件 box.onmousemove = null } } //如果要找盒子在页面上的位置 那么外面要从自己的基于的父元素的距离 + 对应父元素基于他的父元素距离 .. 直到找到body //封装一个方法计算盒子在页面上的位置 传递一个盒子 function computedPointElementInPage(element) { //封装一个距离对象 left离左边的 top离上边的 var distance = { left: 0, top: 0 } //到了body就是null 到了body对应while循环就结束 while (element.offsetParent) { //将对应的左边的距离一个个+ distance.left += element.offsetLeft //将对应的上边的距离一个个+ distance.top += element.offsetTop //进入到父元素 element = element.offsetParent } //将计算好的结果返回出去 return distance } </script>
样式获取
-
style属性 只能获取内嵌样式
var div = document.getElementsByTagName('div')[0] //style的弊端 他只能获取对应的内嵌的样式 也就是只能获取style属性里面写的内容 console.log(div.style.width); //空字符串 console.log(div.style.height); //300px
-
getComputedStyle 方法可以获取所有的样式
//对应的兼容获取所有样式的方法 var style = getComputedStyle(div, '') console.log(style); //getComputedStyle获取样式对象里面都有默认值(所有的样式) console.log(style.backgroundColor); console.log(style.color); console.log(style.width); console.log(style.height);
-
currentStyle ie的低版本兼容
console.log(div.currentStyle); //ie低版本兼容 废弃
-
兼容封装
// getComputedStyle 兼容问题 // console.log(div.currentStyle); //ie低版本兼容 废弃 //兼容写法 传入一个元素 返回一个样式对象 function getStyle(element) { var style = window.getComputedStyle ? getComputedStyle(element, '') : element.currentStyle return style }