真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

純JS實(shí)現(xiàn)放大縮小拖拽功能(完整代碼)

前言

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括金鄉(xiāng)網(wǎng)站建設(shè)、金鄉(xiāng)網(wǎng)站制作、金鄉(xiāng)網(wǎng)頁(yè)制作以及金鄉(xiāng)網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,金鄉(xiāng)網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到金鄉(xiāng)省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!

最近團(tuán)隊(duì)需要做一個(gè)智能客服懸浮窗功能,需要支持拖動(dòng)、放大縮小等功能,因?yàn)檫@個(gè)是全局插件,為了兼容性考慮全部使用原生 JS 實(shí)現(xiàn),不引用任何第三方庫(kù)或者插件。開(kāi)發(fā)過(guò)程中遇到的一些問(wèn)題及解決方法,在這里和大家分享交流一下。

注:下文出現(xiàn)的“采寶”二字,為這個(gè)功能的產(chǎn)品名。

先看效果

純 JS 實(shí)現(xiàn)放大縮小拖拽功能(完整代碼) 

看這個(gè)效果,相信大部分開(kāi)發(fā)都會(huì)覺(jué)得實(shí)現(xiàn)起來(lái)比較容易。在實(shí)際開(kāi)發(fā)中,筆者總結(jié)了三個(gè)主要的坑點(diǎn),及其解決方案。

三個(gè)坑點(diǎn)

  • 拖拽采寶時(shí)會(huì)導(dǎo)致采寶放大縮小
  • 采寶顯示在屏幕邊界時(shí)被遮擋顯示不全
  • 采寶放大和縮小后,位置發(fā)生變化

(一)拖拽時(shí)會(huì)導(dǎo)致采寶放大縮小

我們?cè)诓僮鞑蓪殨r(shí),不管是鼠標(biāo)拖動(dòng)還是點(diǎn)擊放大縮小,我們的事件都需要綁定在采寶頭部的圖標(biāo)上,這樣我們就需要在圖標(biāo)上同時(shí)綁定點(diǎn)擊和拖拽事件。但是當(dāng)我們直接添加 click 事件和 mousedown 事件的時(shí)候,我們發(fā)現(xiàn)在觸發(fā) mousedown 事件的時(shí)候,也會(huì)去觸發(fā) click 事件。這樣就會(huì)出現(xiàn)在拖動(dòng)采寶的時(shí)候,采寶會(huì)放大和縮小。

純 JS 實(shí)現(xiàn)放大縮小拖拽功能(完整代碼) 

這個(gè)效果是我們不想看到的,所以我們就需要區(qū)分開(kāi)采寶上的 click 事件和 mousedown 事件,想辦法使兩個(gè)事件的觸發(fā)相互不影響。

所以我們?cè)谕粋€(gè) DIV 上同時(shí)綁定 mousedown 事件和 click 事件,然后通過(guò)控制臺(tái)輸出每個(gè)事件,查看過(guò)程中的每個(gè)事件的觸發(fā)順序。

const moveBox = document.querySelector('.move');
moveBox.onmousedown = function (evt) {
 console.log('觸發(fā)鼠標(biāo)按下')
 moveBox.onmousemove = function (evt) {
 console.log('觸發(fā)鼠標(biāo)拖動(dòng)')
 }
}
function moveBoxClick(e) {
 console.log('觸發(fā)click')
}
moveBox.onmouseup = function () {
 console.log('觸發(fā)鼠標(biāo)抬起')
}

然后我們得到的結(jié)果是:

純 JS 實(shí)現(xiàn)放大縮小拖拽功能(完整代碼) 

通過(guò)控制臺(tái)的輸出情況,我們就可以看到鼠標(biāo)點(diǎn)擊后的各個(gè)事件觸發(fā)情況:首先執(zhí)行的是 mousedown 事件,然后是 mousemove 事件,再然后是 mouseup 事件,最后是 click 事件。

知道了事件的觸發(fā)順序,我們就可以通過(guò)設(shè)置一個(gè)變量 isMove 來(lái)區(qū)分開(kāi)鼠標(biāo)的拖動(dòng)事件和點(diǎn)擊事件,每次鼠標(biāo)按下的時(shí)候我們將 isMove 復(fù)原,鼠標(biāo)移動(dòng)的時(shí)候?qū)?isMove 的狀態(tài)改變。

因?yàn)槊看斡|發(fā) click 事件的時(shí)候也都會(huì)去先去觸發(fā) mousedown 事件,所以我們?cè)?click 事件里增加一個(gè)判斷,鼠標(biāo)移動(dòng)時(shí),不觸發(fā) click 事件。這樣就可以把 click 事件和 mousedown 事件區(qū)分開(kāi)來(lái),實(shí)現(xiàn) mousedown 和 click 事件的隔離。

click 事件增加判斷

function moveBoxClick(e) {
 // 點(diǎn)擊采寶
 const target = document.querySelector(".move");
 const smallImg = document.querySelector(".small-img");
 const magnifyImg = document.querySelector(".magnify-img");
 // 點(diǎn)擊move盒子
 if (!isMove) {
 if (isBig) {
  smallImg.style.display = "block";
  magnifyImg.style.display = "none";
  target.style.width = "32px";
 } else {
  smallImg.style.display = "none";
  magnifyImg.style.display = "block";
  target.style.width = "130px";
 }
 isBig = !isBig;
 }
}
mousedown 事件重置 isMove 和 mousemove 改變 isMove
let isMove = false; // 是否是拖動(dòng)
let isBig = false; // 是否是變大的盒子
let isMove = false; // 判斷是否移動(dòng)采寶
smallImg.onmousedown = magnifyImg.onmousedown = function(evt) {
 isMove = false; // 每次鼠標(biāo)按下時(shí),重置isMove
 document.onmousemove = function(e) {
 isMove = true; // 每次鼠標(biāo)移動(dòng)時(shí),改變isMove
 };
};

通過(guò) isMove 的狀態(tài),我們就可以區(qū)分開(kāi) mousemove 事件和 click 事件,使得我們?cè)谕蟿?dòng)采寶的時(shí)候,可以不去觸發(fā)采寶放大縮小。

(二)采寶顯示在屏幕邊界時(shí)被遮擋顯示不全

我們?cè)谕蟿?dòng)采寶時(shí),判斷采寶拖動(dòng)的當(dāng)前定位坐標(biāo)是否超出了當(dāng)前顯示屏的高度和寬度,我們需要限制采寶拖動(dòng)的最大距離。小采寶在點(diǎn)擊放大時(shí),也需要做一下處理,把采寶全部顯示出來(lái)。

拖動(dòng)時(shí)

const moveBox = document.querySelector(".move");
const smallImg = document.querySelector(".move .small-img");
const magnifyImg = document.querySelector(".move .magnify-img");
let isMove = false; // 是否是拖動(dòng)
let isBig = false; // 是否是變大的盒子

smallImg.onmousedown = magnifyImg.onmousedown = function(evt) {
 // 拖動(dòng)div盒子
 const clientX = evt.clientX;
 const clientY = evt.clientY;
 const pageX = moveBox.offsetLeft;
 const pageY = moveBox.offsetTop;
 const x = clientX - pageX;
 const y = clientY - pageY;

 document.onmousemove = function(e) {
 // 拖動(dòng)后采寶的坐標(biāo)
 let _x = e.clientX - x;
 let _y = e.clientY - y;
 const boxWidth = moveBox.offsetWidth;
 const boxHeight = moveBox.offsetHeight;
 if (_x < 0) {
  _x = 0;
 }
 // X坐標(biāo)的最大值
 if (_x > window.screen.width - boxWidth) {
  _x = window.screen.width - boxWidth;
 }
 if (_y < 0) {
  _y = 0;
 }
 // Y坐標(biāo)的最大值
 if (_y > document.documentElement.clientHeight - boxHeight) {
  _y = document.documentElement.clientHeight - boxHeight;
 }
 };
};
小采寶在邊界放大時(shí)
// 點(diǎn)擊時(shí),判斷采寶是否超出顯示屏
function autoPotion () {
 let x = moveBox.offsetLeft;
 let y = moveBox.offsetTop;

 if (x < 0) {
  x = 0;
 } else if (x > document.documentElement.clientWidth - moveBox.offsetWidth) {
  x = document.documentElement.clientWidth - moveBox.offsetWidth;
 }

 if (y < 0) {
  y = 0;
 } else if (y > document.documentElement.clientHeight - moveBox.offsetHeight) {
  y = document.documentElement.clientHeight - moveBox.offsetHeight;
 }

 moveBox.style.left = x + "px";
 moveBox.style.top = y + "px";
}

效果如下

純 JS 實(shí)現(xiàn)放大縮小拖拽功能(完整代碼) 

(三)采寶放大和縮小后,位置發(fā)生變化

通過(guò)上圖,我們可以看到,當(dāng)小采寶處在顯示屏邊界時(shí),點(diǎn)擊放大后再點(diǎn)擊縮小,我們發(fā)現(xiàn)采寶的位置發(fā)生了變化。這個(gè)是因?yàn)椴蓪毷歉鶕?jù)左上角的坐標(biāo)來(lái)定位的,當(dāng)小采寶移動(dòng)到右下角時(shí),點(diǎn)擊放大以后,采寶左上角的坐標(biāo)發(fā)生了變化,這樣就使得采寶在放大縮小時(shí),位置在發(fā)生變化。所以,我們?cè)诓蓪氁苿?dòng)完成時(shí)需要記錄采寶左上角的坐標(biāo),在點(diǎn)擊時(shí),需要將采寶上次移動(dòng)完成的坐標(biāo)重新賦值給采寶,這樣就使得采寶在放大縮小時(shí),位置不會(huì)發(fā)生變化。

純 JS 實(shí)現(xiàn)放大縮小拖拽功能(完整代碼) 

這樣,我們把每次 mouseup 事件的時(shí)候記錄下采寶的位置,這樣我們解決了采寶放大縮小時(shí)位置發(fā)生變化的問(wèn)題。

完整的代碼

HTML:

JavaScript const moveBox = document.querySelector(".move"); const smallImg = document.querySelector(".move .small-img"); const magnifyImg = document.querySelector(".move .magnify-img"); var initX = 0; // 記錄小采寶的x坐標(biāo) var initY = 0; // 記錄小采寶的y坐標(biāo) let isMove = false; // 是否是拖動(dòng) let isBig = false; // 是否是變大的盒子 smallImg.onmousedown = magnifyImg.onmousedown = function(evt) { // 拖動(dòng)div盒子 const clientX = evt.clientX; const clientY = evt.clientY; const pageX = moveBox.offsetLeft; const pageY = moveBox.offsetTop; const x = clientX - pageX; const y = clientY - pageY; isMove = false; document.onmousemove = function(e) { const boxWidth = moveBox.offsetWidth; const boxHeight = moveBox.offsetHeight; let _x = e.clientX - x; let _y = e.clientY - y; if (_x < 0) { _x = 0; } if (_x > window.screen.width - boxWidth) { _x = window.screen.width - boxWidth; } if (_y < 0) { _y = 0; } if (_y > document.documentElement.clientHeight - boxHeight) { _y = document.documentElement.clientHeight - boxHeight; } if (isBig) { initX = _x; initY = _y; } moveBox.style.left = _x + "px"; moveBox.style.top = _y + "px"; isMove = true; }; }; document.onmouseup = function() { if (isMove) { initX = moveBox.offsetLeft; initY = moveBox.offsetTop; } document.onmousemove = null; }; function moveBoxClick(e) { const target = document.querySelector(".move"); const smallImg = document.querySelector(".small-img"); const magnifyImg = document.querySelector(".magnify-img"); // 點(diǎn)擊move盒子 if (!isMove) { if (isBig) { smallImg.style.display = "block"; magnifyImg.style.display = "none"; target.style.width = "32px"; target.style.left = initX + 'px'; target.style.top = initY + 'px'; } else { smallImg.style.display = "none"; magnifyImg.style.display = "block"; target.style.width = "130px"; } isBig = !isBig; setTimeout(() => { autoPotion(); }, 100) } } // 點(diǎn)擊時(shí),判斷采寶是否超出顯示屏 function autoPotion () { let x = moveBox.offsetLeft; let y = moveBox.offsetTop; if (x < 0) { x = 0; } else if (x > document.documentElement.clientWidth - moveBox.offsetWidth) { x = document.documentElement.clientWidth - moveBox.offsetWidth; } if (y < 0) { y = 0; } else if (y > document.documentElement.clientHeight - moveBox.offsetHeight) { y = document.documentElement.clientHeight - moveBox.offsetHeight; } moveBox.style.left = x + "px"; moveBox.style.top = y + "px"; }

總結(jié)

以上所述是小編給大家介紹的純 JS 實(shí)現(xiàn)放大縮小拖拽功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!


標(biāo)題名稱(chēng):純JS實(shí)現(xiàn)放大縮小拖拽功能(完整代碼)
文章源于:http://weahome.cn/article/pjojss.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部