事件的传播行为(事件流)
冒泡模式
冒泡模式就是从里到外触发
event.bubbles(只读属性)
console.log(e.bubbles);//当前事件是否冒泡
<div>
<button>按钮</button>
</div>
<script>
document.onclick = function(){
console.log('文档被点击了');
}
document.querySelector('div').onclick = function(){
console.log('div被点击了');
}
document.querySelector('button').onclick = function(e){
// e = e || window.event
console.log(e.bubbles);//当前事件是否冒泡
// e.bubbles//它是只读属性
// e.stopPropagation()//阻止事件冒泡 常用的方法 兼容问题
//兼容写法 兼容ie8及以下
// e.cancelBubble = true
//兼容写法
e.stopPropagation?e.stopPropagation():e.cancelBubble = true
console.log(e.bubbles);//当前时间是否冒泡
console.log('button被点击了');
}
</script>
阻止事件冒泡
-
stopPropagation()方法
e.stopPropagation()//阻止事件冒泡 常用的方法 兼容问题
-
兼容ie的写法 cancleBubble属性
//兼容写法 兼容ie8及以下
e.cancleBubble = true
-
兼容写法
//兼容写法
e.stopPropagation?e.stopPropagation():e.cancleBubble = 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>
//给对应的盒子添加鼠标按下事件
var div = document.querySelector('div');
div.onmousedown = function(e){
e = e || window.event
//在鼠标按下事件内容中获取鼠标在对应盒子里面的位置(offsetX)
var currentX = e.offsetX;
console.log(currentX);
var currentY = e.offsetY;
console.log(currentY);
document.onmousemove = function(e){
e = e || window.event
//获取每次移动在页面上的位置 - 对应的按下时鼠标在盒子里面的位置 = 对应的div盒子定位的位置
// var targetX = e.pageX - currentX
// var targetY = e.pageY - currentY
//设置对应盒子样式里的坐标值
div.style.left = (e.pageX - currentX) + 'px'
div.style.top = (e.pageY - currentY) + 'px'
}
// 在文档里面弹起
document.onmouseup = function(){
document.onmousemove = null//给鼠标移动事件赋一个空对象的值
}
}
</script>
在区间内进行拖拽
offset家族(属性 元素对象)
-
offsetParent偏移父元素(找出最近的定位父元素 如果没有定位就找body)
-
offsetHeight 偏移元素的高度
-
offsetWidth 偏移元素的宽度
-
offsetLeft 离父元素偏移的左边的距离(number类型)
-
offsetTop 离父元素偏移的上边的距离(number类型)
<style type="text/css">
*{padding: 0;margin: 0;}
.outerBox{
width: 500px;
height: 500px;
background-color: yellow;
position: absolute;
left: 100px;
top: 100px;
}
.box{
width: 400px;
height: 400px;
border:1px solid black;
position: absolute;
}
.moveBox{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<div class="outerBox">
<div class="box">
<div class="moveBox"></div>
</div>
</div>
<script>
//获取移动的盒子
var moveBox = document.querySelector('.moveBox');
//获取区间的大盒子
var box = document.querySelector('.box');
//outerBox盒子
// var outerBox = documnet.querySelector('.outerBox');
//给移动的盒子添加鼠标按下事件
moveBox.onmousedown = function(e){
//获取在移动的盒子里面按下的位置
e = e || window.event
var currentX = e.offsetX;
var currentY = e.offsetY;
//给区间的大盒子添加鼠标移动事件
box.onmousemove = function(e){
e = e || window.event
//offset家族
//offsetParent 偏移父元素 找离最近的定位元素 如果没有定位就找body
//offsetHeight 偏移元素的高度
//offsetWidth 偏移元素的宽度
//offsetLeft 离父元素偏移的左边的距离
//offsetTop 离父元素偏移的上边的距离
//设置moveBox这个盒子在box里面的定位
//鼠标在页面的位置 e.pageX - 大盒子在页面的位置 -鼠标按下的位置 currentX
var distance = computedPositionElementInPage(this)
//接收对应的设置的定位位置
var targetX = e.pageX - distance.left - currentX
var targetY = e.pageY - distance.top -currentY
//进行区间判断
//最大的移动距离X 大盒子宽度 - 小盒子宽度
var maxX = this.offsetWidth - moveBox.offsetWidth;
var maxY = this.offsetHeight - moveBox.offsetHeight;
//如果当前的定位位置比0还小 设置为0
if(targetX < 0){
targetX = 0
}
if(targetY < 0){
targetY = 0
}
//如果当前定位位置比最大移动距离还大,那就把最大移动的值赋值给盒子的定位值
if(targetX > maxX){
targetX = maxX
}
if(targetY > maxY){
targetY = maxY
}
//位置设置
moveBox.style.left = targetX + 'px'
moveBox.style.top = targetY + 'px'
}
document.onmouseup = function(){
//清除大盒子的移动事件
box.onmousemove = null
}
}
console.log(box);
console.log(box.offsetParent);
console.log(document.body.offsetParent);
console.log(box.offsetLeft);
console.log(box.offsetTop);
console.log(computedPositionElementInPage(box));
//如果要找盒子在页面上的位置 那么外面要从自己的基于父元素的距离 + 对应父元素基于它的父元素的距离...直到找到body
//封装一个方法计算盒子在页面上的位置 传递的参数为一个元素对象
function computedPositionElementInPage(element){
//封装一个距离对象 left为里左边的距离 top为离上边的距离
var distance = {
left:0,
top:0
}
//到了body就是null 到了body对应的while循环就结束
while(element.offsetParent){
//将对应的左边的距离一个个+
distance.left += element.offsetLeft//自己的基于父元素的x轴距离 + 对应的父元素基于它的父元素的x轴距离
//将对应的上边的距离一个个+
distance.top += element.offsetTop//自己的基于父元素的y轴距离 + 对应的父元素基于它的父元素的y轴距离
//进入到父元素
element = element.offsetParent
}
//将计算的结果返回出去
return distance
}
</script>
样式获取
-
style属性 只能获取内嵌样式
<style type="text/css">
div{
background-color:red;
width:100px;
}
</style>
<body>
<div style="height:300px;"></div>
<script type="text/javascript">
var div = document.getElementsByTagName('div')[0]
//style的弊端 他只能获取对应的内嵌样式,也就是只能获取style属性里面写的内容
console.log(div.style.width);//空字符串
console.log(div.style.height);//300px
</script>
</body>
-
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
}
//调用getStyle()方法
console.log(getStyle(document.getElementsByTagName('div')[0]))//返回对应元素的所有样式
console.log(getStyle(document.getElementsByTagName('div')[0]).height)//返回对应元素样式对应height属性的属性值300px