須要先了解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 ----------------------
複製代碼