二、放大镜简单实现

JavaScriptJqueryExampleHtml2canvas

# 第一步 获取元素

因为这里面的元素都有可能用到

// 获取最外面的div
var box = document.getElementById("box");
// 获取显示小图的div
var small = box.children[0];
// 获取小图中的遮挡的div
var mask = small.children[1];
// 获取显示大图的div
var big = box.children[1];
// 获取大div中的大图
var imgObj = big.children[0];
1
2
3
4
5
6
7
8
9
10

# 第二步 注册鼠标进入离开事件

在鼠标进入的时候,显示遮挡层和大图的图层

在鼠标离开的时候,隐藏遮挡层和大图的图层

// 鼠标进入事件
box.onmouseover = function(){
   mask.style.display = "block";
   big.style.display = "block";
}
// 鼠标离开事件
box.onmouseout = function(){
   mask.style.display = "none";
   big.style.display = "none";
}
1
2
3
4
5
6
7
8
9
10

# 第三步 注册鼠标移动事件(确定遮罩层的定位)

给鼠标注册移动事件,在小图上移动的时候,遮罩层也跟着移动

  • 要拿到可视区域的横纵坐标——clientXclientY(不考虑兼容性)
  • 设置遮罩层的lefttop

那么怎么通过鼠标的横纵坐标来设置遮罩层的lefttop的值呢? 一张图来说明白:

mask.png

上图中的第三步,分析为什么会出现这样的问题

因为在鼠标进入的时候,在鼠标和小图的框中加了一个遮罩层,这个遮罩层让鼠标和小图的框进行了分离。所以当鼠标进行移动的时候,移动到了小图的框的外面,但是检测不到鼠标到底有没有离开小图的范围,所以遮罩层就跟着鼠标一起可以在可视区域中进行移动。

要想要进行范围的限定,就类似于一辆车在两堵墙之间的移动的最大距离一样。最大的移动距离无非就是小图框本身的宽度 - 遮罩层本身的宽度

下面上代码:

small.onmousemove = function (e) {
  var left = e.clientX - mask.offsetWidth / 2;//横坐标
  var top = e.clientY - mask.offsetHeight / 2;//纵坐标
  //设置遮挡层的left和top
  var x = left - 100;//margin
  var y = top - 100;//margin

  //为遮挡层设置范围
  x=x<0?0:x;//如果横坐标小于0就设置为0
  y=y<0?0:y;//如果纵坐标小于0就设置为0

  //如果横坐标大于横向最大移动距离就设置为横向最大移动距离
  x=x>small.offsetWidth-mask.offsetWidth?small.offsetWidth-mask.offsetWidth:x;
  //如果纵坐标大于纵向最大移动距离就设置为纵向最大移动距离
  y=y>small.offsetHeight-mask.offsetHeight?small.offsetHeight-mask.offsetHeight:y;

  //设置mask的定位
  mask.style.left = x + "px";
  mask.style.top = y + "px";
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 最后一步 大图跟着鼠标移动

  • 如果图片是有比例的,那么移动的时候也成比例就可以
  • 如果图片是不成比例的,那么就要有一个普遍的算法

先来个原理图:

max.png

上图说的是宽度,其实高度可以以此类推。

由此可以得出:

**大图的移动距离 = 遮挡层的移动距离 * 大图的最大移动距离 / 遮挡层的最大移动距离 **

//大图的最大的移动距离
var imgMaxMove=imgObj.offsetWidth-big.offsetWidth;
//遮挡层的最大的移动距离
var maskMaxMove=small.offsetWidth-mask.offsetWidth;
//大图的横向移动的距离
var imgMoveLeft=x*imgMaxMove/maskMaxMove;
//大图的纵向移动的距离
var imgMoveTop=y*imgMaxMove/maskMaxMove;

//设置大图的left和top---移动的是margin-left和margin-top

imgObj.style.marginLeft=-imgMoveLeft+"px";
imgObj.style.marginTop=-imgMoveTop+"px";
1
2
3
4
5
6
7
8
9
10
11
12
13

# 整理一下全部的js代码

<script>
  //获取元素
      var box = document.getElementById("box");
      //获取显示小图的div
      var small = box.children[0];
      //获取小图中的遮挡的div
      var mask = small.children[1];
      //获取显示大图的div
      var big = box.children[1];
      //获取大div中的大图
      var imgObj = big.children[0];

  //显示遮挡层和显示大图的的层
  //鼠标进入事件
  box.onmouseover = function () {
      mask.style.display = "block";
      big.style.display = "block";
  };
  //鼠标离开事件
  box.onmouseout = function () {
      mask.style.display = "none";
      big.style.display = "none";
  };

  //为小层注册鼠标移动的事件
  small.onmousemove = function (e) {
      var left = e.clientX - mask.offsetWidth / 2;//横坐标
      var top = e.clientY - mask.offsetHeight / 2;//纵坐标
 //设置遮挡层的left和top
      var x = left - 100;//margin
      var y = top - 100;//margin

      x=x<0?0:x;//如果横坐标小于0就设置为0
      y=y<0?0:y;//如果纵坐标小于0就设置为0
      x=x>small.offsetWidth-mask.offsetWidth?small.offsetWidth-mask.offsetWidth:x;
      y=y>small.offsetHeight-mask.offsetHeight?small.offsetHeight-mask.offsetHeight:y;

 //设置遮挡层的定位值
      mask.style.left = x + "px";
      mask.style.top = y + "px";

 //设置大图的移动距离
      //大图的最大的移动距离
      var imgMaxMove=imgObj.offsetWidth-big.offsetWidth;
      //遮挡层的最大的移动距离
      var maskMaxMove=small.offsetWidth-mask.offsetWidth;
      //大图的横向移动的距离
      var imgMoveLeft=x*imgMaxMove/maskMaxMove;
      //大图的纵向移动的距离
      var imgMoveTop=y*imgMaxMove/maskMaxMove;

      //设置大图的left和top---移动的是margin-left和margin-top

      imgObj.style.marginLeft=-imgMoveLeft+"px";
      imgObj.style.marginTop=-imgMoveTop+"px";
  };
</script>
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
更新时间: 2021-09-15 12:03