仿京东商品放大效果

效果展示:当用户在左侧商品栏移动鼠标时,右侧随之出现产品的放大图,并跟随左侧鼠标移动且放大产品



京东效果

第一步 搭建html结构

主盒子box里面包含左侧img1商品图片、yellow遮罩层,右侧div及右侧img2商品放大图片。

 <h2>仿京东手机放大效果</h2>

    <div id="box">

        <img src="./b3.png"  id="img1">

        <div id="yellow"></div>

        <div id="apt">

            <img src="./big.jpg"  id="img2">

        </div>

    </div>

                                           


第二步 布局CSS样式

主盒子box相对定位,里面的盒子全部绝对定位,黄色遮罩层加opacity显示半透明效果

    <style>

        * {

            margin: 0;

            padding: 0;

        }

        h2 {

            width: 266px;

            height: 66px;

            margin: 0 auto;

        }

        #box {

            position: relative;

            width: 400px;

            height: 400px;

            border: 1px solid #ccc;

            margin: 0 100px;

        }

        #img1 {

            width: 400px;

            height: 400px;

        }

        #yellow {

            position: absolute;

            top: 0;

            left: 0;

            width: 300px;

            height: 300px;

            background-color: #FEDE4F;

            opacity: .5;

            border: 1px solid #ccc;

            cursor: move;

            display: none;

        }

        #apt {

            width: 500px;

            height: 500px;

            position: absolute;

            left: 410px;

            top: 0;

            display: none;

            border: 1px solid #ccc;

            z-index: 999; //如果右侧还有商品详细信息介绍:价格、颜色、版本等等,必须                                      给右侧apt盒子加z-index提高盒子层级,覆盖商品详细信息显示

            overflow: hidden;

        }

        #img2 {

            position: absolute;

            top: 0;

            left: 0;

        }

    <style>


结构样式搭建完成

第三步 JS

1.注册鼠标经过和离开事件,鼠标经过商品时显示黄色遮罩层及右侧商品放大图片,离开隐藏

window.addEventListener('load', function() {

    function $c(a, b) {

        return a.style.display = b

    }

    // 给鼠标注册经过和离开事件

    box.addEventListener('mouseover', function() {

        $c(yellow, 'block')

        $c(apt, 'block')

    })

    box.addEventListener('mouseout', function() {

            $c(yellow, 'none')

            $c(apt, 'none')

        })

}

2. 注册商品栏鼠标移动事件

offset系列属性:

   offsetParent:获取当前元素的定位父元素。

   offsetTop :获取div元素的顶部偏移量

   offsetLeft :获取div元素的左边偏移量

   offsetWidth: 获取div元素的宽度,包含padding+border+内容

   offsetHeight :获取div元素的高度, 包含padding+border+内容

offset系列属性图示

 鼠标事件对象属性:

 pageX:返回鼠标指针的水平坐标,相对于文档页面

 pageY:返回鼠标指针的垂直坐标,相对于文档页面

 clientX:返回鼠标指针的水平坐标,相对于浏览器可视区

 clientY:返回鼠标指针的垂直坐标,相对于浏览器可视区

 screenX:返回鼠标指针的水平坐标,相对于电脑屏幕

 screenY:返回鼠标指针的垂直坐标,相对于电脑屏幕


鼠标事件对象属性

理解这两组属性后我们来分析, 当鼠标在移动时,如何让黄色遮罩层跟随鼠标移动?

首先肯定要得到鼠标在页面中的坐标也就是pageX和pageY,然后再得到盒子在页面中的距离也就是offsetLeft和offsetTop,相减就能得到鼠标在盒子里面的坐标。

鼠标在盒子内的坐标

①鼠标在盒子里面的坐标 x = pageX - 盒子.offsetLeft  , y轴同理

window.addEventListener('load', function() {

    function $c(a, b) {

        return a.style.display = b

    }

    // 给鼠标注册经过和离开事件

    box.addEventListener('mouseover', function() {

        $c(yellow, 'block')

        $c(apt, 'block')

    })

    box.addEventListener('mouseout', function() {

            $c(yellow, 'none')

            $c(apt, 'none')

        })

        //鼠标移动事件

    box.addEventListener('mousemove', function(e) {

        // 2.1计算出鼠标在盒子内的坐标

        let x = e.pageX - this.offsetLeft;

        let y = e.pageY - this.offsetTop;

}

②此时鼠标是在左上角,京东原版是鼠标是在最中央,所以遮罩层要走宽度的一半高度的一半才能到中央,得出遮罩层的移动距离,得到坐标后赋值给遮罩层的left和top

鼠标在左上角

③遮罩层不能超出大盒子,遮罩层的MAX移动距离 = 大盒子.offsetWidth - 遮罩层.offsetWidth; 

遮罩层超出父盒子


遮罩层MAX移动距离

window.addEventListener('load', function() {

    function $c(a, b) {

        return a.style.display = b

    }

    // 给鼠标注册经过和离开事件

    box.addEventListener('mouseover', function() {

        $c(yellow, 'block')

        $c(apt, 'block')

    })

    box.addEventListener('mouseout', function() {

            $c(yellow, 'none')

            $c(apt, 'none')

        })

        //鼠标移动事件

    box.addEventListener('mousemove', function(e) {

        // 2 黄色盒子跟随鼠标移动

        // 2.1计算出鼠标在盒子内的坐标

        let x = e.pageX - this.offsetLeft;

        let y = e.pageY - this.offsetTop;

        // 2.2鼠标居中 防止盒子宽高发生变化写活 遮挡层不能超出父盒子

        let yellowX = x - yellow.offsetWidth / 2;

        let yellowY = y - yellow.offsetHeight / 2;

        // 遮挡层最大移动距离

        let yellowMaxX = box.offsetWidth - yellow.offsetWidth;

        let yellowMaxY = box.offsetHeight - yellow.offsetHeight;

        if (yellowX <= 0) {

            yellowX = 0;

        } else

        if (yellowX >= yellowMaxX) {

            yellowX = yellowMaxX;

        };

        if (yellowY <= 0) {

            yellowY = 0;

        } else if (yellowY >= yellowMaxY) {

            yellowY = yellowMaxY;

        };

        // 赋值

        yellow.style.left = yellowX + 'px';

        yellow.style.top = yellowY + 'px';

}



3.移动黄色遮罩层,右侧大图片随之移动

逻辑:左侧遮罩层移动,右侧大图片跟随移动,因为两边的宽高都不一样,所以移动的距离肯定是不同的,但是移动比例肯定是相同的,我们用此逻辑分析:


比例关系


公式

现在已知遮挡层移动距离x和遮挡层最大移动距离MaxX,大图片最大移动距离用大图片宽度减去大盒子宽度可以得出,那么大图片移动距离=遮挡层移动距离*大图片最大移动距离/遮挡层最大移动距离

我们先求出大图片最大移动距离:


         // 求大图片的最大移动距离

        let aptMaxX = apt.offsetWidth - img2.offsetWidth;

        let aptMaxY = apt.offsetHeight - img2.offsetHeight;

        // 根据公式求大图片的移动距离

        let aptX = yellowX * aptMaxX / yellowMaxX

        let aptY = yellowY * aptMaxY / yellowMaxY

        img2.style.left = aptX + 'px';

        img2.style.top = aptY + 'px';


完成效果:



Video_2021-12-15_172911.wmv

为什么大图片和左边是反向移动?为什么大图片不给最大移动距离?答案在CSS中

总结:案例使用offset搭配事件对象实现了动画效果,JS要实现动画效果,三大系列offset系列、client系列、scroll系列以及事件对象必不可少,所以要多多练习。

END!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容