原生JS实现图片放大镜效果 - 干货分享

准备工作

  1. 需要先了解JS的三个鼠标事件

    onmouseenter 鼠标进入

    onmouseleave 鼠标移出

    onmousemove 鼠标移动

    注意:鼠标移入的时候需要阻止事件的冒泡传播(ev.stopPropagation),所以不用onmouseover和onmouseout

  2. 理解盒子模型

    offsetParent:当前盒子的父级参照物

    offsetLeft / offsetTop:当前盒子距离其父级参照物的偏移量

    offsetWidth / offsetHeight:当前元素可视区域的宽高(内容的宽高+padding+border)

    scrollLeft / scrollTop:滚动条卷去的宽度/高度

  3. 区分鼠标事件对象

    ev.clientX / ev.clientY: 当前鼠标触发点距离当前窗口左上角的X/Y轴坐标

    ev.pageX / ev.pageY:当前鼠标触发点距离body(第一屏幕)左上角的X/Y轴坐标

    注意:低版本浏览器事件对象中不存在pageX/pageY

    ev.pageX = ev.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
    ev.pageY = ev.clientY + (document.documentElement.scrollTop || document.body.scrollTop)
    复制代码
  4. 如果图片是在某些盒子里,并且盒子距离左上角的距离根据浏览器窗口的大小改变,那么计算偏移量的时候就不能用ev.clientX/ev.clientY,而是需要用ev.pageX/ev.pageY

思路

  1. 布局
"smallBox" class="smallBox"> "smallImg.jpg"/>
"mask" id="mask">
"big" id="bigBox"> "bigImg" src="bigImg.jpg" alt=""/>
复制代码
  1. 样式
.small{width:400px;height:400px}
.small img{width:100%;height:100%}
.small .mask{width: 200px; height: 200px; background: rgba(255, 255, 0, 0.4); position: absolute; left: 0; top: 0; display: none; cursor: move; }
.big{ width: 480px; height: 480px; border: 1px solid #999; position: absolute; top: 0; left: 400px; overflow: hidden; z-index:999; display: none;}
.big img{width:800px; height: 800px;}
复制代码
  1. JS逻辑

    3.1 页面加载完成后触发

    window.onload = function(){}
    复制代码

    3.2 获取操作的元素

    let small = document.getElementById("smallBox"),
        big = document.getElementById("bigBox"),
        bigImg = document.getElementById("bigImg"),
        mask = document.getElementById("mask");
    复制代码

    3.3 计算小图距离body的偏移量

    let smallLeft = small.offsetLeft,//小图距body的左偏移量
        smallTop = small.offsetTop,//小图距body的上偏移量
        smallBox = small;//临时值,用于计算小图距body的偏移量
    
    //计算小图距body的偏移量
    while(smallBox.offsetParent.nodeName !== 'BODY'){
        smallBox = smallBox.offsetParent;
        smallLeft += smallBox.offsetLeft;
        smallTop += smallBox.offsetTop;
    }
    复制代码

    3.4 设置鼠标移入/移出小图时,大图和遮罩层的隐藏和显示

    small.onmouseenter = function(){
        big.style.display = "block";
        mask.style.display = "block";
    };
    small.onmouseleave = function(){
        big.style.display = "none";
        mask.style.display = "none";
    };
    复制代码

    3.5 遮罩层随着鼠标移动

    small.onmousemove = function(event){
        event = event || window.event;
    
        //兼容低版本浏览器 - 低版本浏览器中不存在pageX和pageY
        event.pageX = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
        event.pageY = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
    
        var x = event.pageX - smallLeft - mask.offsetWidth/2;
        var y = event.pageY - smallTop - mask.offsetHeight/2;
        
        mask.style.top = y + "px";
        mask.style.left = x + "px";
    }
    复制代码

    3.6 鼠标移动时不超出小图时拉回

    //水平方向的最大值
    var maxX = small.clientWidth-mask.clientWidth;
    //竖直方向的最大值
    var maxY = small.clientHeight-mask.clientHeight;
    
    //超出左侧时,拉回
    if(x<0) x=0;
    
    //超出右侧时,拉回
    if(x>maxX) x=maxX;
    
    //顶部超出
    if(y<0) y=0;
    
    //底部超出
    if(y>maxY) y=maxY;
    复制代码

    3.7 大图根据比例显示

    //比例 = 大图移动的距离/mask移动的距离 = 大图/小图
    var scale = bigImg.offsetWidth / small.offsetWidth;
    bigImg.style.marginLeft = -scale * x +"px";
    bigImg.style.marginTop = -scale * y +"px";
    复制代码

主要代码

//-------------------- HTML start --------------------
"smallBox" class="smallBox"> "smallImg.jpg"/>
"mask" id="mask">
"big" id="bigBox"> "bigImg" src="bigImg.jpg" alt=""/>
//--------------------- HTML end --------------------- //--------------------- CSS start -------------------- .small{width:400px;height:400px} .small img{width:100%;height:100%} .small .mask{width: 200px; height: 200px; background: rgba(255, 255, 0, 0.4); position: absolute; left: 0; top: 0; display: none; cursor: move; } .big{ width: 480px; height: 480px; border: 1px solid #999; position: absolute; top: 0; left: 400px; overflow: hidden; z-index:999; display: none;} .big img{width:800px; height: 800px;} //--------------------- CSS end --------------------- //--------------------- JS start -------------------- window.onload = function(){ var small = document.getElementById("smallImg"), big = document.getElementById("bigBox"), bigImg = document.getElementById("bigImg"), mask = document.getElementById("imgMask"), smallLeft = small.offsetLeft,//小图距body的左偏移量 smallTop = small.offsetTop,//小图距body的上偏移量 smallBox = small;//临时值,用于计算小图距body的偏移量 //计算小图距body的偏移量 while(smallBox.offsetParent.nodeName !== 'BODY'){ smallBox = smallBox.offsetParent; smallLeft += smallBox.offsetLeft; smallTop += smallBox.offsetTop; } //big和mask在鼠标移入small时显示,移出时隐藏 small.onmouseenter = function(){ big.style.display = "block"; mask.style.display = "block"; }; small.onmouseleave = function(){ big.style.display = "none"; mask.style.display = "none"; }; small.onmousemove = function(event){ event = event || window.event; //兼容低版本浏览器 - 低版本浏览器中不存在pageX和pageY event.pageX = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft); event.pageY = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop); var x = event.pageX - smallLeft - mask.offsetWidth/2; var y = event.pageY - smallTop - mask.offsetHeight/2; //水平方向的最大值 var maxX = small.clientWidth-mask.clientWidth; //竖直方向的最大值 var maxY = small.clientHeight-mask.clientHeight; if(x<0){ //相当于超出左侧,超出左侧时,拉回 x=0; } //超出右侧时拉回 if(x>maxX){ x=maxX; } //顶部超出 if(y<0){ y=0; } //底部超出 if(y>maxY){ y=maxY; } mask.style.top = y + "px"; mask.style.left = x + "px"; //比例 = 大图移动的距离/mask移动的距离 = 大图/小图 var scale = bigImg.offsetWidth / small.offsetWidth; bigImg.style.marginLeft = -scale * x +"px"; bigImg.style.marginTop = -scale * y +"px"; } }; //--------------------- JS end ---------------------- 复制代码

你可能感兴趣的:(原生JS实现图片放大镜效果 - 干货分享)