js 实现的页面图片放大器以及 event中的诸多 x

背景:

  淘宝、天猫等电商网站浏览图片时可以查看大图的功能;

 

思路:

  思路很简单,两张图片,一张较小渲染在页面上,一张较大是细节图,随鼠标事件调整它的 left & top;

需要的知识点:

  • onmouseover
  • onmouseout
  • onmouseenter
  • js event对象中的各类坐标

 

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// index.html
 
<!DOCTYPE html>
<html lang="en">
<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">
    <link rel="stylesheet" href="./css/style.css">
    <title>放大镜</title>
</head>
<body>
    <div id="container">
        <div id="small-box">
            <!-- #mark 防止用户点击并拖动图片加的一个遮罩层 -->
            <div id="mark"></div>
            <div id="float-box"></div>
            <img src="./img/small.jpg" alt="">
        </div>
 
        <div id="big-box">
            <img src="./img/big.jpg" alt="">
        </div>
    </div>
 
    <script src="./js/render.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// style.css
 
* {
    margin: 0;
    padding: 0;
}
 
#container {
    display: block;
    /* 图片宽高 */
    width: 450px;
    height: 450px;
    margin: 50px;
    position: relative;
    border: 1px solid #ccc;
}
 
#small-box {
    position: relative;
    z-index: 1;
}
#float-box {
    display: none;
    width: 200px;
    height: 150px;
    position: absolute;
    background-color: #ffc;
    border: 1px solid #ccc;
    filter: alpha(opacity = 50); /* 兼容 ie 写法*/
    opacity: 0.5;
}
 
#mark {
    position: absolute;
    display: block;
     /* 图片宽高 */
    width: 450px;
    height: 450px;
    background-color: #fff;
    filter: alpha(opacity = 0);
    opacity: 0;
    z-index: 10;
}
 
#big-box {
    display: none;
    position: absolute;
    top: 0;
    left: 460px;
    /* 此处宽高比例同 #float-box */
    width: 480px;
    height: 360px;
    overflow: hidden;
    border: 1px solid #ccc;
    z-index: 1;
}
#big-box img {
    position: absolute;
    z-index: 5;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// render.js
 
window.onload = function() {
    let container = document.querySelector('#container');
    let smallBox = document.querySelector('#small-box');
    let mark = document.querySelector('#mark');
    let floatBox = document.querySelector('#float-box');
    let bigBox = document.querySelector('#big-box');
    let bigBoxImage = document.querySelectorAll('img')[1];
 
    mark.onmouseover = function() {
        floatBox.style.display = 'block';
        bigBox.style.display = 'block';
    }
 
    mark.onmouseout = function() {
        floatBox.style.display = 'none';
        bigBox.style.display = 'none';
    }
 
    mark.onmousemove = function(e) {
        let _event = e || window.event;  // 兼容性
        // console.log(_event);
        // console.log(_event.clientX,container.offsetLeft, smallBox.offsetLeft, floatBox.offsetWidth)
        let left = _event.clientX - container.offsetLeft - smallBox.offsetLeft - floatBox.offsetWidth / 2;
        let top = _event.clientY - container.offsetTop - smallBox.offsetTop - floatBox.offsetHeight / 2;
 
        // 处理边界
        if (left < 0) {
            left = 0;
        } else if (left > (mark.offsetWidth - floatBox.offsetWidth)) {
            left = mark.offsetWidth - floatBox.offsetWidth;
        }
 
        if (top < 0) {
            top = 0;
        } else if (top > (mark.offsetHeight - floatBox.offsetHeight)) {
            top = mark.offsetHeight - floatBox.offsetHeight;
        }
 
        floatBox.style.left = left + 'px';
        floatBox.style.top = top + 'px';
 
        // 求百分比
        let percentX = left / (mark.offsetWidth - floatBox.offsetWidth);
        let percentY = top / (mark.offsetHeight - floatBox.offsetHeight);
 
        //方向相反,小图片鼠标移动方向与大图片相反,故而是负值
        bigBoxImage.style.left = - percentX * (bigBoxImage.offsetWidth - bigBox.offsetWidth) + "px";
        bigBoxImage.style.top = - percentY * (bigBoxImage.offsetHeight - bigBox.offsetHeight) + "px";
    }
}

 

 

event 中的各类坐标:

 

需要注意:

offsetLeft 获取的是相对于父对象的左边距;left 获取或设置相对于 具有定位属性(position定义为relative)的父对象 的左边距;

  • offsetLeft返回的数值,而style.left则返回的是字符串;
  • offsetLeft是只读的,style.left可读写的;
  • style.left的值需要事先定义,否则取到的值为空,而且必须要定义在html里,如果写在样式里面,是取不出它的值的;

这是这个代码的要点之一,另外一个就是去要计算其比例。根据对应比例,进行代码的显示。

另外,小图片和大图片的显示,移动方向是相反的,所以比例前面会乘以一个负号。这个需要注意。

 

posted @   shiweiqianju  阅读(346)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示