总体三个元素的css样式:
- 小图片 (wrap)插入img
- 镜片(box)插入背景图
- 大图片(big)插入背景图
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: none;
position: absolute;
top: 0;
left: 0;
width: 230px;
height: 230px;
/* background-color: #0f0; */
background: url(images/dotpng.png)
}
#wrap {
width: 430px;
height: 430px;
position: absolute;
top: 100px;
left: 100px;
border: 1px solid #000;
}
#big {
display: none;
width: 430px;
height: 430px;
position: absolute;
top: 100px;
left: 550px;
background: url(images/big.jpg);
border: 1px solid #000;
}
</style>
下面为html
<div id="wrap">
<img src="images/small.jpg" >
<div class="box"></div>
</div>
<div id="big">
</div>
下面为script内容
<script>
// 获取小图片
var wrap = document.querySelector("#wrap");
// 镜片
var box = document.querySelector(".box");
// 大图片
var big = document.querySelector("#big");
// 设置鼠标进入图片区域事件
wrap.onmouseenter=function(){
console.log("鼠标进入了");
// 鼠标进去后显示镜片与大图片
box.style.display= "block";
big.style.display = "block";
// 最后看这一步 小图片的clientWidth 减去 镜片的clientWidth 除以 800 减去 大图片的clientWidth 算出比例 (这个800是找的图片是800x800的)
var r = (wrap.clientWidth - box.clientWidth) / (800 - big.clientWidth)
// 设置鼠标在图片区域移动事件(绑定在document上)
document.onmousemove=function(e){
// 获取鼠标在页面(整个页面,包括滚动条下面需要拖动的的页面)的坐标
var mouseX = e.pageX;
var mouseY = e.pageY;
// 获取元素离视口的距离(获取图片距离视口有多少距离,需用到函数)
var elementX = offset(wrap).left;
var elementY = offset(wrap).top;
// 求出镜片元素最终移动值(鼠标进入页面的X/Y坐标 减去 图片到视口上边/下边的距离 减去 镜片元素宽度/高度的一半 减去 图片的上/下边框 )
var zz_X = mouseX - elementX - box.clientWidth/2 - wrap.clientLeft;
var zz_Y = mouseY - elementY - box.clientHeight/2 - wrap.clientTop;
// 设置镜片移动范围
// 判断zz_X数值如果小于0 那个元素就出超出父元素的范围(左边超出)
if(zz_X < 0 ){
// 如果镜片移动值小于0 就让他强制等于 0
zz_X = 0 ;
// 判断如果zz_X数值如果大于 父元素的clientWidth距离 减去 镜片元素的chlientWidth距离就会超出父元素范围(右边超出)
}else if(zz_X > wrap.clientWidth-box.clientWidth){
// 就让他强制等于 父元素的clientWidth距离 减去 镜片元素的chlientWidth距离
zz_X = wrap.clientWidth - box.clientWidth;
}
// 判断zz_y数值如果小于0 那个元素就出超出父元素的范围(上边超出)
if(zz_Y < 0 ){
// 如果小于0就让他强制等于 0 相当于让镜片的top值强制设置为 0
zz_Y = 0 ;
// 判断如果zz_y数值如果大于 父元素的clientHeight距离 减去 镜片元素的clientHeight距离就会超出父元素范围(下边超出)
}else if(zz_Y > wrap.clientHeight - box.clientHeight){
// 就让他强制等于 父元素的clientWidth距离 减去 镜片元素的chlientWidth距离
zz_Y = wrap.clientHeight - box.clientHeight;
}
// 最终镜片移动值 赋值给镜片元素box的left/top值
box.style.left = zz_X + "px";
box.style.top = zz_Y + "px";
// 大图片的背景图片定位值 // 设置镜片移动时右边大图片显示的内容(改变定位值)// 动态的移动值 除以 算出的比例
big.style.backgroundPositionX = -zz_X / r + "px";
big.style.backgroundPositionY = -zz_Y / r + "PX";
}
}
// 鼠标移出事件
wrap.onmouseleave=function(){
console.log("鼠标移出了");
// 移除后镜片与大图片设置为隐藏
box.style.display = "none";
big.style.display = "none";
}
// 计算某个元素到视口的距离
function offset(dom) {
// 返回一个对象
var obj = {
left: 0,
top: 0
}
// 先让这个对象加上 dom的自己得到定位父元素的距离
obj.left = dom.offsetLeft;
obj.top = dom.offsetTop;
// 判定浏览器是否是IE8
var isIE8 = window.navigator.userAgent.indexOf("MSIE 8") != -1;
// 循环往上走 累加每一个offsetParent的offsetLeft和clientLeft
// 加每一个offsetParent的offsetTop和clientTop
var offsetParent = dom.offsetParent;
while (offsetParent != document.body) {
if (isIE8) {
obj.left += offsetParent.offsetLeft;
obj.top += offsetParent.offsetTop;
} else {
obj.left += offsetParent.offsetLeft + offsetParent.clientLeft;
obj.top += offsetParent.offsetTop + offsetParent.clientTop;
}
offsetParent = offsetParent.offsetParent;
}
return obj;
}
</script>
最终放大镜就完成了如下
如有不对请指正