知识点回顾:
1 伪数组
NodeList / HTMLCollection / Arguments
转真数组 遍历数组,push到新的数组
2 事件:事件源 + 事件类型 + 事件处理函数
3 事件对象:event 事件处理函数的第一个参数 ---
4 事件流:页面接受事件的顺序(IE和其他浏览器是相反的)
5 事件冒泡 阻止事件冒泡的方法e.stopPropagation()
6 事件捕获
7 事件监听 addEventListener 不会覆盖,多一个参数(同时支持事件捕获和事件冒泡)
8 事件委托
实现方法:给父元素绑定同类型的事件
原理:事件冒泡
优点:减少了事件处理函数,可以给未来的对象添加事件绑定
案例:
留言板1
前插 insertBefore(oLi , oUl.firstChild)
因为每一次插入都是第一个,所以只需要给第一个绑定事件就可以了
留言板2
事件委托中,每一个if都相当于一个独立的函数(每一个if里面的变量都是局部变量)
事件类型
鼠标事件
键盘事件
表单事件
其他事件
鼠标事件
click左键单击 dblclick左键双击
鼠标按下和抬起 mousedown / mouseup (左键,中间键和右键都可以触发)
注意:单击事件是包含了鼠标按下+抬起,专指鼠标左键
e.button 0左键 / 1中间键 / 2右键
鼠标移入,移出
mouseover / mouseout 一对 支持事件冒泡
mouseenter / mouseleave 一对 支持事件捕获 不建议使用
鼠标移动 mousemove
坐标
坐标需要用过事件对象才能拿到
距离浏览器的坐标 e.clientX / e.clientY 一般也简写做 e.x / e.y
距离实际页面的坐标 e.pageX / e.pageY
距离目标源的坐标 e.offsetX / e.offsetY
offsetLeft 距离最近的具有定位的祖先元素的距离 , 这个元素自身不需要定位
offsetTop
事件禁用 相当于按钮上的disabled属性;pointer-events: none;
盒子自身的三种宽度
offsetWidth (border+padding+width)
clientWidth (padding+width)
getComputedStyle(ele).width (width)
拓展: 由于id在页面上具有唯一性,所以元素不获取也可以直接通过id访问元素,一般建议还是先获取元素
放大镜案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.fdj{
width: 1100px;
margin: auto;
display: flex;
justify-content: space-between;
}
.left{
width: 350px;
height: 350px;
}
.left1{
width: 400px;
height: 400px;
position: relative;
}
.left1 img{
width: 400px;
height: 400px;
}
.cover{
position: absolute;
width: 200px;
height: 200px;
background-color: rgba(0,0,0,.5);
top: 0;
/* display: none; */
opacity: 0;
/* filter: alpha(opacity=0); */
/* pointer-events: none; */
cursor: pointer;
}
.right{
width: 600px;
height: 600px;
position: relative;
overflow: hidden;
/* display: none; */
opacity: 0;
}
.right img{
width: 1200px;
height: 1200px;
position: absolute;
}
</style>
</head>
<body>
<div class="fdj">
<div class="left">
<div class="left1">
<img src="../images/1.jpg" alt="">
<div class="cover"></div>
</div>
<div class="left2"></div>
</div>
<div class="right">
<img src="../images/1.jpg" alt="">
</div>
</div>
<script>
// 实现放大镜的前提条件
// 左边图片和遮罩层的比例 = 右边大图和盒子的比例
// 移动的比例 : 右边大图的移动范围 / 左边遮罩层的移动范围
var oBox = $('.fdj') ;
var oLeft = $('.left') ;
var oLeft1 = $('.left1') ;
var oCover = $('.cover') ;
var oRight = $('.right') ;
var oRightImg = $('.right img') ;
// 大盒子距离左边的距离
var _left = oLeft.offsetLeft ;
console.log(_left);
var _top = oLeft.offsetTop ;
// 遮罩层的宽度 --- 如果使用了display:none 就拿不到
var r = oCover.offsetWidth / 2 ;
console.log(r);
// 遮罩层的最大移动范围
var maxX = oLeft1.clientWidth - oCover.offsetWidth ;
var maxY = oLeft1.clientHeight - oCover.offsetHeight ;
// 右侧大图的最大移动范围
var maxX2 = oRightImg.clientWidth - oRight.offsetWidth ;
var scale = maxX2 / maxX ;
console.log(scale);
// 鼠标移入
oLeft1.addEventListener('mouseover' , function () {
// oCover.style.display = 'block' ;
oCover.style.opacity = 1 ;
oRight.style.opacity = 1 ;
// 鼠标移动事件
document.addEventListener('mousemove' , function (e) {
var x = e.x - _left - r ;
var y = e.y - _top - r ;
if(x < 0) x = 0 ;
if(y < 0) y = 0 ;
if(x > maxX) x = maxX ;
if(y > maxY) y = maxY ;
// cssText会覆盖行内样式
oCover.style.cssText += `left:${x}px;top:${y}px`;
oRightImg.style.cssText += `left:${-x * scale}px;top:${-y * scale}px`;
})
})
// 鼠标移出
oLeft1.addEventListener('mouseout' , function () {
oCover.style.opacity = 0 ;
oRight.style.opacity = 0 ;
})
function $ (selector) {
return document.querySelector(selector)
}
</script>
</body>
</html>
鼠标拖拽事件代码段
// 鼠标按下
oDiv.onmousedown = function (e) {
e = e || event ;
// 鼠标按下的时候,获取鼠标在盒子中的位置
var gapX = e.x - oDiv.offsetLeft ;
var gapY = e.y - oDiv.offsetTop ;
// 鼠标跟随
document.onmousemove = function (e) {
e = e || event ;
var x = e.x - gapX ;
var y = e.y - gapY ;
oDiv.style.cssText = `left:${x}px;top:${y}px`;
}
// 鼠标抬起时 清除鼠标跟随事件
oDiv.onmouseup = function () {
document.onmousemove = null ;
}
}