模仿电商放大镜功能

css:

* {
  padding: 0;
  margin: 0;
  list-style: none;
}
.xiehContent {
  width: 450px;
  height: 602px;
  border: 1px solid red;
  margin-left: 10px;
  margin-top: 10px;
}
.xiehContent > .box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  position: relative;
}
.xiehContent > .box > .show {
  width: 450px;
  height: 450px;
  border: 1px solid chocolate;
  position: relative;
  cursor: none;
}
.xiehContent > .box > .show > .mask {
  width: 200px;
  height: 200px;
  position: absolute;
  top: 0px;
  left: 0px;
  background-color: rgba(255, 235, 59, 0.5);
  pointer-events: none;
  display: none;
}
.xiehContent > .box > .show > .mask.active {
  display: block;
}
.xiehContent > .box > .enlarge {
  width: 500px;
  height: 500px;
  border: 1px solid rebeccapurple;
  position: absolute;
  top: 0px;
  left: 105%;
  background-image: url(../img/iPhone12_big.jpg);
  background-size: 800px 800px;
  background-repeat: no-repeat;
  display: none;
}
.xiehContent > .box > .enlarge.active {
  display: block;
}
.xiehContent > .box > .list {
  width: 450px;
  height: 150px;
  border-top: 2px solid #333;
  box-sizing: border-box;
  padding: 20px 20px;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
}
.xiehContent > .box > .list ul {
  white-space: nowrap;
}
.xiehContent > .box > .list ul li {
  width: 60px;
  height: 60px;
  display: inline-block;
  border: 1px solid grey;
  cursor: pointer;
}
.xiehContent > .box > .list ul li.active {
  border: 1px solid red;
}
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}
::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  background-color: transparent;
  border-radius: 100px;
}
::-webkit-scrollbar-thumb {
  border-radius: 100px;
  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  background-color: #0D9FE3;
}
::-webkit-scrollbar-button {
  background-color: transparent;
}
::-webkit-scrollbar-corner {
  background: khaki;
}

html:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="css/enlarge.css">
    </head>

    <body>
        <div class="xiehContent">
            <div class="box">

                <div class="show">
                    <!-- 展示图片 -->
                    <img src="img/iPhone12_normal.jpg" style="display: block;" width="100%" height="100%" alt="">
                    <!-- 遮罩层 -->
                    <div class="mask"></div>
                </div>

                <!-- 放大镜 -->
                <div class="enlarge"></div>

                <div class="list">
                    <ul class="clearfix">
                        <li class="active">
                            <img src="img/iPhone12_small.jpg" data-show="img/iPhone12_normal.jpg" jqimg="img/iPhone12_big.jpg" width="100%" height="100%" alt="">
                        </li>
                        <li>
                            <img src="img/pic_small.jpg" data-show="img/pic_normal.jpg" jqimg="img/pic_big.jpg" width="100%" height="100%" alt="">
                        </li>

                    </ul>
                </div>

            </div>
        </div>

    </body>
    <script src="js/enlarge.js"></script>
    <script type="text/javascript">
        let e = new Enlarge(".xiehContent>.box");
        e.init();
        console.log(e);
    </script>

</html>

js:

/***
 * 思路:
 * 1.得到需要操作的元素
 * 2.鼠标移出移出,遮罩显示隐藏
 * 3.调整某个元素的大小,成比例
 *     遮罩mask的尺寸        enlarge的尺寸
 * ------------- = --------------
 *  show盒子的尺寸        enlarge背景图的尺寸
 * 
 * enlarge的尺寸 = 遮罩mask的尺寸 * enlarge背景图的尺寸 / show盒子的尺寸    ;
 * 
 * 4.移动
 */

function Enlarge(ele) {
    // 父元素
    this.ele = document.querySelector(ele);

    // 找到.show元素
    this.show = document.querySelector(ele + ">.show");

    // 找到mask遮罩层
    this.mask = document.querySelector(ele + ">.show>.mask");

    //找到放大镜enlarge
    this.enlarge = document.querySelector(ele + ">.enlarge");

    // 找到list
    this.list = document.querySelector(ele + ">.list");
    
    // 找到ul
    this.ulcontent = document.querySelector(ele + ">.list>ul");
    
    
    // 遮罩层尺寸
    this.mask_width = parseInt(window.getComputedStyle(this.mask).width);
    this.mask_height = parseInt(window.getComputedStyle(this.mask).height);
    
    // show盒子尺寸
    this.show_width = parseInt(window.getComputedStyle(this.show).width);
    this.show_height = parseInt(window.getComputedStyle(this.show).height);
    
    // enlarge的尺寸
    this.enlarge_width = parseInt(window.getComputedStyle(this.enlarge).width);
    this.enlarge_height = parseInt(window.getComputedStyle(this.enlarge).height);
    
    // enlarge的背景图尺寸
    const bg = window.getComputedStyle(this.enlarge).backgroundSize.split(" ");
    this.enlarge_bg_width = parseInt(bg[0]);
    this.enlarge_bg_height = parseInt(bg[1]);
}


/**
 * 鼠标移入移出,显示隐藏遮罩层mask
 */
Enlarge.prototype.overOut = function(){
    
    this.show.addEventListener("mouseenter",()=>{
        this.mask.classList.add("active");
        this.enlarge.classList.add("active");
    });
    
    this.show.addEventListener("mouseleave",()=>{
        this.mask.classList.remove("active");
        this.enlarge.classList.remove("active");
    });
    
}

/**
 * 设置比例
 *  遮罩mask的尺寸        enlarge的尺寸
 * ------------- = --------------
 *  show盒子的尺寸        enlarge背景图的尺寸
 * 
 * enlarge的尺寸 = 遮罩mask的尺寸 * enlarge背景图的尺寸 / show盒子的尺寸    ;
 */
Enlarge.prototype.setScaleEnlarge = function(){
    
    const newEnlargeWidth = (this.mask_width * this.enlarge_bg_width / this.show_width);
    const newEnlargeHeight = (this.mask_height * this.enlarge_bg_height / this.show_height);

    // 设置enlarge的尺寸
    this.enlarge.style.width = newEnlargeWidth + "px";
    this.enlarge.style.height = newEnlargeHeight + "px";
    
    // 因为初始化时,是css中设置的enlarge的尺寸,这里被修改了,需要同步调整
    this.enlarge_width = newEnlargeWidth;
    this.enlarge_height = newEnlargeHeight;
    
}


/**
 * 设置比例
 *  遮罩mask的尺寸        enlarge的尺寸
 * ------------- = --------------
 *  show盒子的尺寸        enlarge背景图的尺寸
 * 
 * enlarge背景图的尺寸 = enlarge的尺寸 * show盒子的尺寸 / 遮罩mask的尺寸;
 */
Enlarge.prototype.setScaleBg = function(){
    // 设置背景图尺寸
    const bg_width = (this.enlarge_width * this.show_width / this.mask_width);
    const bg_height = (this.enlarge_height * this.show_height / this.mask_height);
    
    // 注意两个px之间有个空格隔开!
    this.enlarge.style.backgroundSize = bg_width + "px " + bg_height + "px";
    
    // 因为初始化时,是css中设置的enlarge的背景尺寸,这里被修改了,需要同步调整
    this.enlarge_bg_width = bg_width;
    this.enlarge_bg_height = bg_height;
}


/**
 *   遮罩层尺寸        enlarge尺寸
 * ------------ = --------------
 *  遮罩层移动距离           enlarge背景图移动距离(负数)
 * 
 * enlarge背景图移动距离  = enlarge尺寸  *  遮罩层移动距离  / 遮罩层尺寸
 */
Enlarge.prototype.move = function(){
    // 给show盒子绑定事件
    this.show.addEventListener("mousemove",e =>{
        e = e ||window.event;
        
        let x = e.offsetX - ( this.mask_width / 2 );
        let y = e.offsetY - ( this.mask_height / 2 );

        // 边界定位
        if(x <= 0){x = 0};
        if(y <= 0){y = 0};
        if(x >= (this.show_width - this.mask_width))  {x = this.show_width - this.mask_width};
        if(y >= (this.show_height - this.mask_height)) {y = this.show_height - this.mask_height};
        
        // 给mask赋值,设置距离
        this.mask.style.left = x + "px";
        this.mask.style.top = y + "px";
        
        
        // 背景图移动
        const moveX = this.enlarge_width * x / this.mask_width;
        const moveY = this.enlarge_height * y / this.mask_height;
        this.enlarge.style.backgroundPosition = `-${ moveX }px -${ moveY }px`;
    });
}

/**
 * 绑定点击事件
 */
Enlarge.prototype.bindEvent = function(){

    
    this.list.addEventListener("click",e => {
        e = e || window.event;
        const target = e.target || window.srcElement;
        if(target.nodeName === 'IMG'){
            for(let i = 0 ; i < this.ulcontent.children.length; i ++){
                this.ulcontent.children[i].classList.remove("active");
            }
            target.parentElement.classList.add("active");
            
            let normalPicPath = target.getAttribute("data-show");
            let bigPicPath = target.getAttribute("jqimg");
            console.log(normalPicPath)
            console.log(bigPicPath)
            
            // 设置图片
            this.show.firstElementChild.src = normalPicPath;
            this.enlarge.style.backgroundImage =  "url("+bigPicPath+")";
        }
    });
}



Enlarge.prototype.init = function(){
    this.overOut();
    this.setScaleBg();
    this.move();
    this.bindEvent();
}

图片资源和源码地址:https://gitee.com/xieh-gitee/EnlargeProject

效果:

原文地址:https://www.cnblogs.com/xiejn/p/14026310.html