须要先了解JS的三个鼠标事件node
onmouseenter 鼠标进入浏览器
onmouseleave 鼠标移出bash
onmousemove 鼠标移动布局
注意:鼠标移入的时候须要阻止事件的冒泡传播(ev.stopPropagation),因此不用onmouseover和onmouseoutui
理解盒子模型spa
offsetParent:当前盒子的父级参照物code
offsetLeft / offsetTop:当前盒子距离其父级参照物的偏移量对象
offsetWidth / offsetHeight:当前元素可视区域的宽高(内容的宽高+padding+border)seo
scrollLeft / scrollTop:滚动条卷去的宽度/高度事件
区分鼠标事件对象
ev.clientX / ev.clientY: 当前鼠标触发点距离当前窗口左上角的X/Y轴坐标
ev.pageX / ev.pageY:当前鼠标触发点距离body(第一屏幕)左上角的X/Y轴坐标
注意:低版本浏览器事件对象中不存在pageX/pageY
ev.pageX = ev.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
ev.pageY = ev.clientY + (document.documentElement.scrollTop || document.body.scrollTop)
复制代码
若是图片是在某些盒子里,而且盒子距离左上角的距离根据浏览器窗口的大小改变,那么计算偏移量的时候就不能用ev.clientX/ev.clientY,而是须要用ev.pageX/ev.pageY
<div id="smallBox" class="smallBox">
<img src="smallImg.jpg"/>
<div class="mask" id="mask"></div>
</div>
<div class="big" id="bigBox">
<img id="bigImg" src="bigImg.jpg" alt=""/>
</div>
复制代码
.small{width:400px;height:400px}
.small img{width:100%;height:100%}
.small .mask{width: 200px; height: 200px; background: rgba(255, 255, 0, 0.4); position: absolute; left: 0; top: 0; display: none; cursor: move; }
.big{ width: 480px; height: 480px; border: 1px solid #999; position: absolute; top: 0; left: 400px; overflow: hidden; z-index:999; display: none;}
.big img{width:800px; height: 800px;}
复制代码
JS逻辑
3.1 页面加载完成后触发
window.onload = function(){}
复制代码
3.2 获取操做的元素
let small = document.getElementById("smallBox"),
big = document.getElementById("bigBox"),
bigImg = document.getElementById("bigImg"),
mask = document.getElementById("mask");
复制代码
3.3 计算小图距离body的偏移量
let smallLeft = small.offsetLeft,//小图距body的左偏移量
smallTop = small.offsetTop,//小图距body的上偏移量
smallBox = small;//临时值,用于计算小图距body的偏移量
//计算小图距body的偏移量
while(smallBox.offsetParent.nodeName !== 'BODY'){
smallBox = smallBox.offsetParent;
smallLeft += smallBox.offsetLeft;
smallTop += smallBox.offsetTop;
}
复制代码
3.4 设置鼠标移入/移出小图时,大图和遮罩层的隐藏和显示
small.onmouseenter = function(){
big.style.display = "block";
mask.style.display = "block";
};
small.onmouseleave = function(){
big.style.display = "none";
mask.style.display = "none";
};
复制代码
3.5 遮罩层随着鼠标移动
small.onmousemove = function(event){
event = event || window.event;
//兼容低版本浏览器 - 低版本浏览器中不存在pageX和pageY
event.pageX = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
event.pageY = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
var x = event.pageX - smallLeft - mask.offsetWidth/2;
var y = event.pageY - smallTop - mask.offsetHeight/2;
mask.style.top = y + "px";
mask.style.left = x + "px";
}
复制代码
3.6 鼠标移动时不超出小图时拉回
//水平方向的最大值
var maxX = small.clientWidth-mask.clientWidth;
//竖直方向的最大值
var maxY = small.clientHeight-mask.clientHeight;
//超出左侧时,拉回
if(x<0) x=0;
//超出右侧时,拉回
if(x>maxX) x=maxX;
//顶部超出
if(y<0) y=0;
//底部超出
if(y>maxY) y=maxY;
复制代码
3.7 大图根据比例显示
//比例 = 大图移动的距离/mask移动的距离 = 大图/小图
var scale = bigImg.offsetWidth / small.offsetWidth;
bigImg.style.marginLeft = -scale * x +"px";
bigImg.style.marginTop = -scale * y +"px";
复制代码
//-------------------- HTML start --------------------
<div id="smallBox" class="smallBox">
<img src="smallImg.jpg"/>
<div class="mask" id="mask"></div>
</div>
<div class="big" id="bigBox">
<img id="bigImg" src="bigImg.jpg" alt=""/>
</div>
//--------------------- HTML end ---------------------
//--------------------- CSS start --------------------
.small{width:400px;height:400px}
.small img{width:100%;height:100%}
.small .mask{width: 200px; height: 200px; background: rgba(255, 255, 0, 0.4); position: absolute; left: 0; top: 0; display: none; cursor: move; }
.big{ width: 480px; height: 480px; border: 1px solid #999; position: absolute; top: 0; left: 400px; overflow: hidden; z-index:999; display: none;}
.big img{width:800px; height: 800px;}
//--------------------- CSS end ---------------------
//--------------------- JS start --------------------
window.onload = function(){
var small = document.getElementById("smallImg"),
big = document.getElementById("bigBox"),
bigImg = document.getElementById("bigImg"),
mask = document.getElementById("imgMask"),
smallLeft = small.offsetLeft,//小图距body的左偏移量
smallTop = small.offsetTop,//小图距body的上偏移量
smallBox = small;//临时值,用于计算小图距body的偏移量
//计算小图距body的偏移量
while(smallBox.offsetParent.nodeName !== 'BODY'){
smallBox = smallBox.offsetParent;
smallLeft += smallBox.offsetLeft;
smallTop += smallBox.offsetTop;
}
//big和mask在鼠标移入small时显示,移出时隐藏
small.onmouseenter = function(){
big.style.display = "block";
mask.style.display = "block";
};
small.onmouseleave = function(){
big.style.display = "none";
mask.style.display = "none";
};
small.onmousemove = function(event){
event = event || window.event;
//兼容低版本浏览器 - 低版本浏览器中不存在pageX和pageY
event.pageX = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
event.pageY = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
var x = event.pageX - smallLeft - mask.offsetWidth/2;
var y = event.pageY - smallTop - mask.offsetHeight/2;
//水平方向的最大值
var maxX = small.clientWidth-mask.clientWidth;
//竖直方向的最大值
var maxY = small.clientHeight-mask.clientHeight;
if(x<0){
//至关于超出左侧,超出左侧时,拉回
x=0;
}
//超出右侧时拉回
if(x>maxX){
x=maxX;
}
//顶部超出
if(y<0){
y=0;
}
//底部超出
if(y>maxY){
y=maxY;
}
mask.style.top = y + "px";
mask.style.left = x + "px";
//比例 = 大图移动的距离/mask移动的距离 = 大图/小图
var scale = bigImg.offsetWidth / small.offsetWidth;
bigImg.style.marginLeft = -scale * x +"px";
bigImg.style.marginTop = -scale * y +"px";
}
};
//--------------------- JS end ----------------------
复制代码