逻辑模块(布局)
1.首先对于页面的布局要有一个粗略的思想
<!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>
上方为html整体的静态布局,可结合下面的css样式整体观看分析
* {
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;
}
布局讲解
对于最外部的版心模块w和其中包含的主体模块fdj我想就不用多说了,这是最基础的div+css布局,如果哪位同学不怎么熟悉的话,就去复习一下吧
接下来将左右模块的盒子进行分开讲解:
1.左边盒子:本盒子主要放置随鼠标移动的小黄盒子和小图片,他的宽高随小图片的宽高自行决定,我们可以发现在css样式中给他的display属性是隐藏的(none)而下方又新添加了一个类名active来使display变成了block,可能会不理解,这其实是要结合js来达到显示隐藏的效果的,右侧盒子同样也是用了这种方法,下面讲解js的时候我们再赘述
2.右边盒子:本盒子放置跟左侧盒子小图片相同的大图片,也是随小黄盒子的移动来进行移动,所以要用到定位—–“子绝父相”,小黄盒子也是同样的道理
剩下的一些样式同学们可以通过自己的心情进行添加
逻辑模块(js)
当然要先贴出代码啦
//【准备:获取要操作的元素】
var _leftBox = document.querySelector('#_leftBox'); // 左侧盒子
var _tool = document.querySelector('#_tool'); // 小黄盒子
var _rightBox = document.querySelector('#_rightBox'); // 右侧盒子
//鼠标进入/离开左侧盒子显示/隐藏小黄和右侧盒子
// 给_leftBox注册鼠标进入事件 onmouseenter
_leftBox.onmouseenter = function () {
// 显示小黄盒子,给小黄盒子添加类名 active
_tool.className = 'tool active';
// 显示右侧盒子,给右侧盒子添加类名 active
_rightBox.className = 'rightBox active';
}
//给_leftBox注册鼠标离开事件 onmouseleave
_leftBox.onmouseleave = function () {
// 2.1 显示小黄盒子,给小黄盒子去除类名 active
_tool.className = 'tool';
// 2.2 显示右侧盒子,给右侧盒子去除类名 active
_rightBox.className = 'rightBox';
}
//鼠标在左侧区域移动时,控制小黄和右侧盒子中图片的位置
// 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;
// 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';
}
首先是绑定了鼠标进入和离开事件,可以用addclass和removeclass的方法来控制小黄盒子和右侧盒子的隐藏与显示,这里是使用className来控制类名,方法有很多,自己用的开心顺手就好。
offset的相关
最最重要的东西就是获取鼠标相对元素的位置
// 事件对象的 offsetX 和 offsetY
// 归属于事件对象
// 作用:关注的鼠标的坐标(鼠标相对于当前元素的坐标)
// 元素的 offsetLeft 和 offsetTop
// 归属于元素
// 作用:关注的元素的坐标(相对于offsetParent的坐标)
上方的区别一定要搞清楚
接下来就是具体获取鼠标相对元素的位置了
这时候发现鼠标位置在小黄盒子的左上方,那怎么解决呢?其实很简单,仔细观察会发现,如果让小黄盒子分别向上和向左走他一半的宽度和高度就可以啦。
就可以得到以下计算方式:
var x = e.clientX - _leftBox.offsetLeft - _tool.offsetWidth/2
var y = e.clientY - _leftBox.offsetTop - _tool.offsetHeight/2
这样就可以解决问题啦。
对于一些电商网站的放大镜功能相信大家都有所印象,也不难想到右侧的大图会随着小黄盒子的移动得到相对应的位置,其实仔细想一下,它的原理就是大图移动的方向与小黄盒子移动的方向相反,并且比例关系是2:1,所以将得到的鼠标移动的位置乘上-2就可以使大图随盒子的移动而移动。不要忘了将得到的x y值赋给大图片!
还有最最后一个问题,我们当然要控制小黄盒子不能在浏览器乱跑,所以用判断语句来获取小黄盒子能到达的最大最小值,并判断一下就可以啦。
这样我们来总结一下整个思路:
1.想象要达到的效果并html布局+css样式
2.鼠标进入和离开事件来控制小黄盒子和右侧大图盒子的隐藏与显示
3.获取鼠标相对元素位置的坐标并以比例关系赋给大图(鼠标移动事件)
4.最后控制小黄盒子移动的最大范围就搞定了
将两张图给大家吧,可以尝试一下
整体效果如下: