javascript
JS实现购物网站商品放大镜效果
一、需求說明
1、鼠標移入圖片顯示遮罩層和右邊的放大鏡
??????鼠標移出圖片隱藏遮罩層和右邊的放大鏡
2、鼠標經過下面的圖片列表區切換顯示的圖片
3、鼠標在顯示的圖片上移動,遮罩層也會跟著移動,并且放大的圖片也會跟著對應移動
二、核心代碼
// 放大鏡構造函數 // 參數1 生成放大鏡內容的標簽對象 // 參數2 放大鏡參數數據數組 class setGlass {constructor(element, array) {// 定義屬性存儲參數this.ele = element;this.arr = array;// 定義屬性存儲數據this.show;this.img;this.mask;this.list;this.listLiImg;this.glass;}// 入口函數init() {// 入口函數中調用所有需要執行的函數程序this.setPage();this.setMouseOver();this.setMouseMove();}// 動態生成頁面setPage() {// 創建標簽對象this.show = document.createElement('div');this.mask = document.createElement('div');this.glass = document.createElement('div');this.img = document.createElement('img');this.list = document.createElement('ul');// 設定標簽對象的相關屬性// 顯示區 設定 class選擇器this.show.classList.add('show');this.mask.classList.add('mask');this.list.classList.add('list');this.glass.classList.add('glass');// 圖片標簽 默認顯示 數組中 第一組數據中 large圖片this.img.setAttribute('src', `./images/${this.arr[0].large}`);// 圖片標簽 添加name屬性值this.img.setAttribute('name', 'showImg');this.mask.setAttribute('name', 'showImg');// 顯示區中 有 圖片標簽 和 遮蓋層標簽this.show.appendChild(this.img);this.show.appendChild(this.mask);// 給 this.show 這個節點 直接 綁定事件// 綁定好事件之后 再 執行寫入操作// 之后 即使 再次動態渲染生成頁面 也是 創建新的this.show節點 同時綁定事件 再寫入節點this.show.addEventListener('mouseenter', () => {// 移入 讓 遮蓋層 和 放大鏡 顯示this.mask.style.display = 'block';this.glass.style.display = 'block';})this.show.addEventListener('mouseleave', () => {// 移入 讓 遮蓋層 和 放大鏡 隱藏this.mask.style.display = 'none';this.glass.style.display = 'none';})// 根據數組生成 list 中 li 標簽對象let liStr = '';this.arr.forEach((item, key) => {liStr += key === 0 ? `<li><img name="liImg" class="active" index="${key}" src="./images/${item.small}" alt=""></li>` : `<li><img name="liImg" index="${key}" src="./images/${item.small}" alt=""></li>`})// 將 字符串 寫入 list,ul標簽中this.list.innerHTML = liStr;// 將 標簽對象 寫入 box,div標簽 中this.ele.appendChild(this.show);this.ele.appendChild(this.list);this.ele.appendChild(this.glass);// 將 標簽對象 寫入 box,div標簽 之后 // 獲取 list 標簽中的 li標簽 中的 img標簽this.listLiImg = this.list.querySelectorAll('li>img');}// 鼠標 移入 圖片// 只有 移入沒有移出 可以 事件委托添加給 圖片標簽setMouseOver() {// 給 父級div標簽 添加 鼠標移入事件this.ele.addEventListener('mouseover', e => {// 如果 移入的標簽 name 是 liImg 證明 移入的是 列表 圖片標簽if (e.target.getAttribute('name') === 'liImg') {// 1 清除其他的img標簽 class,active 給 移入的img標簽添加 class,active// 循環遍歷 所有的 li>img 清除 class,activethis.listLiImg.forEach(item => {// item 就是 圖片標簽對象item.classList.remove('active');})// 給經過的 li>img 添加 class,activee.target.classList.add('active');// 2 設定 show顯示區域中img標簽src屬性 // 是 鼠標進過的 li>img 標簽 index屬性中 存儲的索引下標this.img.setAttribute('src', `./images/${this.arr[Number(e.target.getAttribute('index'))].large}`);// 3 設定 glass放大鏡中背景圖片的css樣式this.glass.style.backgroundImage = `url('./images/${this.arr[Number(e.target.getAttribute('index'))].large}')`;}})}// 鼠標 拖住效果setMouseMove() {// 如果視窗窗口大小改變,刷新頁面window.addEventListener('resize', function () {window.location.reload();})// 獲取 數據 // 獲取 box,div的 外間距let oBoxLeft = this.ele.offsetLeft;let oBoxTop = this.ele.offsetTop;// 獲取 show,div的 邊框線let oShowBorderLeft = this.show.clientLeft;let oShowBorderTop = this.show.clientTop;// 獲取 show,div的 占位 內容+padding// 用來設置極值let oShowWidth = this.show.clientWidth;let oShowHeight = this.show.clientHeight;console.log(oShowWidth);let oShowWidth1 = this.show.offsetWidth;let oShowHeight1 = this.show.offsetHeight;// 獲取 mask,div的 占位 內容+padding+borderlet oMaskWidth = parseInt(window.getComputedStyle(this.mask).width);let oMaskHeight = parseInt(window.getComputedStyle(this.mask).height);// 給 父級div標簽 添加 鼠標移動事件// 如果 是 在 show,div 中 img標簽 觸發移動事件 執行 鼠標拖拽效果this.ele.addEventListener('mousemove', e => {// 事件對象標簽 name 是 showImg 證明 觸發的標簽是 show,div中的img標簽if (e.target.getAttribute('name') === 'showImg') {// 1, 計算設定 遮蓋層定位數據let x = e.pageX - oBoxLeft - oShowBorderLeft - oMaskWidth / 2;let y = e.pageY - oBoxTop - oShowBorderTop - oMaskHeight / 2;// 2, 設定極值x = x < 0 ? 0 : x;y = y < 0 ? 0 : y;x = x > oShowWidth - oMaskWidth ? oShowWidth - oMaskWidth : x;y = y > oShowHeight - oMaskHeight ? oShowHeight - oMaskHeight : y;// 3, 將 遮蓋層定位賦值this.mask.style.left = x + 'px';this.mask.style.top = y + 'px';// 4, 設定 背景圖片定位數值 // 和 遮蓋層定位數值方向相反 比例關系 是 2.5 倍this.glass.style.backgroundPosition = `${-x * 2.5}px ${-y * 2.5}px`;}})} }三、解釋說明
放大鏡
? ????? 1, 放大鏡 默認起始顯示 第一組圖片內容
? ????? 2, 放大鏡div中顯示的 背景圖片
? ????? 3, 各個區域內容的原始比例關系
? ????? ? ????? ? ????? 遮蓋層 ? ????? ? ?? 放大鏡
? ????? ? ????? ? ????? --------? ?? = ? ??-----------
? ????? ? ????? ? ????? 顯示區 ? ????? ? ??背景圖片
重點內容:外部 js 文件中的相對路徑
? 不是寫外部 js 文件的相對路徑,寫的是加載執行這個 js 文件的 html 文件的相對路徑,意思就是: js 里面的圖片路徑是從這個 html 文件出發去尋找圖片的,而不是從 js 出發。
重點內容:子級標簽添加鼠標移入移出事件
? 不能通過事件委托給父級標簽添加事件,實現子級標簽的移入、移出;因為子級標簽觸發over 移入的同時也會觸發父級標簽的 out 移出事件。
? 在創建標簽時直接給創建的子級標簽節點添加事件,添加好事件之后,將標簽節點寫入,也就是每次寫入的節點都是綁定好事件的節點。
給列表區中的 img標簽添加鼠標移入事件
只有鼠標移入,沒有鼠標移出,因此可以通過事件委托的語法形式給 img標簽添加事件。
需要注意:
- img標簽設定的是標簽的 src屬性的屬性值
- div標簽設定的是 backgroundImage背景圖片的路徑樣式
鼠標拖動效果
獲取數據:
-
display: none / 絕對定位 / 固定定位 的標簽,沒有占位大小,
-
只能通過標簽的 css 樣式屬性獲取占位大小。在獲取 mask的占位時用到了。
-
遮蓋層移動和背景圖片移動的比例關系
-
遮蓋層移動和背景圖片移動方向相反
-
移動數值成等比例關系
遮蓋層 ? ????? ? ? ?? 顯示區 ? ????? ? ? ? 遮蓋層定位 ? ????? ? ?
---------- ? ??= ? ?? -------------? ??=? ??------------------? ??? ??
放大鏡 ? ????? ? ? ? 背景圖片 ???? ? ? 背景圖片定位 ? ????? ? ?
-
比例關系怎么確定?
- 若遮罩層移動到最右邊,那么背景圖要移動到最左邊
- 遮罩層到最右邊需要移動 顯示區的大小(400) - 遮罩層的大小(200) = 200
- 背景圖到最左邊需要移動 背景圖的大小(1000) - 放大鏡的大小(500) = 500
- 他們移動距離的比值是:200/500 = 1/2.5
-
四、效果演示
五、完整代碼下載
???????????下載地址
總結
以上是生活随笔為你收集整理的JS实现购物网站商品放大镜效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sdcms_php_web,SDCMS通
- 下一篇: DITA Topic常用开发