JavaScript實現(xiàn)電商平臺商品細(xì)節(jié)圖
本文分享一個電商平臺常見查看商品細(xì)節(jié)圖案例,如某東網(wǎng)站手機(jī)類別中具體某一部手機(jī)詳情頁中,手機(jī)的細(xì)節(jié)圖展示,左側(cè)小圖獲得用戶鼠標(biāo)焦點即可在屏幕右側(cè)展示出該圖片區(qū)域的大圖效果,其中JS部分主要涉及鼠標(biāo)經(jīng)過、鼠標(biāo)離開、鼠標(biāo)移動等事件以及含有一個小算法公式,先展示效果:
某電商平臺效果圖展示:

本案例代碼部分:
HTML結(jié)構(gòu):
<div class="box">
<img src="images/s3.png" alt="">
<div class="mask"></div>
<div class="big">
<img src="images/big.jpg" alt="">
</div>
</div>
CSS樣式:
<style>
* {
padding: 0;
margin: 0;
}
.box {
position: relative;
top: 70px;
left: 30px;
width: 400px;
height: 400px;
border: 1px solid #ccc;
}
.box > img {
height: 100%;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
box-sizing: border-box;
background-color: rgba(254, 222, 79, .5);
border: 1px solid #ccc;
cursor: move;
/*讓鼠標(biāo)的狀態(tài)改成十字型*/
}
.big {
display: none;
position: absolute;
top: 0;
left: 410px;
width: 500px;
height: 500px;
border: 1px solid #ccc;
overflow: hidden;
z-index: 999;
}
.big img {
/* 一定要給.big下的img定位屬性它的位置才能隨著遮罩層的移動而移動哦 */
position: absolute;
top: 0;
left: 0;
}
</style>
JavaScript行為:
<script>
window.addEventListener('load', function () {
// 1.獲取元素
var box = document.querySelector('.box');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 2.注冊事件
// (1)box鼠標(biāo)經(jīng)過即顯示出遮罩層mask和右側(cè)大圖 onmouseover
box.addEventListener('mouseover', function () {
mask.style.display = 'block';
big.style.display = 'block';
})
// (2)box鼠標(biāo)離開即隱藏遮罩層mask和右側(cè)大圖 onmouseout
box.addEventListener('mouseout', function () {
mask.style.display = 'none';
big.style.display = 'none';
})
// (3)讓mask遮罩層隨著鼠標(biāo)移動(此事件要寫在獲得鼠標(biāo)的情況下)
box.addEventListener('mousemove', function (e) {
// (1). 先計算出鼠標(biāo)在盒子內(nèi)的坐標(biāo),鼠標(biāo)在盒子里的坐標(biāo)=鼠標(biāo)在屏幕中的坐標(biāo)-盒子的offsetLeft/offsetTop
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// (2) 鼠標(biāo)在遮罩層中應(yīng)該處于中心的位置,所以還要把鼠標(biāo)從遮罩層的左上角往右往下移動遮罩層寬高的一半才行,即鼠標(biāo)在盒子里的坐標(biāo)減去盒子高度的一半和寬度的一半就是我們mask 的最終 left 和top值了
var maskX = x - mask.offsetWidth / 2; // 鼠標(biāo)位置在遮罩層水平中間
var maskY = y - mask.offsetHeight / 2; // 鼠標(biāo)位置在遮罩層垂直中間
// (3) 我們mask 遮罩層水平移動的距離即maskX= 遮罩層的父盒子的寬-遮罩層的寬,而遮罩層垂直移動的距離即maskY= 遮罩層的父盒子的高-遮罩層的高
// (4) 如果x 坐標(biāo)小于了0 就讓他停在0 的位置
// 遮擋層的最大移動距離= 遮罩層的父盒子的寬-遮罩層的寬(因為此案例的遮罩層是一個正方形,所以水平和垂直的范圍是一致的)
var maskMax = box.offsetWidth - mask.offsetWidth; // 遮罩層的最大移動距離
// 判斷限定遮罩層的可移動范圍:水平可移動范圍:
maskX <= 0 ? maskX = 0 : maskX = maskX; // 水平最小可移動范圍
maskX >= maskMax ? maskX = maskMax : maskX = maskX; // 水平最小大可移動范圍
// 判斷限定遮罩層的可移動范圍:垂直可移動范圍:
maskY <= 0 ? maskY = 0 : maskY = maskY; // 垂直最小可移動范圍
maskY >= maskMax ? maskY = maskMax : maskY = maskY; // 垂直最大可移動范圍
// 將鼠標(biāo)的坐標(biāo)值給mask的left和top(mask是有定位的)注意要加px單位?。?!
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// (5)讓右側(cè)大圖隨著遮罩層移動而移動
// 大圖片的移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離
// 獲取大圖
var bigImg = big.querySelector('img');
// 大圖片最大移動距離
var bigMax = bigImg.offsetWidth - big.offsetWidth;
// 大圖片的移動距離 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
// 注意:1.bigImg獲取到的元素需要有CSS定位屬性才能移動位置的,沒有定位位置是不會變的哦
// 2.大圖的移動和遮罩層移動的方向是相反的哦,因為遮罩層往左移動時實際上大圖是要往右移動的,所以值是負(fù)數(shù)
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px';
})
})
</script>
效果展示:
1.程序運行,用戶鼠標(biāo)還未經(jīng)過左側(cè)小圖(.box)時:

2.鼠標(biāo)經(jīng)過左側(cè)小圖時 :

3.鼠標(biāo)在左側(cè)小圖(.box)上移動時:

案例知識點及細(xì)節(jié):
1.HTML結(jié)構(gòu)部分:主要結(jié)構(gòu)是一個大的div裝一張圖片(即左側(cè)小圖)和兩個div(一個遮罩層、一個右側(cè)裝大圖的div),這三個元素,默認(rèn)顯示的只有左側(cè)的小圖,另外的遮罩層和大圖都是默認(rèn)隱藏的(即display: none;),且遮罩層和大圖都是通過定位(子絕父相)放到對應(yīng)的位置上的,這里需要注意的是右側(cè)大圖的z-index需要給個值,因為一般右側(cè)大圖原本的區(qū)域是有內(nèi)容顯示的,大圖可能會被壓在下面,所以要提一下層級;
2.CSS樣式部分:樣式就根據(jù)一般樣式給就可以,唯一一點需要注意的是大圖里面的img要給一個position: absolute;的絕對定位,這樣JS部分才能通過left和top來移動圖片的位置實現(xiàn)大圖隨小圖內(nèi)鼠標(biāo)的移動而移動的效果;
3.JavaScript部分:主要設(shè)計鼠標(biāo)經(jīng)過事件(onmouseover)、鼠標(biāo)離開事件(onmouseout)和鼠標(biāo)移動事件(onmousemove),注意寫在addEventListener()內(nèi)則不需要加on,且需要用引號引起來,主要思路是給最外層的大盒子(即.box)添加鼠標(biāo)經(jīng)過事件,鼠標(biāo)經(jīng)過則讓遮罩層和右側(cè)大圖顯示出來(即display: block;),鼠標(biāo)離開則隱藏(即display: none;),然后再給.box添加鼠標(biāo)移動事件,鼠標(biāo)在其內(nèi)部移動先獲取到鼠標(biāo)的坐標(biāo)(用鼠標(biāo)的e.pageX - box.offsetLeft得X坐標(biāo);Y坐標(biāo)同理可得),得到鼠標(biāo)的坐標(biāo)就可以決定遮罩層的位置了,但是注意鼠標(biāo)的坐標(biāo)來決定遮罩層的位置時鼠標(biāo)應(yīng)該是在遮罩層的中心位置,所以要把得到的鼠標(biāo)坐標(biāo)往下和往右移動遮罩層高寬的一半,這樣得到的坐標(biāo)值賦值到遮罩層上(決定的是遮罩層的左上角坐標(biāo))才對;
4.遮罩層可以隨著鼠標(biāo)移動而移動了,但是還有一點那就是遮罩層的移動范圍應(yīng)該是受限的,它不能超出父盒子,所以要添加一個判斷,如果遮罩層往左走到了0則不能再走,而往右走可以走多少其實本身是右遮罩層和其父盒子(即.box)的寬度來決定的,因為遮罩層的移動范圍是從0~(box.offsetWidth - mask.offsetWidth),即0到父盒子的寬度減去遮罩層的寬度得來的;
5.遮罩層可以正常移動了范圍也限制好了接下來就是右側(cè)大圖的顯示了,這里主要設(shè)計到一個算法即:

因為大圖的移動和遮罩層的移動其實是有比例關(guān)系的,即遮罩層移動多少大圖按照該比例就移動多少(比如遮罩層移動1px,大圖移動2px,那么遮罩層移動2px時大圖就應(yīng)該移動4px),由此公式可得出小圖移動時大圖對應(yīng)應(yīng)該移動的距離數(shù)據(jù),然后將此數(shù)據(jù)賦值給右側(cè)大圖(即div下的img),通過style.left和style.top即可改變圖標(biāo)的位置(主要值要加px單位),但是注意,大圖的移動和遮罩層的移動其實是相反的哦,如遮罩層往右移動,其實大圖是往左移的(因為大圖要往左走才能展示其右側(cè)區(qū)域),所以給left和top賦的值要加個負(fù)號哦。
如此,便基本介紹了本案例所涉及的基本知識點和注意點,建議可以結(jié)合代碼(內(nèi)含詳細(xì)注釋)可以更清晰的看到編程步驟以及實現(xiàn)思路。本案例是純JS底層代碼實現(xiàn)(所以具有很多可以優(yōu)化的地方)或許會有更好更簡單的方法實現(xiàn)此功能,但是使用最基本的JS代碼實現(xiàn)可以比較清晰的理解核心代碼和算法。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中將一個值轉(zhuǎn)換為字符串的方法分析[譯]
在JavaScript中,主要有三種方法能讓任意值轉(zhuǎn)換為字符串.本文講解了每種方法以及各自的優(yōu)缺點2012-09-09
echarts統(tǒng)計x軸區(qū)間的數(shù)值實例代碼詳解
這篇文章主要介紹了echarts統(tǒng)計x軸區(qū)間的數(shù)值,本文給出了實現(xiàn)實例及實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07
通過js隨機(jī)函數(shù)Math.random實現(xiàn)亂序
這篇文章主要介紹了通過js隨機(jī)函數(shù)Math.random實現(xiàn)亂序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05
基于JavaScript實現(xiàn)百葉窗動畫效果不只單純flas可以實現(xiàn)
看到這種百葉窗效果的動畫,以為是用flash做的,下面通過本文給大家介紹基于JavaScript實現(xiàn)百葉窗動畫效果,需要的朋友參考下吧2016-02-02
用RadioButten或CheckBox實現(xiàn)div的顯示與隱藏
用RadioButten(或CheckBox)實現(xiàn)div的顯示與隱藏,當(dāng)選擇“女”時,顯示“美女、才女”;當(dāng)選擇“男”時隱藏,具體實現(xiàn)如下,感興趣的朋友可以參考下2013-09-09
uniapp開發(fā)小程序的開發(fā)規(guī)范總結(jié)
uni-app 是一個使用 vue.js 開發(fā)跨平臺應(yīng)用的前端框架,下面這篇文章主要給大家介紹了關(guān)于uniapp開發(fā)小程序的開發(fā)規(guī)范,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
js中獲取鍵盤按下鍵值event.keyCode、event.charCode和event.which的兼容性詳解
這篇文章主要給大家介紹了關(guān)于Javascript中獲取鍵盤按下鍵值event.keyCode、event.charCode和event.which的兼容性的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03

