js实现图片放大镜功能,简单明了

请添加图片描述
写购物项目的时候,需要放大图片,这里用js写了一个方法,鼠标悬浮的时候放大当前图片

这个是class写法

<!--
 * @Descripttion: 
 * @Author: 苍狼一啸八荒惊
 * @LastEditTime: 2024-07-10 09:41:34
 * @LastEditors: 夜空苍狼啸
-->

<!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>商品详情</title>
  <!-- <link rel="stylesheet" href="./css/detail.css"> -->
  <style>
    .product_wrapper {
      
      
      width: 1200px;
      margin: 0 auto;
      font: 12px "Hiragino Sans GB", "Verdana", "Simsun";
      background-color: #fff;
    }


    .product_wrapper .detail {
      
      
      overflow: hidden;
    }

    .product_wrapper .detail .list_detail {
      
      
      width: 320px;
      height: 320px;
      float: left;
      padding: 0 20px 30px 0;
      position: relative;
    }

    .product_wrapper .detail .list_detail .list_detail_1 {
      
      
      width: 280px;
      height: 280px;
      position: relative;
    }

    .product_wrapper .detail .list_detail .list_detail_1>img {
      
      
      width: 100%;
      height: 100%;
    }

    .product_wrapper .detail .list_detail .list_detail_1 .mask {
      
      
      width: 150px;
      height: 150px;
      background: url(../img/zoom_pup.png);
      opacity: 0.5;
      position: absolute;
      left: 30px;
      top: 40px;
      pointer-events: none;
      display: none;
    }

    .product_wrapper .detail .list_detail .list_detail_2 {
      
      
      position: absolute;
      left: 0;
      bottom: 0;
      display: flex;
      justify-content: space-evenly;
      align-items: center;
    }

    .product_wrapper .detail .list_detail .list_detail_2>img {
      
      
      width: 54px;
      height: 54px;
      margin-right: 50px;
      cursor: pointer;
    }

    .product_wrapper .detail .list_detail .list_detail_2 .active {
      
      
      box-shadow: 0 0 8px rgb(255, 255, 255) inset, 0 0 8px red;
    }

    .product_wrapper .detail .list_detail .list_detail_enlarge {
      
      
      width: 480px;
      height: 480px;
      position: absolute;
      position: absolute;
      left: 90%;
      top: 0;
      overflow: hidden;
      display: none;
      z-index: 999;
    }

    .product_wrapper .detail .list_detail .list_detail_enlarge>img {
      
      
      display: block;
      width: 800px;
      height: 800px;
      position: absolute;
      left: 0;
      top: 0;
    }
  </style>
</head>

<body>


  <div class="product_wrapper">


    <div class="detail hover">
      <div class="list_detail" id="box">
        <!-- 放大镜 -->
        <div class="list_detail_1">
          <img src="./img/lx1.jpg" alt="">
          <div class="mask"></div>
        </div>
        <div class="list_detail_2">
          <img src="./img/lx1.jpg" class="active" alt="" data-show="./img/lx1.jpg" data-bg="./img/lx1.jpg">
          <img src="./img/lx2.jpg" alt="" data-show="./img/lx2.jpg" data-bg="./img/lx2.jpg">
          <img src="./img/lx3.jpg" alt="" data-show="./img/lx3.jpg" data-bg="./img/lx3.jpg">
        </div>
        <div class="list_detail_enlarge enlarge">
          <!-- <img src="./img/lx1.jpg" alt=""> -->
          <img src="http://img3m2.ddimg.cn/27/17/25583112-1_u_11.jpg" alt="">
        </div>


      </div>


    </div>
  </div>

  <!-- 引入放大镜 -->
  <!-- <script src="./js/detail.js"></script> -->
  <script>

    // 放大镜
    class Enlarge {
      
      
      constructor(select) {
      
      
        // 0-1. 获取到范围元素, 目的是为了让所有内容都出现在这里面
        this.ele = document.querySelector(select)
        this.show = this.ele.querySelector('.list_detail_1')
        this.mask = this.ele.querySelector('.mask')
        this.list = this.ele.querySelector('.list_detail_2')
        this.enlarge = this.ele.querySelector('.enlarge')
        this.bg = this.enlarge.firstElementChild
        // 需要一些尺寸数据
        this.show_w = this.show.clientWidth
        this.show_h = this.show.clientHeight
        // 非行内样式获取
        this.mask_w = parseInt(window.getComputedStyle(this.mask).width)
        this.mask_h = parseInt(window.getComputedStyle(this.mask).height)
        this.bg_w = parseInt(window.getComputedStyle(this.bg).width)
        this.bg_h = parseInt(window.getComputedStyle(this.bg).height)
        // 在这里调用函数来启动
        this.setScale()
        this.overOut()
        this.listChange()
        this.move()
      }
      // 计算数值
      setScale() {
      
      
        // 1. 计算数值
        this.enlarge_w = this.mask_w * this.bg_w / this.show_w
        this.enlarge_h = this.mask_h * this.bg_h / this.show_h

        // 2. 给 this.enlarge 赋值
        this.enlarge.style.width = this.enlarge_w + 'px'
        this.enlarge.style.height = this.enlarge_h + 'px'
      }
      // 鼠标经过显示遮罩层, 图片放大
      overOut() {
      
      
        this.show.addEventListener('mouseover', () => {
      
      
          this.mask.style.display = 'block'
          this.enlarge.style.display = 'block'
        })

        this.show.addEventListener('mouseout', () => {
      
      
          this.mask.style.display = 'none'
          this.enlarge.style.display = 'none'
        })
      }
      // tab 切换
      listChange() {
      
      
        this.list.addEventListener('click', e => {
      
      
          // 处理事件对象兼容
          e = e || window.event
          // 处理事件目标兼容
          const target = e.target || e.srcElement

          // 判断点击的是 img 标签
          if (target.nodeName !== 'IMG') return

          // 1. 切换 img 类名
          for (let i = 0; i < this.list.children.length; i++) {
      
      
            this.list.children[i].classList.remove('active')
          }
          target.classList.add('active')

          // 2. 切换 show里面img 和 bg 的 src
          const showUrl = target.dataset.show
          const bgUrl = target.dataset.bg

          this.show.firstElementChild.src = showUrl
          this.bg.src = bgUrl
        })
      }
      // 鼠标移动
      move() {
      
      
        // 1. 绑定事件
        this.show.addEventListener('mousemove', e => {
      
      
          e = e || window.event

          // 2. 获取光标坐标点
          let x = e.offsetX - this.mask_w / 2
          let y = e.offsetY - this.mask_h / 2

          // 3. 边界值判断
          if (x <= 0) x = 0
          if (y <= 0) y = 0
          if (x >= this.show_w - this.mask_w) x = this.show_w - this.mask_w
          if (y >= this.show_h - this.mask_h) y = this.show_h - this.mask_h

          this.mask.style.left = x + 'px'
          this.mask.style.top = y + 'px'

          const bg_x = x * this.enlarge_w / this.mask_w * -1
          const bg_y = y * this.enlarge_h / this.mask_h * -1

          this.bg.style.left = bg_x + 'px'
          this.bg.style.top = bg_y + 'px'
        })
      }
    }


    const enlarge = new Enlarge('#box')



  </script>

</body>

</html>

这个是函数写法

<!--
 * @Descripttion: 
 * @Author: 苍狼一啸八荒惊
 * @LastEditTime: 2024-07-10 09:41:34
 * @LastEditors: 夜空苍狼啸
-->

<!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>商品详情</title>
  <!-- <link rel="stylesheet" href="./css/detail.css"> -->
  <style>
    .product_wrapper {
      
      
      width: 1200px;
      margin: 0 auto;
      font: 12px "Hiragino Sans GB", "Verdana", "Simsun";
      background-color: #fff;
    }


    .product_wrapper .detail {
      
      
      overflow: hidden;
    }

    .product_wrapper .detail .list_detail {
      
      
      width: 320px;
      height: 320px;
      float: left;
      padding: 0 20px 30px 0;
      position: relative;
    }

    .product_wrapper .detail .list_detail .list_detail_1 {
      
      
      width: 280px;
      height: 280px;
      position: relative;
    }

    .product_wrapper .detail .list_detail .list_detail_1>img {
      
      
      width: 100%;
      height: 100%;
    }

    .product_wrapper .detail .list_detail .list_detail_1 .mask {
      
      
      width: 150px;
      height: 150px;
      background: url(../img/zoom_pup.png);
      opacity: 0.5;
      position: absolute;
      left: 30px;
      top: 40px;
      pointer-events: none;
      display: none;
    }

    .product_wrapper .detail .list_detail .list_detail_2 {
      
      
      position: absolute;
      left: 0;
      bottom: 0;
      display: flex;
      justify-content: space-evenly;
      align-items: center;
    }

    .product_wrapper .detail .list_detail .list_detail_2>img {
      
      
      width: 54px;
      height: 54px;
      margin-right: 50px;
      cursor: pointer;
    }

    .product_wrapper .detail .list_detail .list_detail_2 .active {
      
      
      box-shadow: 0 0 8px rgb(255, 255, 255) inset, 0 0 8px red;
    }

    .product_wrapper .detail .list_detail .list_detail_enlarge {
      
      
      width: 480px;
      height: 480px;
      position: absolute;
      position: absolute;
      left: 90%;
      top: 0;
      overflow: hidden;
      display: none;
      z-index: 999;
    }

    .product_wrapper .detail .list_detail .list_detail_enlarge>img {
      
      
      display: block;
      width: 800px;
      height: 800px;
      position: absolute;
      left: 0;
      top: 0;
    }
  </style>
</head>

<body>


  <div class="product_wrapper">


    <div class="detail hover">
      <div class="list_detail" id="box">
        <!-- 放大镜 -->
        <div class="list_detail_1">
          <img src="./img/lx1.jpg" alt="">
          <div class="mask"></div>
        </div>
        <div class="list_detail_2">
          <img src="./img/lx1.jpg" class="active" alt="" data-show="./img/lx1.jpg" data-bg="./img/lx1.jpg">
          <img src="./img/lx2.jpg" alt="" data-show="./img/lx2.jpg" data-bg="./img/lx2.jpg">
          <img src="./img/lx3.jpg" alt="" data-show="./img/lx3.jpg" data-bg="./img/lx3.jpg">
        </div>
        <div class="list_detail_enlarge enlarge">
          <img src="./img/lx1.jpg" alt="">
        </div>


      </div>


    </div>
  </div>

  <!-- 引入放大镜 -->
  <!-- <script src="./js/detail.js"></script> -->
  <script>
    /*
 * @Descripttion: 
 * @Author: 苍狼一啸八荒惊
 * @LastEditTime: 2024-07-10 10:18:57
 * @LastEditors: 夜空苍狼啸
 */

// 放大镜


// 0-1. 获取到范围元素, 目的是为了让所有内容都出现在这里面
let ele = document.querySelector('#box')
let show = ele.querySelector('.list_detail_1')
let mask = ele.querySelector('.mask')
let list = ele.querySelector('.list_detail_2')
let enlarge = ele.querySelector('.enlarge')
let bg = enlarge.firstElementChild
// 需要一些尺寸数据
let show_w = show.clientWidth
let show_h = show.clientHeight
// 非行内样式获取
let mask_w = parseInt(window.getComputedStyle(mask).width)
let mask_h = parseInt(window.getComputedStyle(mask).height)
let bg_w = parseInt(window.getComputedStyle(bg).width)
let bg_h = parseInt(window.getComputedStyle(bg).height)


// 计算数值
// 1. 计算数值
enlarge_w = mask_w * bg_w / show_w
enlarge_h = mask_h * bg_h / show_h

// 2. 给 enlarge 赋值
enlarge.style.width = enlarge_w + 'px'
enlarge.style.height = enlarge_h + 'px'

// 鼠标经过显示遮罩层, 图片放大

show.addEventListener('mouseover', () => {
      
      
    mask.style.display = 'block'
    enlarge.style.display = 'block'
})

show.addEventListener('mouseout', () => {
      
      
    mask.style.display = 'none'
    enlarge.style.display = 'none'
})

// tab 切换

list.addEventListener('click', e => {
      
      
    // 处理事件对象兼容
    e = e || window.event
    // 处理事件目标兼容
    const target = e.target || e.srcElement

    // 判断点击的是 img 标签
    if (target.nodeName !== 'IMG') return

    // 1. 切换 img 类名
    for (let i = 0; i < list.children.length; i++) {
      
      
        list.children[i].classList.remove('active')
    }
    target.classList.add('active')

    // 2. 切换 show里面img 和 bg 的 src
    const showUrl = target.dataset.show
    const bgUrl = target.dataset.bg

    show.firstElementChild.src = showUrl
    bg.src = bgUrl
})

// 鼠标移动

// 1. 绑定事件
show.addEventListener('mousemove', e => {
      
      
    e = e || window.event

    // 2. 获取光标坐标点
    let x = e.offsetX - mask_w / 2
    let y = e.offsetY - mask_h / 2

    // 3. 边界值判断
    if (x <= 0) x = 0
    if (y <= 0) y = 0
    if (x >= show_w - mask_w) x = show_w - mask_w
    if (y >= show_h - mask_h) y = show_h - mask_h

    mask.style.left = x + 'px'
    mask.style.top = y + 'px'

    const bg_x = x * enlarge_w / mask_w * -1
    const bg_y = y * enlarge_h / mask_h * -1

    bg.style.left = bg_x + 'px'
    bg.style.top = bg_y + 'px'
})







  </script>

</body>

</html>

猜你喜欢

转载自blog.csdn.net/qq_43940789/article/details/140315392