JavaScript實現(xiàn)電商平臺商品細節(jié)圖
本文分享一個電商平臺常見查看商品細節(jié)圖案例,如某東網(wǎng)站手機類別中具體某一部手機詳情頁中,手機的細節(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.大圖的移動和遮罩層移動的方向是相反的哦,因為遮罩層往左移動時實際上大圖是要往右移動的,所以值是負數(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)上移動時:
案例知識點及細節(jié):
1.HTML結(jié)構(gòu)部分:主要結(jié)構(gòu)是一個大的div裝一張圖片(即左側(cè)小圖)和兩個div(一個遮罩層、一個右側(cè)裝大圖的div),這三個元素,默認顯示的只有左側(cè)的小圖,另外的遮罩層和大圖都是默認隱藏的(即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賦的值要加個負號哦。
如此,便基本介紹了本案例所涉及的基本知識點和注意點,建議可以結(jié)合代碼(內(nèi)含詳細注釋)可以更清晰的看到編程步驟以及實現(xiàn)思路。本案例是純JS底層代碼實現(xiàn)(所以具有很多可以優(yōu)化的地方)或許會有更好更簡單的方法實現(xiàn)此功能,但是使用最基本的JS代碼實現(xiàn)可以比較清晰的理解核心代碼和算法。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript遍歷json對象的key和任意js對象屬性實例
下面小編就為大家?guī)硪黄猨avascript遍歷json對象的key和任意js對象屬性實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03寫了10年的Javascript也未必全了解的連續(xù)賦值運算
很喜歡 蔡蔡 的這個標(biāo)題,實際蔡蔡已經(jīng)分析過了,這里借用了?;蛟S有點標(biāo)題黨的意思??赐昃椭恕?/div> 2011-03-03原生javascript實現(xiàn)圖片滾動、延時加載功能
這篇文章主要介紹了使用原生javascript實現(xiàn)圖片滾動、延時加載功能,思路與方法均分享給大家,希望對大家能有所幫助。2015-01-01JavaScript Event事件學(xué)習(xí)第一章 Event介紹
Events是每一個JavaScript程序核心。什么是事件處理,它有什么問題和怎樣寫出跨瀏覽器的代碼,我將在這一章做一個概述。我也會提供一些有精彩的關(guān)于事件處理程序的細節(jié)的文章。2010-02-02最新評論