原生JS实现类似《掘金》网站的图片查看器

经常看掘金网站发现他的图片预览挺不错的,跟以前的 fancyBox 插件效果差不多。在这里我为大家提供一些编写思路。

  • 记录页面的图片所在位置offsetTop / offsetLeft / width /height。
  • 创建div层铺满整屏幕。
  • 如果是加载大图需要显示loading。
  • 创建白色遮罩层。
  • 复制一份图片填充到屏幕之前记录的位置。
  • 根据屏幕算出中心位置并动画移动。
  • 点击关闭,返回到之前记录的位置即可,但是这里需要注意的是如果有滚动条则需要减去srcollTop的值,原因是动态创建的层和图片是position:fixed属性。
  • 滚动条滚动立即隐藏。

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片预览</title>
<style>
*{
    margin:0;
    padding:0;
}
.image{
    width:100px;
}
</style>

</head>
<body>
<div style="margin:auto;width:1000px">
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
<img src="https://user-gold-cdn.xitu.io/2018/5/13/16359c7b4fffa97c?imageslim" class="image"><br>
</div>
</body>
</html>

<script>
let container = document.documentElement||document.body;
let img,div,src;
let x,y,w,h,tx,ty,tw,th,ww,wh;
let closeMove=function(){
    if(div==undefined){
        return false;
    }
    div.style.opacity=0;
    img.style.height=h+"px";
    img.style.width=w+"px";
    img.style.left=x+"px";
    img.style.top=(y - container.scrollTop)+"px";
    // 延迟移除dom
    setTimeout(function(){
        div.remove();
        img.remove();
    },100);
};

let closeFade=function(){
    if(div==undefined){
        return false;
    }
    div.style.opacity=0;
    img.style.opacity=0;
    // 延迟移除dom
    setTimeout(function(){
        div.remove();
        img.remove();
    },100);
};

// 监听滚动关闭层
document.addEventListener("scroll",function(){
    closeFade();
});
document.querySelectorAll("img").forEach(v=>{
    v.addEventListener("click",function(e){ // 注册事件
        // 记录小图的位置个大小
        x=e.target.offsetLeft;
        y=e.target.offsetTop;
        w=e.target.offsetWidth;
        h=e.target.offsetHeight;
        src=e.target.src;

        // 创建遮罩层
        div=document.createElement("div");
        div.style.cssText=`
            position:fixed;
            left:0;
            top:0;
            bottom:0;
            right:0;
            background-color:#fff;
            transition:all .3s cubic-bezier(0.165, 0.84, 0.44, 1);
            opacity:0;
        `;
        document.body.appendChild(div);
        setTimeout(function(){
            div.style.opacity=1;
        },0);
        // (此处可以加loading)

        // 创建副本
        img=new Image();
        img.src=src;
        img.style.cssText=`
            position:fixed;
            left:${x}px;
            top:${y - container.scrollTop}px;
            width:${w}px;
            height:${h}px;
            transition:all .3s cubic-bezier(0.165, 0.84, 0.44, 1);
            opacity:0;
        `;
        img.onload=function(){
            document.body.appendChild(img);
            // 浏览器宽高
            wh=window.innerHeight;
            ww=window.innerWidth;

            // 目标宽高和坐标
            tw=w/h*wh >> 0;
            th=wh;
            tx=(ww - tw) / 2;
            ty=0;
            
            // 延迟写入否则不会有动画
            setTimeout(function(){
                img.style.opacity=1;
                img.style.height=wh+"px";
                img.style.width=tw+"px";
                img.style.left=tx+"px";
                img.style.top=ty+"px";
                // 点击隐藏
                div.onclick=img.onclick=closeMove;
            },0);
        };
    });//end event
});//end forEach
</script>
复制代码

DEMO: jinzhe.github.io/todo/image-…

原文:im.zee.kim/post/79/

转载于:https://juejin.im/post/5afa7c6df265da0b7f44b2ea

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值