放大镜效果实现

放大镜效果
Utils.js文档内容
export default class Utils{
    static ce(type,style){
        let elem=document.createElement(type);
        Object.assign(elem.style,style);
        return elem;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module">
    // 引入js文件
    import Utils from "./js/Utils.js";

    // 数据驱动显示
    var max,min,mask,imgCon,preImg;
    var x=0,y=0;
    const MIN_WIDTH=450;
    const MAX_WIDTH=540;
    const MASK_WIDTH=303.75;
    const IMAGE_MARGIN=9;
    const IMAGE_WIDTH=58;
    var bnList=[];
    var iconList=["./img/a_icon.jpg","./img/b_icon.jpg","./img/c_icon.jpg","./img/d_icon.jpg","./img/e_icon.jpg","./img/f_icon.jpg","./img/g_icon.jpg","./img/h_icon.jpg","./img/i_icon.jpg","./img/j_icon.jpg"];
    /*
        1、创建div父容器
        2、父容器内创建一个小容器,一个大容器
        3、小容器中有两个容器,一个是图片展示,另一个是将这个容器使用鼠标拖拽效果
        4、大容器让对应的图片放大显示
        5、创建一个容器用于存放每个小图片的展示
        5、将创建好的元素添加到body中
    */
    init();
    function init(){
        var zoom=Utils.ce("div",{
            position:'absolute',
            left:"100px",
            top:"100px"
        });
        createMin(zoom);
        createMax(zoom);
        createCarousel(zoom);
        document.body.appendChild(zoom);
    }

    /*
        创建小容器
        1、为创建好的容器设置内联样式
        2、创建一个需要拖拽的容器样式
        3、将创建好的容器添加父容器中
        4、为容器添加鼠标滑过事件,执行mouseHandler函数

    */
    function createMin(parent){
        min=Utils.ce("div",{
            position:"absolute",
            width:MIN_WIDTH+"px",
            height:MIN_WIDTH+"px",
            backgroundImage:"url(./img/a.jpg)",
            backgroundSize:"100% 100%",
            border:"1px solid #CCCCCC"
        });
        mask=Utils.ce("div",{
            position:"absolute",
            width:MASK_WIDTH+"px",
            height:MASK_WIDTH+"px",
            display:"none",
            backgroundColor:"rgba(180,160,0,0.3)"
        })
        min.appendChild(mask);
        parent.appendChild(min);
        min.addEventListener("mouseenter",mouseHandler);
    }

    /*
        创建大容器,用于大图展示
        1、设置内联样式
        2、将大容器添加到父容器中
    */
    function createMax(parent){
        max=Utils.ce("div",{
            position:"absolute",
            width:MAX_WIDTH+"px",
            height:MAX_WIDTH+"px",
            backgroundImage:"url(./img/a.jpg)",
            border:"1px solid #CCCCCC",
            display:"none",
            left:MIN_WIDTH+1+"px"
        });
        parent.appendChild(max);
    }

    /*
        创建容器,容器里面有三个子容器
        1、左边容器,设置宽体等样式,添加左箭头背景图
        2、右边容器,设置宽体等样式,添加右箭头背景图
        3、中间容器,添加每张小图
        4、添加点击事件
    */
    function createCarousel(parent){
        var div=Utils.ce("div",{
            position:"absolute",
            width:MIN_WIDTH+2+"px",
            height:"58px",
            top:MIN_WIDTH+2+"px"
        })
        var left=Utils.ce("div",{
            width:"22px",
            height:"32px",
            top:"13px",
            backgroundImage:"url(./img/sprite.png)",
            backgroundPositionX:"0px",
            backgroundPositionY:"-54px",
            position:"absolute",
        });
        // 将左边容器的样式复制给左边一份
        var right=left.cloneNode(false);
        // 再给左边的容器添加left 0 防止复制时,将属性和值复制后无法更改
        left.style.left="0px";
        // 设置右边容器属性样式
        Object.assign(right.style,{
            right:"0px",
            backgroundPositionX:"-78px",
            backgroundPositionY:"0px",
        })
        // 分别将左右容器添加在定义的数组中,方便后面调用
        bnList.push(left);
        bnList.push(right);
        // 分别将左右容器添加到父容器中
        div.appendChild(left);
        div.appendChild(right);

        var con=Utils.ce("div",{
            position:"absolute",
            width:"380px",
            height:"58px",
            left:"36px",
            overflow:"hidden",
        })
        // 将创建好的容器添加到父元素diva中
        div.appendChild(con);
        // 调用创建图片容器这个函数,将创建con作为参数带入进去
        createImageCon(con);
        // 添加到父容器中
        parent.appendChild(div);
        // 创建点击事件
        div.addEventListener("click",clickHandler);
    }

    /*
        创建图片容器
        1、获取每张图片的宽度
        2、设置每张图的内联样式,添加图片路径地址
        3、添加鼠标滑过事件
    */
    function createImageCon(parent){
        // iconList.length几张图*每个图片的大小+图片数组-1*每个图片的左右margin值
        // 整个容器的宽度
        var width=iconList.length*IMAGE_WIDTH+(iconList.length-1)*IMAGE_MARGIN*2;
        imgCon=Utils.ce("div",{
            position:"absolute",
            width:width+"px",
            height:"58px",
            left:0,
            transition: "all 0.5s"
        });
        // 循环遍历,设置每个图片的内联样式
        for(var i=0;i<iconList.length;i++){
            var img=Utils.ce("img",{
                // 宽度-4,因为有一个boder值
                width:IMAGE_WIDTH-4+"px",
                height:IMAGE_WIDTH-4+"px",
                // 设置边框样式
                // 通过判断如果i===0设置颜色透明或者显示
                border:`2px solid rgba(255,0,0,${i==0 ? 1 : 0})`,
                // 如果i===0设置第一个图片左边的margin值为0,
                marginLeft:`${i===0 ? '0px' : IMAGE_MARGIN+"px"}`,
                marginRight:IMAGE_MARGIN+"px",
            });
            // 为每个img设置图片路径地址
            img.src=iconList[i];
            // 将img赋给定义的变量preImg
            if(i===0) preImg=img;
            imgCon.appendChild(img);
        }
        // 图片容器添加鼠标滑过事件
        imgCon.addEventListener("mouseover",iconMouseHandler);
        parent.appendChild(imgCon);
    }

    function iconMouseHandler(e){
        // 如果鼠标滑过的对象的节点名不是img,直接跳出不再向后继续执行
        if(e.target.nodeName!=="IMG") return;
        if(preImg){
            // 当鼠标滑过时,
            preImg.style.border="2px solid rgba(255,0,0,0)";
        }
        // 将滑过目标对象赋给变量preImg,滑过谁就显示边框样式
        preImg=e.target;
        preImg.style.border="2px solid rgba(255,0,0,1)";
        // 改变大容器和小容器的背景图,和滑过的图片相对应
        min.style.backgroundImage=max.style.backgroundImage=`url(${e.target.src.replace(/_icon/,"")})`;
    }

    // 小容器鼠标滑过侦听事件函数
    function mouseHandler(e){
        // 当事件类型是mouseenter(鼠标进入时) 为min增添鼠标移动时和离开侦听事件
        if(e.type==="mouseenter"){
            mask.style.display=max.style.display="block"
            min.addEventListener("mouseleave",mouseHandler);
            min.addEventListener("mousemove",mouseHandler);
        // 当事件类型是鼠标移动时,执行move函数
        // 同时带入参数,元素位置相对可视窗口左上角位置
        // mousemove是有冒泡效果
        }else if(e.type==="mousemove"){
            move(e.clientX,e.clientY);
        // 当事件类型是mouseleave(鼠标离开是) 删除鼠标移动时和离开时这两个侦听事件
        }else if(e.type==="mouseleave"){
            // 同时设置mask的样式设置为隐藏
            mask.style.display=max.style.display="none"
            min.removeEventListener("mouseleave",mouseHandler);
            min.removeEventListener("mousemove",mouseHandler);
        }
    }

    // 鼠标移动坐标函数
    function move(mouseX,mouseY){
        // 获取min容器的视口距离赋给变量rect
        var rect=min.getBoundingClientRect();
        // 将鼠标的位置设置在容器的中心位置
        // 当前矩形的x轴相对可视窗口的距离
        x=mouseX-MASK_WIDTH/2-rect.x;
        // 当前矩形的y轴相对可视窗口的距离
        y=mouseY-MASK_WIDTH/2-rect.y;
        // 让移动坐标位置,始终是在父容器内进行移动
        if(x<0) x=0;
        if(y<0) y=0;
        // 当x轴大于min容器的宽度-mask容器的宽度,重新设置为min容器的宽度-mask容器的宽度
        if(x>MIN_WIDTH-MASK_WIDTH) x=MIN_WIDTH-MASK_WIDTH;
        // 当y轴大于min容器的高度-mask容器的高度,重新设置为min容器的高度-mask容器的高度
        if(y>MIN_WIDTH-MASK_WIDTH) y=MIN_WIDTH-MASK_WIDTH;
        // 根据x的值去改变mask容器的定位位置
        mask.style.left=x+"px";
        mask.style.top=y+"px";
        // max容器的移动方向和mask的移动方向相反
        // 大图的宽度除小图的宽度,等到一个宽高比,让其移动的大小相等
        max.style.backgroundPositionX=-x*(MAX_WIDTH/MASK_WIDTH)+"px";
        max.style.backgroundPositionY=-y*(MAX_WIDTH/MASK_WIDTH)+"px";
    }

    // 图片容器点击事件
    function clickHandler(e){
        // 查找点击元素bnList数组中的下标赋给index
        var index=bnList.indexOf(e.target);
        // 如果为0,不动
        if(index===0){
            imgCon.style.left="0px";
        }else{
            // 否则容器向左进行偏移
            imgCon.style.left="-295px";
        }
    }
</script>
</body>
</html>
实现效果展示

放大镜效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值