JavaScript-0831-放大镜

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .middleBox {
            width: 400px;
            height: 400px;
            border: 1px solid #000;
            position: relative;
        }

        .middleBox img {
            width: 400px;
            height: 400px;
        }

        .shade {
            width: 100px;
            height: 100px;
            background: yellow;
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0.5;
            display: none;
        }

        .smallBox {
            margin-top: 10px;

        }

        .smallBox img {
            border: 1px solid #000;
            margin-left: 5px;
            width: 50px;
            height: 50px;
        }

        .smallBox img.active {
            border-color: red;
        }

        .box {
            margin: 50px;
            width: 402px;
            position: relative;
        }

        .bigBox {
            width: 400px;
            height: 400px;
            border: 1px solid #000;
            position: absolute;
            top: 0;
            left: 105%;
            display: none;
            background-image: url(./images/big1.jpg);
            background-position: 0 0;
            background-size: 1600px 1600px;
            background-repeat: no-repeat;
        }

        .shade:hover {
            cursor: move;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="middleBox">
            <img src="./images/big1.jpg" width="400" height="400">
            <div class="shade"></div>
        </div>
        <div class="smallBox">
            <img class="active" src="./images/big1.jpg">
            <img src="./images/big2.jpg" alt="">
        </div>
        <div class="bigBox"></div>
    </div>
</body>

</html>
<script src="common.js"></script>
<script>
    /*
        思路分析
        1、用户点击小图
            a、获取到当前小图的地址 赋值给中图
            b、当前点击的添加特殊样式
            c、大图的背景图片需要修改
        2、用户在中图上移动
            a)绑定鼠标划入事件 设置划入之后显示遮罩与大图
            b)绑定鼠标移动事件 需要根据遮罩距离左侧的距离与中图的宽度计算出百分比,根据百分比设置大图背景的位置
            c)绑定鼠标的划出事件 设置移动事件失效并且将其他的内容隐藏
    */
    // 1、获取常用的dom对象
    const boxDom = document.querySelector('.box');
    const middleBoxDom = document.querySelector('.middleBox');
    const shadeDom = document.querySelector('.shade');
    const smallBoxDom = document.querySelector('.smallBox');
    const bigBoxDom = document.querySelector('.bigBox');
    // 2、实现小图的点击事件
    smallBoxDom.onclick = function (event) {
        if (event.target.tagName == 'IMG') {
            // 1、设置特殊样式
            smallBoxDom.querySelector('.active').className = '';
            event.target.className = 'active'
            // 2、设置中图的图片  middleBoxDom.querySelector('img')表示在middleBoxDom对应的标签下寻找img标签
            middleBoxDom.querySelector('img').src = event.target.src;
            // 3、设置大图的图片
            bigBoxDom.style.backgroundImage = `url(${event.target.src})`
        }
    }
    // 3、处理中图的鼠标划入事件
    middleBoxDom.onmouseover = function () {
        // 显示遮罩
        shadeDom.style.display = 'block';
        // 显示大图
        bigBoxDom.style.display = 'block';
        // 绑定鼠标的移动事件
        middleBoxDom.onmousemove = function (event) {
            // 在获取鼠标坐标点时不能使用offsetX/offsetY,因为移动事件事件源会改变导致坐标点是错误的。所以可以使用clientX/clientY获取到相对于浏览器的坐标点(永远是准确的),减掉box左侧/上侧的距离,就可以得到坐标点相对图片的距离
            let x = event.clientX;
            let y = event.clientY;
            // 遮罩宽度与高度的一半
            let shadeWidthHalf = shadeDom.clientWidth / 2;
            let shadeHeightHalf = shadeDom.clientHeight / 2;
            // 需要限制xy的值 从而限制遮罩只能在中图中
            // 如果鼠标坐标点 位置比 box的左侧距离+遮罩宽度的异步 还要要小 就需要限制在左侧
            if (x < boxDom.offsetLeft + shadeWidthHalf) {
                x = boxDom.offsetLeft + shadeWidthHalf
            }
            if (x > boxDom.offsetLeft + boxDom.clientWidth - shadeWidthHalf) {
                x = boxDom.offsetLeft + boxDom.clientWidth - shadeWidthHalf
            }
            if (y < boxDom.offsetTop + shadeHeightHalf) {
                y = boxDom.offsetTop + shadeHeightHalf
            }
            if (y > boxDom.offsetTop + middleBoxDom.clientHeight - shadeHeightHalf) {
                y = boxDom.offsetTop + middleBoxDom.clientHeight - shadeHeightHalf
            }
            shadeDom.style.left = x - boxDom.offsetLeft - shadeWidthHalf + 'px';
            shadeDom.style.top = y - boxDom.offsetTop - shadeHeightHalf + 'px';
            // 计算出遮罩在中图中的百分比
            // 以遮罩左上角的距离与中图的尺寸计算出百分比
            let xPercentage = (x - boxDom.offsetLeft - shadeWidthHalf) / middleBoxDom.clientWidth;
            let yPercentage = (y - boxDom.offsetTop - shadeHeightHalf) / middleBoxDom.clientHeight;
            // 获取背景图的原始尺寸
            let bigBoxSize = getStyle(bigBoxDom, 'backgroundSize');
            let bigBoxWidth = parseInt(bigBoxSize.split(' ')[0])
            let bigBoxHeight = parseInt(bigBoxSize.split(' ')[1])
            // 计算背景移动的位置
            let xMove = bigBoxWidth * xPercentage;
            let yMove = bigBoxHeight * yPercentage;
            bigBoxDom.style.backgroundPosition = `-${xMove}px -${yMove}px`
        }
    }
    // 4、鼠标离开事件
    middleBoxDom.onmouseout = function () {
        shadeDom.style.display = 'none';
        bigBoxDom.style.display = 'none';
        middleBoxDom.onmousemove = null;
    }
</script>

封装公共函数

/**
 * 生成随机数
 * @param {Number} min 开始数字 
 * @param {Number} max  结束数字
 * @param {Boolean} hasEnd 是否包含结束位置 true包含 否则 不包含
 * @returns {Number}
 */

function makeRandom(min, max, hasEnd) {
    // return Math.floor(Math.random()*(max-min+hasEnd?1:0)+min);
    if (hasEnd) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }
    return Math.floor(Math.random() * (max - min) + min);
}

/**
 * 获取元素的样式
 * @param {Element} elem  需要获取样式元素的DOM对象
 * @param {String} attr 需要获取的样式名称
 */
function getStyle(elem, attr) {
    if (window.getComputedStyle) {
        // 证明 window对象下存在 getComputedStyle属性的(方法) 所以就是满足w3c标准的浏览器
        // 因为attr 是变量  window.getComputedStyle(elem)的到的是对象 所以 需要使用数组语法
        return window.getComputedStyle(elem)[attr];
    }
    // 代码执行到这一行 绝对证明 是IE的低版本
    return elem.currentStyle[attr];
}

/**
 * 批量设置样式
 * @param {Document} elem 元素dom对象 
 * @param {Object} options 对象格式 表示具体设置的样式信息 属性名称是样式名称,属性值是设置的样式值 
 * @returns {String}
 */
function setStyle(elem, options) {
    for (var key in options) {
        elem.style[key] = options[key];
    }
}


/**
 * 绑定事件
 * @param {Document} elem 绑定事件的dom对象 
 * @param {String} eventName 事件名称 是没有on前缀的名称
 * @param {Function} handler 事件处理程序 
 */
function bindEvent(elem,eventName,handler){
    if(window.addEventListener){
        // 判断是w3c浏览器
       return elem.addEventListener(eventName,handler);
    }
    return elem.attachEvent('on'+eventName,handler);
}
/**
 * 解除事件监听的绑定
 * @param {Document} elem 绑定事件的dom对象 
 * @param {String} eventName 事件名称 是没有on前缀的名称
 * @param {Function} handler 事件处理程序 
 */
function unbindEvent(elem,eventName,handler){
    try {
        elem.removeEventListener(eventName,handler);
    } catch (error) {
        elem.detachEvent('on'+eventName,handler);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

goto_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值