您的当前位置:首页正文

JavaScript实现淘宝放大镜的两种方法介绍(代码示例)

2020-11-27 来源:榕意旅游网

本篇文章给大家带来的内容是关于JavaScript实现淘宝放大镜的两种方法介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

啥是淘宝放大镜

781221957-5c70fec7e9e7b_articlex.png

这个,当你的鼠标移动到左边的主图上时,右边会出现一个放大的图,暂且就把这个叫做放大镜吧。

大概的做法

  • 第一种,左边一个小图,右边一个原图,当鼠标在小图上移动的时候,通过更改left和top的值来实现同步移动(原图的position属性设置为absolute)

  • 第二种,鼠标在小图上移动的时候,通过改变原图的background-position的值来同步移动。

  • 关键操作

  • 第一步,获取鼠标在小图上的位置,并且定位好跟随鼠标的方块(你应该知道是哪个方块吧。)的位置。

  • //e.offsetX ,offsetY是鼠标的位置
    //方块的left top在你的鼠标的左上方(网页左上角是原点),因此是减去一个方块的一半。
     var x = e.offsetX - 方块.offsetWidth / 2;
     var y = e.offsetY - 方块.offsetHeight / 2;
     方块.style.left = x + 'px';
     方块.style.top = y + 'px';

    这明显是不足够的!

    还需要考虑极端位置/情况
    如果只用上面的设置,那么当你的鼠标移动到图片边缘的时候,方块有一半会出现在图片外。

    2667449965-5c71041b0590f_articlex.png

    正确的应该是 当你的方块触碰到边缘的时候,你的方块就不能在移动了,尽管你的鼠标还在往下图中“鼠标的有效活动区域”外移动。

    1281913955-5c7102c9ee329_articlex.png

    那么得加点代码

     if (x < 0) {
     x = 0;
     }
     if (y < 0) {
     y = 0;
     }
     if (x > 小图.offsetWidth - 方块.offsetWidth) {
     x = 小图.offsetWidth - 方块.offsetWidth;
     }
     if (y > 小图.offsetHeight - 方块.offsetHeight) {
     y = 小图.offsetHeight - 方块.offsetHeight;
     }
  • 第二步,控制大图里的left - top或者background-position

  •  //第一种方法:需要注意的是这里的left 和 top得反过来,你鼠标在小图上往下移的时候,对应的大图其实是往上移的。
     //所以:大图上的left = -小图上的left * 他们的缩放倍率
     大图.style.display = "block";
     大图.style.left = -x * 大图.offsetWidth / 小图.offsetWidth + 'px';
     大图.style.top = -y * 大图.offsetHeight / 小图.offsetHeight + 'px';
     
     //第二种方法,这里需要注意 backgroundPosition的值是从0 - 100%的(得用百分比表示);
     //需要注意的是何时为百分百,从上面的极端情况判定我们可以知道
     //x 是从0 到 mask.offsetWidth - rect.offsetWidth;
     //因此这就是0 - 100%;y同理
     大图.style.display = "block";
     大图.style.backgroundPosition =`${x/(mask.offsetWidth - rect.offsetWidth)*100}% ${y/(mask.offsetHeight- rect.offsetHeight)*100}%`;

    注意事项

  • 我们上面说在小图img上绑定mousemove事件来定位方块,其实实际操作上,我们不能直接用img来绑定,而是得用一个和img一样大小遮罩层来绑定,不然在你鼠标移动的时候,图片会疯狂闪烁,疯狂!crazy!

  • 还有 就是函数节流,这个想节流就节流吧。

  • 还有个很重要的,就是右边那个显示大图的p的大小,一定得是小图上的方块大小 * 缩放倍率 的大小,如果过大,则会多出空白,过小,显示不完全。下面有代码,你可以带回家疯狂测试。

  • 再详细一点

    我知道我可能说的不是很详细,所以。

    <!DOCTYPE html>
    <html>
    
    <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>tb放大镜</title>
     <style>
     .small-box {
     position: relative;
     height: 300px;
     }
    
     .small-pic {
     width: auto;
     height: 300px;
     }
    
     .mask {
     width: 526px;
     position: absolute;
     top: 0;
     left: 0;
     z-index: 1;
     height: 100%;
     cursor: crosshair;
     }
    
     .rect {
     position: absolute;
     top: 0;
     left: 0;
     width: 100px;
     height: 100px;
     opacity: .5;
     background-color: red;
     z-index: 0;
     }
    
     .big-box {
     display: inline-block;
     position: relative;
     width: 266px;
     height:266px;
     border: 1px solid red;
     overflow: hidden;
     }
     .big-pic {
     position: absolute;
     width: 1400px;
     height: 798px;
     top: 0;
     left: 0;
     }
     .big-pic2{
     display: inline-block;
     width: 266px;
     height:266px;
     background-size: auto 798px;
     background-image: url("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1550846791000&di=15edaf7bce643e13b65f70c82d74de30&imgtype=0&src=http%3A%2F%2Fpic.92to.com%2F360%2F201604%2F08%2F19864861_13.jpg");
     background-position: 0 0;
    }
     </style>
    </head>
    
    <body>
     <div>
     <img
     src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1550846791000&di=15edaf7bce643e13b65f70c82d74de30&imgtype=0&src=http%3A%2F%2Fpic.92to.com%2F360%2F201604%2F08%2F19864861_13.jpg"
     alt="">
     <div></div>
     <div style="display: none"></div>
     </div>
     <div>
     <img 
     style="display: none"
     src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1550846791000&di=15edaf7bce643e13b65f70c82d74de30&imgtype=0&src=http%3A%2F%2Fpic.92to.com%2F360%2F201604%2F08%2F19864861_13.jpg"
     alt="">
     </div>
     <div>
     <div></div>
     </div>
    </body>
    <script>
     
     window.onload = function () {
     var mask = document.getElementsByClassName('mask')[0];
     //为什么要用mask呢?不直接用选中small-pic。
     //如果直接选择图片标签来绑定下面的mouseover事件,图片会一直闪烁!所以我们得给他一个和图片一样大小的遮罩层
     var rect = document.getElementsByClassName('rect')[0];
     var bPic = document.getElementsByClassName("big-pic")[0];
     var bPic2 = document.getElementsByClassName("big-pic2")[0];
     mask.addEventListener('mousemove', throttle(magnifier,100))
     function magnifier(e){
    
     //方块的left top在你的鼠标的左上方(网页左上角是原点),因此是减去一个方块的一半。
     var x = e.offsetX - rect.offsetWidth / 2;
     var y = e.offsetY - rect.offsetHeight / 2;
     //极端情况,也就是当你的鼠标上的方块到四个边的边缘的时候。
     if (x < 0) {
     x = 0;
     }
     if (y < 0) {
     y = 0;
     }
     if (x > mask.offsetWidth - rect.offsetWidth) {
     x = mask.offsetWidth - rect.offsetWidth;
     }
     if (y > mask.offsetHeight - rect.offsetHeight) {
     y = mask.offsetHeight - rect.offsetHeight;
     }
    
     //方块定位
     rect.style.display="block";
     rect.style.left = x + 'px';
     rect.style.top = y + 'px';
    
     //第一种方法:需要注意的是这里的left 和 top得反过来,你鼠标在小图上往下移的时候,对应的大图其实是往上移的。
     //所以:大图上的left = -小图上的left * 他们的缩放倍率
     bPic.style.display = "block";
     bPic.style.left = -x * bPic.offsetWidth / mask.offsetWidth + 'px';
     bPic.style.top = -y * bPic.offsetHeight / mask.offsetHeight + 'px';
     
     //第二种方法,这里需要注意 backgroundPosition的值是从0 - 100%的(得用百分比表示);
     //需要注意的是何时为百分百,从上面的极端情况判定我们可以知道
     //x 是从0 到 mask.offsetWidth - rect.offsetWidth;
     //因此这就是0 - 100%;y同理
     bPic2.style.display = "block";
     bPic2.style.backgroundPosition =`${x/(mask.offsetWidth - rect.offsetWidth)*100}% ${y/(mask.offsetHeight- rect.offsetHeight)*100}%`;
    
     }
    
    
     mask.addEventListener('mouseout',function(){
     rect.style.display = "none";
     bPic.style.display = "none";
     bPic2.style.display = "none";
     })
    
    
     //函数节流
     function throttle(fn, delay) {
     var pre = new Date().getTime();
     return function () {
     var context = this;
     var args = arguments;
     var now = new Date().getTime();
     if (now - pre > delay) {
     fn.apply(this,arguments);
     }
     }
     }
    
    
     }
    </script>
    
    </html>
    显示全文