前端优化之商品图片放大镜

优化原因

现在的电商商城项目解决的主要是购买商品的问题,那么购买商品主要要看清楚商品表面外形的主要特征和细节,如果图片处理过小,或者细节过于模糊,就需要做一个商品高清图片放大局部的功能。

技术关键点

  1. 左侧和上侧距离,在一个水平位置和垂直位置中有我们可以挪动的区域,就是原图片区域,鼠标挪动位置是一个块状位置,他的左侧和上侧距离浏览器上侧和左侧分别有一个长度,我们叫它们 ClientX 和 ClientY,而左上侧鼠标没有略过的位置实际上是一个点,我们拖动放大块时,它会由一个点变成一个方块,这个放大镜左上边的点所控制的这一点距离屏幕上侧和左侧的 ClientY 和 ClientX 会随着鼠标的移动而变大变小,那么要计算放大块左侧距离原点和上侧原点就要减去原图距离屏幕的上边高度和左边高度。在一个水平位置和垂直位置中有我们可以挪动的区域,就是原图片区域,鼠标挪动位置是一个块状位置,他的左侧和上侧距离浏览器上侧和左侧分别有一个长度,我们叫它们 ClientX 和 ClientY,而左上侧鼠标没有略过的位置实际上是一个点,我们拖动放大块时,它会由一个点变成一个方块,这个放大镜左上边的点所控制的这一点距离屏幕上侧和左侧的 ClientY 和 ClientX 会随着鼠标的移动而变大变小,那么要计算放大块左侧距离原点和上侧原点就要减去原图距离屏幕的上边高度和左边高度。

计算方式
x = 事件对象.clientX - 外侧盒子.offsetLeft;
Y = 事件对象.clientY - 外侧盒子.offsetTop;

在这里插入图片描述

在这里插入图片描述

  1. 解决如何鼠标在黄块内居中的问题,横纵位移分别加上放大黄块一半的长度和宽度。

计算方式
x = 事件对象.clientX - 外侧盒子.offsetLeft - 小黄.offsetWidth/2;
Y = 事件对象.clientY - 外侧盒子.offsetTop - 小黄.offsetHeight/2;
// 事件对象的 offsetX 和 offsetY
// 归属于事件对象
// 作用:关注的鼠标的坐标(鼠标相对于当前元素的坐标)
// 元素的 offsetLeft 和 offsetTop
// 归属于元素
// 作用:关注的元素的坐标(相对于offsetParent的坐标)

在这里插入图片描述
3. 小黄块的最大距离
在这里插入图片描述

  1. 用preventDefault阻止事件冒泡

简易实现代码

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="base.css"/>
</head>
<body>
    <div class="w">
        <div class="fdj">
            <!-- 左侧 -->
            <div class="leftBox" id="_leftBox">
                <!-- 小图 -->
                <img src="img/m.jpg" alt=""/>
                <!-- 小黄盒子 -->
                <div class="tool" id="_tool"></div>
            </div>
            <!-- 右侧 -->
            <div class="rightBox" id="_rightBox">
                <img id="_bImg" src="img/b.jpg" alt=""/>
            </div>
        </div>
    </div>
    <!-- 引入的外部js程序文件 -->
    <script src="index.js"></script>
</body>
</html>
* {
    margin:0;
    padding:0;
}

.w {
    width: 1190px;
    margin: 0 auto;

}
.fdj {
    margin-top: 20px;
}

.fdj .leftBox {
    width: 400px;
    height: 400px;
    border: 1px solid #ccc;
    float: left;
    position: relative;
    overflow: hidden;
}

.fdj .tool {
    width: 250px;
    height: 250px;
    background:gold;
    opacity:.5;
    filter:alpha(opacity=50);
    position: absolute;
    top:0;
    left: 0;
    cursor: move;
    /* 默认隐藏 */
    display: none;

}
/* 给小黄加上active 就会显示 */
.fdj .tool.active {
    display: block;
}

.fdj .rightBox {
    width: 500px;
    height: 500px;
    border:1px solid #ccc;
    float: left;
    overflow: hidden;
    /* 隐藏 */
    display: none;
    position: relative;
}
/* 加上active表示显示 */
.fdj .rightBox.active {
    display: block;
}

.fdj .rightBox img {
    position: absolute;
}
//【准备:获取要操作的元素】
var _leftBox = document.querySelector('#_leftBox');  // 左侧盒子
var _tool = document.querySelector('#_tool');  // 小黄盒子
var _rightBox = document.querySelector('#_rightBox');  // 右侧盒子
var _bImg = document.querySelector('#_bImg');  // 右侧盒子中的大图片


//【功能1:鼠标进入/离开左侧盒子显示/隐藏小黄和右侧盒子】
// 1. 给_leftBox注册鼠标进入事件 onmouseenter
_leftBox.onmouseenter = function () {
    // 1.1 显示小黄盒子,给小黄盒子添加类名 active
    _tool.className = 'tool active';
    // 1.2 显示右侧盒子,给右侧盒子添加类名 active 
    _rightBox.className = 'rightBox active';

}

// 2. 给_leftBox注册鼠标离开事件 onmouseleave
_leftBox.onmouseleave = function () {
    //  2.1 显示小黄盒子,给小黄盒子去除类名 active
    _tool.className = 'tool';
    //  2.2 显示右侧盒子,给右侧盒子去除类名 active
    _rightBox.className = 'rightBox';
}

//【功能2:鼠标在左侧区域移动时,控制小黄和右侧盒子中图片的位置】
// 1. 给左侧盒子注册鼠标移动事件 onmosuemove
_leftBox.onmousemove = function (e) {
    // 2. 通过事件对象获取鼠标相对元素的位置(x,y)
    var x = e.clientX - _leftBox.offsetLeft- _tool.offsetWidth/2;
    var y = e.clientY - _leftBox.offsetTop - _tool.offsetHeight/2;

    // 这里给x和y赋值时,不要用事件对象的offsetX和offsetY。
    // 原因:因为【事件冒泡】,鼠标在移动时,有时会移动到小黄盒子上。若移动到小黄盒子上时,获取的值不是相对于左侧盒子元素,而是相对小黄盒子元素。所以当鼠标进入或离开小黄时,获取的坐标值时大时小,导致小黄盒子上下左右波动。
    // 解决方案:在小黄移动事件中,停止冒泡。但是鼠标在移动时,就没有效果了。
    // 最终解决方案:放弃使用事件对象offsetX/Y。 选择事件对象的clienX/Y 结合左侧盒子的位置计算出正确的位置。

    // 2.1 对x和y限制
    if (x < 0) {
        x = 0;
    }
    if (y < 0) {
        y = 0;
    }
    if (x > _leftBox.offsetWidth - _tool.offsetWidth) {
        x = _leftBox.offsetWidth - _tool.offsetWidth;
    }
    if (y > _leftBox.offsetHeight - _tool.offsetHeight) {
        y = _leftBox.offsetHeight - _tool.offsetHeight;
    }

    // 3. 把计算好的位置 赋值给小黄 
    _tool.style.left = x + 'px';
    _tool.style.top = y + 'px';

    // 4. 设定右侧大图片的位置(设置的方向是相反的,比例关系是1:2)
    _bImg.style.left = -2 * x + 'px';
    _bImg.style.top = -2 * y + 'px';
}

猜你喜欢

转载自blog.csdn.net/github_27314097/article/details/82929812