原生js實(shí)現(xiàn)一個(gè)放大鏡效果超詳細(xì)
前言:
學(xué)習(xí)js之初,寫過js放大鏡,但是當(dāng)時(shí)模模糊糊,似懂非懂,最近重溫js內(nèi)容,決定重寫了一下這個(gè)放大鏡效果,希望可以讓初學(xué)者對(duì)js-DOM的練習(xí)更好上手
一、放大鏡效果

二、實(shí)現(xiàn)步驟
1. 首先分析放大鏡結(jié)構(gòu)
- 左邊圖片:
img---原圖片 - 左邊圖片里面的類似于放大鏡的遮罩層:
glass---用于選擇需要放大的部分 - 右邊放大的圖片:
bigImg---用于展示放大效果
html代碼如下:
<div class="box">
<div class="glassWrapper">
<img src="./assets/green.jpg" class="img"/>
<div class="glass" id="glass"></div>
</div>
<div class="bigWrapper">
<img src="./assets/green.jpg" class="bigImg"/>
</div>
</div>2. 整體樣式---css部分
整體居中: 左右兩張圖片居中垂直使用flex布局,網(wǎng)上很多,這里不多說布局問題
右邊放大效果的關(guān)鍵樣式: 底部有一張大圖片,有一個(gè)固定的框展示放大的部分,超過這個(gè)展示款的部分就遮住,從而出現(xiàn)一種被放大的效果,使用:overflow: hidden;

圖片移動(dòng)的關(guān)鍵: 移動(dòng)的圖片使用:絕對(duì)定位(注意子絕父相)
css代碼:
.glassTitle {
color: #89cff0;
text-align: center;
}
.box {
width: 80vw;
min-width: 800px;
height: 80vh;
min-height: 600px;
line-height: 80vh;
display: flex;
align-items: center;
justify-content: space-around;
background-color: #f2f3f4;
margin: 10px auto;
border-radius: 10px;
box-shadow: 0px 0px 10px 1px #5d8aa8;
}
.glassWrapper{
line-height: 0;
position: relative;
}
.img {
display: block;
width: 250px;
height: auto;
}
.glass {
position: absolute;
width: 80px;
height: 80px;
background: #89cff0;
opacity: .5;
display: none;
}
.bigWrapper {
position: relative;
width: 500px;
height: 500px;
background-color: #fff;
border: 1px dashed #89cff0;
border-radius: 10px;
overflow: hidden;
}
.bigImg {
width: 2500px;
display: none;
position: absolute;
}3. JS操作dom實(shí)現(xiàn)放大鏡
現(xiàn)在樣式和結(jié)構(gòu)都準(zhǔn)備好了,就差來操作DOM了
1. 實(shí)現(xiàn)glass跟隨鼠標(biāo)移動(dòng)
效果是只要鼠標(biāo)進(jìn)入img中,就出現(xiàn)glass,出去就消失,所以給img添加鼠標(biāo)監(jiān)聽事件mouseover,原本img是display:none, 后變成display:block,離開img的鼠標(biāo)監(jiān)聽事件是mouseout,
const glassWrapper = document.querySelector('.glassWrapper'); // 放大鏡的盒子
? glassWrapper.addEventListener('mouseover', () => {
? ? glass.style.display = 'block';
? ? bigImg.style.display = 'block';
? });
? glassWrapper.addEventListener('mouseout', () => {
? ? glass.style.display = 'none';
? ? bigImg.style.display = 'none';
? })2. 實(shí)現(xiàn)glass跟隨鼠標(biāo)移動(dòng),并且鼠標(biāo)位于glass中央
如圖:

e.pageX是鼠標(biāo)相對(duì)于文檔(document)的水平坐標(biāo),e.pageY是鼠標(biāo)相對(duì)文檔的垂直坐標(biāo)glassWrapper.offsetWidth是glassWrapper元素的水平偏移位置,glassWrapper.offsetTop是glassWrapper元素的垂直偏移位置,e.pageX - glassWrapper.offsetLeft可以得到鼠標(biāo)相對(duì)于glassWrapper的偏移量xx - glass.offsetWidth / 2:x減去glass寬度的一半就可以得到glass相對(duì)于glassWrapper的偏移量,即可得到絕對(duì)定位的left,同理Top也可以得到- 以下代碼即可實(shí)現(xiàn)glass跟隨鼠標(biāo)移動(dòng)
為什么因?yàn)間lass是相對(duì)于glassWrapper而移動(dòng)的?因?yàn)閏ss里面的子絕父相
box.addEventListener('mousemove', (e) => {
// 該操作讓glassWrapper的左上角變成坐標(biāo)原點(diǎn), 因?yàn)間lass是先相對(duì)于glassWrapper而移動(dòng)的
const x = e.pageX - glassWrapper.offsetLeft;
const y = e.pageY - glassWrapper.offsetTop;
// 讓鼠標(biāo)在glass的中間位置
let width = x - glass.offsetWidth / 2;
let height = y - glass.offsetHeight / 2;
// 改變放大鏡的位置
glass.style.left = width + 'px';
glass.style.top = height + 'px';3. glass不超出img內(nèi)部
如圖絕對(duì)定位的left, 也就是width的最小是0,最大是glassWrapper.offsetWidth - glass.offsetWidth

box.addEventListener('mousemove', (e) => {
// 該操作讓glassWrapper的左上角變成坐標(biāo)原點(diǎn), 因?yàn)間lass是先相對(duì)于glassWrapper而移動(dòng)的
const x = e.pageX - glassWrapper.offsetLeft;
const y = e.pageY - glassWrapper.offsetTop;
// 讓鼠標(biāo)在glass的中間位置
let width = x - glass.offsetWidth / 2;
let height = y - glass.offsetHeight / 2;
// 讓glass不超出img內(nèi)部
+ if (width <= 0) {
+ width = 0;
+ } else if (width >= glassWrapper.offsetWidth - glass.offsetWidth) {
+ width = glassWrapper.offsetWidth - glass.offsetWidth;
+ }
+ if (height <= 0) {
+ height = 0;
+ } else if (height >= glassWrapper.offsetHeight - glass.offsetHeight) {
+ height = glassWrapper.offsetHeight - glass.offsetHeight;
+ }
// 改變放大鏡的位置
glass.style.left = width + 'px';
glass.style.top = height + 'px';
})4.重點(diǎn):放大的圖片的移動(dòng)--較難理解
- 首先確定放大比例并更改大圖片的大小
放大比例是由
glass和bigWrapper之間的比例來決定的,所以首先先計(jì)算大圖片應(yīng)該有多大,bigImg.style.width = img.offsetWidth * bigWrapper.offsetWidth / glass.offsetWidth + 'px';并且更改大圖片的大??;
- 移動(dòng)大圖片left的正負(fù)
小圖片
img和大圖片bigImg的left都是相對(duì)其父元素的,不同的是:左邊我們移動(dòng)的是glass, 而右邊我們移動(dòng)的是bigImg,glass往左邊移動(dòng)(left為正),相當(dāng)于視口相對(duì)于圖片往左邊移動(dòng),反過來,圖片就是相對(duì)于視口往右邊移(bigImg的left為負(fù)),所以bigImg的left和glass的left是符號(hào)是相反的
- left的比例
bigImg移動(dòng)的距離是glass移動(dòng)的距離之間的比例由:大圖片和小圖片之間的比例(或者glass和glassWrapper之間的比例)來決定
// 改變大圖片的位置
bigImg.style.width = img.offsetWidth * bigWrapper.offsetWidth / glass.offsetWidth + 'px';
bigImg.style.left = - width * bigImg.offsetWidth / img.offsetWidth + 'px';
bigImg.style.top = - height * bigImg.offsetHeight / img.offsetHeight + 'px';總結(jié)
到此這篇關(guān)于原生js實(shí)現(xiàn)一個(gè)放大鏡效果超詳細(xì)的文章就介紹到這了,更多相關(guān)js放大鏡效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)Select列表各項(xiàng)上移和下移的方法
這篇文章主要介紹了js實(shí)現(xiàn)Select列表各項(xiàng)上移和下移的方法,涉及javascript動(dòng)態(tài)操作頁(yè)面元素屬性值的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
JavaScript中跨標(biāo)簽頁(yè)通信的常見方式
跨標(biāo)簽頁(yè)通信是指在瀏覽器中的不同標(biāo)簽頁(yè)之間進(jìn)行數(shù)據(jù)傳遞和通信的過程,這篇文章為大家整理了幾個(gè)常見的跨標(biāo)簽頁(yè)通信方式,感興趣的小伙伴可以了解下2023-10-10
JavaScript中var let const的用法有哪些區(qū)別
在ES6(ES2015)出現(xiàn)之前,JavaScript中聲明變量就只有通過var關(guān)鍵字,函數(shù)聲明是通過function關(guān)鍵字,而在ES6之后,聲明的方式有var、let、const、function、class,本文主要討論var、let和const之間的區(qū)別2021-10-10
跟我學(xué)習(xí)javascript的定時(shí)器
跟我學(xué)習(xí)javascript的定時(shí)器,告訴大家具體的使用方法,并向大家提出了一個(gè)消息要求,制作一個(gè)定時(shí)器,有沒有朋友感興趣,挑戰(zhàn)一下2015-11-11
JS實(shí)現(xiàn)獲取圖片大小和預(yù)覽的方法完整實(shí)例【兼容IE和其它瀏覽器】
這篇文章主要介紹了JS實(shí)現(xiàn)獲取圖片大小和預(yù)覽的方法,結(jié)合完整實(shí)例形式分析了javascript針對(duì)不同瀏覽器處理圖片上傳與預(yù)覽等操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04
原生javascript實(shí)現(xiàn)勻速運(yùn)動(dòng)動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了原生javascript實(shí)現(xiàn)勻速運(yùn)動(dòng)動(dòng)畫效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02

