Javascript實(shí)例項(xiàng)目放大鏡特效的實(shí)現(xiàn)流程
前言
本票博客主要是放大鏡案例,里面涉及到的知識(shí)點(diǎn)會(huì)提出來(lái),可放心食用~后有源代碼。
案例:仿京東放大鏡效果
效果見(jiàn)下圖:
功能要求:
- 當(dāng)鼠標(biāo)移動(dòng)到小圖片上時(shí),遮罩層出現(xiàn),同時(shí)旁邊大圖片也出現(xiàn),鼠標(biāo)移出,遮罩層消失,大圖片也消失。
- 遮罩層只能在小盒內(nèi)子移動(dòng),不能超出。
- 遮罩層在小盒子內(nèi)移動(dòng),大圖片顯示對(duì)應(yīng)的板塊。
案例分析:
- 元素的隱層和顯示
- 遮罩層的移動(dòng)范圍用offset計(jì)算
- 計(jì)算出大盒子內(nèi)移動(dòng)的距離
案例代碼:
首先咱們應(yīng)該將結(jié)構(gòu)搭建好,結(jié)構(gòu)大致為:
先將各個(gè)盒子的樣式全部書(shū)寫(xiě)完畢后,把藍(lán)色遮罩層盒子和右邊的裝紅色大圖片的盒子隱藏起來(lái),注意,紫色的盒子是相對(duì)定位,所有盒子的定位都是根據(jù)紫色盒子進(jìn)行定位的。
代碼如下:
<div class="box"> <img src="./image/pic1.jpg" alt="" class="box_pic"> <div class="mask"></div> <div class="big"> <img src="./image/bigimg.jpg" alt="" class="bigImg"> </div> </div>
搭建好后,我們給這個(gè)box盒子添加鼠標(biāo)移動(dòng)事件,當(dāng)鼠標(biāo)移動(dòng)到box上時(shí),mask盒子和big盒子出現(xiàn),鼠標(biāo)移出后,mask盒子和big盒子消失。
代碼如下:
var pic = document.querySelector('.box'); var mask = document.querySelector('.mask'); var big = document.querySelector('.big'); //出現(xiàn) 消失 pic.addEventListener('mouseenter', function () { mask.style.display = 'block'; big.style.display = 'block'; }) pic.addEventListener('mouseleave', function () { mask.style.display = 'none'; big.style.display = 'none'; })
接著我們就需要計(jì)算一下遮罩層可以移動(dòng)的距離。
由上圖可見(jiàn),因?yàn)槲覀円笳谡謱硬荒艹鲂『凶拥姆秶?,所以遮罩層能在小盒子?nèi)移動(dòng)的距離就只有小盒子的寬度減去遮罩層盒子的寬度,此時(shí)我們使用offset中的屬性。
offset系列
使用 offset系列相關(guān)屬性可以動(dòng)態(tài)的得到該元素的位置(偏移)、大小等
offset系列屬性:
注意:offset系列只有offsetTop和offsetLeft?。?!且返回的值是不帶單位的。
對(duì)比:offset和style屬性
offset
styleoffset 可以得到任意樣式表中的樣式值style 只能得到行內(nèi)樣式表中的樣式值
offset 系列獲得的數(shù)值是沒(méi)有單位的
style.width 獲得的是帶有單位的字符串 offsetWidth 包含padding+border+widthstyle.width 獲得不包含padding和border 的值offsetWidth 等屬性是只讀屬性,只能獲取不能賦值style.width 是可讀寫(xiě)屬性,可以獲取也可以賦值總結(jié):適合獲取元素大小位置總結(jié):適合給元素更改值
那么接下來(lái)我們先使用e.pageX和e.pageY獲取到鼠標(biāo)當(dāng)前的坐標(biāo),得到之后用e.pageX-box.offsetLeft得到的就是盒子里面的鼠標(biāo)的位置了,話不多說(shuō),看圖解!
黑線-紅線得到的距離就是當(dāng)前鼠標(biāo)在盒子內(nèi)的位置。另外 由于遮罩層是一個(gè)盒子,鼠標(biāo)定位是緊貼著盒子的左上角的,我們需要將盒子往上移動(dòng)50%,往右移動(dòng)50%,讓鼠標(biāo)與盒子的中心點(diǎn)對(duì)齊。最后我們得到鼠標(biāo)的位置,并且判斷當(dāng)前是否處于盒子內(nèi)部,即判斷這個(gè)移動(dòng)的位置是否處于大于0且小于最大移動(dòng)距離之間。
代碼如下:
pic.addEventListener('mousemove', function (e) { var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; // mask移動(dòng)距離 var maskX = x - mask.offsetWidth / 2; var maskY = y - mask.offsetHeight / 2; var maskMax = pic.offsetWidth - mask.offsetWidth; // 判斷是否在盒子內(nèi)部 if (maskX <= 0) { maskX = 0; } else if (maskX >= maskMax) { maskX = maskMax; } if (maskY <= 0) { maskY = 0; } else if (maskY >= maskMax) { maskY = maskMax; } mask.style.left = maskX + 'px'; mask.style.top = maskY + 'px'; }
現(xiàn)在我們可以看到遮罩層可以在盒子內(nèi)部移動(dòng),并且不會(huì)超出盒子的范圍,那么本項(xiàng)目就到了最后一步,即讓旁邊的大盒子里的圖片能夠顯示出對(duì)應(yīng)的區(qū)塊。
因?yàn)閮蓮垐D片的比例相同,我們可以按照下圖公式進(jìn)行計(jì)算:
即:大圖片的移動(dòng)距離 = 遮擋層移動(dòng)距離 * 大圖片最大移動(dòng)距離 / 遮擋層的最大移動(dòng)距離
代入公式,我們就可以得到大圖片的移動(dòng)距離。注意,當(dāng)我們鼠標(biāo)從左往右滑時(shí),大圖片應(yīng)該是從右往左移,所以應(yīng)該是負(fù)值。
代碼如下:
// 大圖片的最大移動(dòng)距離 = 遮擋層移動(dòng)距離 * 大圖片最大移動(dòng)距離 / 遮擋層的最大移動(dòng)距離 var bigImg = document.querySelector('.bigImg'); bigMax = bigImg.offsetWidth - big.offsetWidth; var bigX = maskX * bigMax / maskMax; var bigY = maskY * bigMax / maskMax; bigImg.style.left = -bigX + 'px'; bigImg.style.top = -bigY + 'px';
至此,我們放大鏡的項(xiàng)目就完成啦,一步一步解析下來(lái)還是很簡(jiǎn)單的!主要是使用了offset系列屬性,那么介紹了offset系列屬性,不介紹一下他的另外兩個(gè)小伙伴怎么能行?補(bǔ)充介紹一下client系列和scroll系列。
完整代碼如下:
<!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> .box { position: relative; margin: 30px; width: 300px; height: 300px; /* pointer-events: none; */ /* cursor: alias; */ /* cursor: default; */ } .box_pic { width: 300px; height: 300px; border: 1px solid #ccc; } .mask { display: none; position: absolute; top: 0; left: 0; width: 200px; height: 200px; background-color: rgb(54, 240, 240); opacity: 0.5; cursor: all-scroll; z-index: 9; } .big { display: none; position: absolute; top: 0; left: 320px; width: 500px; height: 500px; overflow: hidden; border: 1px solid #ccc; } .big img { position: absolute; width: 800px; height: 800px; } </style> </head> <body> <div class="box"> <img src="./image/pic1.jpg" alt="" class="box_pic"> <div class="mask"></div> <div class="big"> <img src="./image/bigimg.jpg" alt="" class="bigImg"> </div> </div> </div> <script> var pic = document.querySelector('.box'); var mask = document.querySelector('.mask'); var big = document.querySelector('.big'); //出現(xiàn) 消失 pic.addEventListener('mouseenter', function () { mask.style.display = 'block'; big.style.display = 'block'; }) pic.addEventListener('mouseleave', function () { mask.style.display = 'none'; big.style.display = 'none'; }) // 移動(dòng) //獲取鼠標(biāo)位置 pic.addEventListener('mousemove', function (e) { var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; // mask移動(dòng)距離 var maskX = x - mask.offsetWidth / 2; var maskY = y - mask.offsetHeight / 2; var maskMax = pic.offsetWidth - mask.offsetWidth; // 判斷是否在盒子內(nèi)部 if (maskX <= 0) { maskX = 0; } else if (maskX >= maskMax) { maskX = maskMax; } if (maskY <= 0) { maskY = 0; } else if (maskY >= maskMax) { maskY = maskMax; } mask.style.left = maskX + 'px'; mask.style.top = maskY + 'px'; // 大圖片的最大移動(dòng)距離 = 遮擋層移動(dòng)距離 * 大圖片最大移動(dòng)距離 / 遮擋層的最大移動(dòng)距離 var bigImg = document.querySelector('.bigImg'); bigMax = bigImg.offsetWidth - big.offsetWidth; var bigX = maskX * bigMax / maskMax; var bigY = maskY * bigMax / maskMax; bigImg.style.left = -bigX + 'px'; bigImg.style.top = -bigY + 'px'; }) </script> </body> </html>
client系列
使用 client 系列的相關(guān)屬性來(lái)獲取元素可視區(qū)的相關(guān)信息。
client系列屬性:
注意:client包含padding值,返回值也不帶單位。
scroll系列
使用 scroll 系列的相關(guān)屬性可以動(dòng)態(tài)的得到該元素的大小、滾動(dòng)距離等。
scroll系列屬性:
三大系列總結(jié)
三大系列的內(nèi)容包含:
主要用法如下:
offset系列 經(jīng)常用于獲得元素位置 offsetLeft offsetTopclient經(jīng)常用于獲取元素大小 clientWidth clientHeightscroll 經(jīng)常用于獲取滾動(dòng)距離 scrollTop scrollLeft 注意頁(yè)面滾動(dòng)的距離通過(guò) window.pageXOffset 獲得
看完這篇博客,是不是把放大鏡案例直接拿下!本案例不算難,主要是通過(guò)這個(gè)案例復(fù)習(xí)BOM對(duì)象中的offset、client和scroll。我們還可以通過(guò)這些知識(shí)點(diǎn)完成模態(tài)框的制作、消滅星星案例哦~
以上就是Javascript實(shí)例項(xiàng)目放大鏡特效的實(shí)現(xiàn)流程的詳細(xì)內(nèi)容,更多關(guān)于Javascript 放大鏡特效的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Typescript中的as、問(wèn)號(hào)與感嘆號(hào)詳解
這篇文章主要介紹了Typescript中的as、問(wèn)號(hào)與感嘆號(hào)詳解,本文分別講述了這幾個(gè)關(guān)鍵字的含義作用以及實(shí)例,通過(guò)文字和代碼的描述,詳細(xì)的表達(dá).以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07javascript scrollLeft,scrollWidth,clientWidth,offsetWidth 完全
javascript scrollLeft,scrollWidth,clientWidth,offsetWidth 完全詳解,實(shí)例修正版。2009-07-07用JavaScript實(shí)現(xiàn)頁(yè)面重定向功能的教程
這篇文章主要介紹了用JavaScript實(shí)現(xiàn)頁(yè)面重定向功能的教程,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06基于JavaScript 數(shù)據(jù)類型之Boolean類型分析介紹
本篇文章小編為大家介紹,基于JavaScript 數(shù)據(jù)類型之Boolean類型分析介紹。需要的朋友參考下2013-04-04使用 TypeScript 重新編寫(xiě)的 JavaScript 坦克大戰(zhàn)游戲代碼
這篇文章主要介紹了使用 TypeScript 重新編寫(xiě)的 JavaScript 坦克大戰(zhàn)游戲代碼,主要是對(duì)自己近期學(xué)習(xí)TypeScript的一個(gè)小小的總結(jié)實(shí)踐,推薦給小伙伴們,希望大家能夠喜歡。2015-04-04簡(jiǎn)介JavaScript中toUpperCase()方法的使用
這篇文章主要介紹了JavaScript中的toUpperCase()方法的使用,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06Javascript基礎(chǔ)學(xué)習(xí)筆記(菜鳥(niǎo)必看篇)
下面小編就為大家?guī)?lái)一篇Javascript基礎(chǔ)學(xué)習(xí)筆記(菜鳥(niǎo)必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07