文档章节

javascript淘宝主图放大镜功能

zfx2016
 zfx2016
发布于 2016/10/19 11:42
字数 1239
阅读 9
收藏 0

工欲善其事,必先利其器。想要实现某一种效果,我们必须要先了解其中的原理。

放大镜的功能就是通过获取鼠标在小图中的位置,然后根据大小图的尺寸比例换算出大图需要显示的部分,然后使用定位让大图要显示的部分出现在右边的边框内。

然后看代码,根据代码看讲解会更容易理解。


html部分


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>放大镜效果</title>
    <link rel="stylesheet" href="magnifier.css">
</head>
<body>
    <div id="wrapper">
    <!--小图-->
        <div id="img_min">
        <!--图片-->
        <img src="test.jpg" alt="min">
        <!--跟随鼠标的白块-->
        <p id="mousebg"></p>
        </div>
        <!--大图-->
        <div id="img_max"><img id="img2_img" src="test.jpg" alt="max"></div>
    </div>
    <script type="text/javascript" src="magnifier.js"></script>
</body>
</html>


css部分


*{
    margin: 0;
    padding: 0;
}
div{
    position: relative;
}
div>div{
    width: 300px;
    height: 300px;
    float: left;
    margin: 100px;
    overflow: hidden;
}
#img_min>img{
	/*display: block;*/
    width: 300px;
}
#img_max{
    display: none;
    
}
#img_max>img{
	position: absolute;
	top: 0;
	left: 0;
	display: block;
    width: 1500px;
}
#mousebg{
	display: none;
	position: absolute;
	width: 60px;
	height: 60px;
	background-color: rgba(255,255,255,.7);
	top: 0;
	left: 0;
}


最重要的javascript部分


window.onload = function () {
    var img1 = document.getElementById('img_min');//小图盒子
    var img2 = document.getElementById('img_max');//大图盒子
    var img2_img = document.getElementById('img2_img');//大图图片
    var wrap = document.getElementById('wrapper');
    var mousebg = document.getElementById('mousebg');//鼠标白块
    var mul = 5;
    //当某一个模块dispaly:none的时候不能使用offsetWidth获取它的宽高
    img1.onmouseover = function () {
		//鼠标进入
        img2.style.display = 'block';
        mousebg.style.display = 'block';
        
    }
    img1.onmouseout = function () {
	    //鼠标离开
        img2.style.display = 'none';
        mousebg.style.display = 'none';
    }
    img1.onmousemove = function (event) {
        var _event = event||window.event;//兼容性处理
        var mouseX = _event.clientX - wrap.offsetLeft - img1.offsetLeft;
        //计算鼠标相对与小图的位置
        var mouseY = _event.clientY - wrap.offsetTop - img1.offsetTop;

		//特殊情况处理,分别靠近四条边的时候
		if(mouseX<mousebg.offsetWidth/2){
			mouseX = mousebg.offsetWidth/2;
		}
		if(mouseX>img1.offsetWidth-mousebg.offsetWidth/2){
			mouseX = img1.offsetWidth-mousebg.offsetWidth/2;
		}
		if(mouseY<mousebg.offsetHeight/2){
			mouseY = mousebg.offsetHeight/2;
		}
		if(mouseY>img1.offsetHeight-mousebg.offsetHeight/2){
			mouseY = img1.offsetHeight-mousebg.offsetHeight/2;
		}
		//计算大图的显示范围
		img2_img.style.left = -mul*mouseX+img2.offsetWidth/2+"px";
	    img2_img.style.top = -mul*mouseY+img2.offsetHeight/2+"px";
	   //使鼠标在白块的中间
		mousebg.style.left = mouseX-mousebg.offsetWidth/2+"px";
		mousebg.style.top = mouseY-mousebg.offsetHeight/2+"px";
        
    }
}


如果你看完代码和注释已经理解了,用李云龙的一句话说:“哎呀,你小子tnd还真是个天才”。那么下面的解析部分你快速的浏览完就OK了。


解析部分:


html和css部分都是简单的布局代码,不再讲解,js部分代码也比较简单,我们直接讲解鼠标移动事件部分的代码。

首先用一张图来解释一下获取鼠标相对与小图位置的原理


可以看到通过代码中的运算,我们所获取的值就是鼠标相对于img1左上角的值。

理解了这一步之后,其实可以说我们的工作已经完成了一半了。

然后,我们先跳过特殊情况的处理,直接进行右边图片定位的基本运算。

因为有用到offsetWidth、offsetHeight、style.width、style.height属性,其中style.width、style.height和offsetWidth、offsetHeight的范围是相同的,其他不同我会在另一篇博客中详细描述。我们先用一张图了解下这几个属性,同时和上面的几个属性进行对比(图片来自互联网,侵删)


然后我们讲解代码


右边大图框中的图片使用style.left定位在大图框中的位置,负号是因为我们鼠标的运动方向刚好是和我们大图框中的图片运动的方向相反,mul则是根据大图和小图的尺寸计算出来的比例,-mul*mouseX计算出来的其实就是图片在大图框中的相对位置,但是此时你会发现你鼠标所在的位置在右边是在图框的左上角的,所以我们要加上一个 img2.offsetWidth/2 来让图片居中显示。同样我们在纵坐标进行相同的处理就好了。

//计算大图的显示范围
		img2_img.style.left = -mul*mouseX+img2.offsetWidth/2+"px";
	    img2_img.style.top = -mul*mouseY+img2.offsetHeight/2+"px";

下面我们就要进行特殊情况的处理了,做到上一步的时候你会发现,在鼠标移动到边缘的时候,鼠标那个小白块有时候会跑出图片的范围,所以我们就要进行处理将它限制在图片的范围内,因为鼠标是在白色透明块的中间,所以我们就是将鼠标限制在距离图片边框上下左右二分之一白块长/宽的位置即可。

//特殊情况处理,分别靠近四条边的时候
		if(mouseX<mousebg.offsetWidth/2){
			mouseX = mousebg.offsetWidth/2;
		}
		if(mouseX>img1.offsetWidth-mousebg.offsetWidth/2){
			mouseX = img1.offsetWidth-mousebg.offsetWidth/2;
		}
		if(mouseY<mousebg.offsetHeight/2){
			mouseY = mousebg.offsetHeight/2;
		}
		if(mouseY>img1.offsetHeight-mousebg.offsetHeight/2){
			mouseY = img1.offsetHeight-mousebg.offsetHeight/2;
		}

当距离左边小于二分之一宽的时候,我们就让mouseX等于二分之一宽,这样白块就不会继续移动,其他三个方向同理。

做完这一步,我们的效果也就全部完成了。

ps:抽象的地方可以通过画图来帮助理解



© 著作权归作者所有

zfx2016
粉丝 1
博文 22
码字总数 14027
作品 0
广州
前端工程师
私信 提问
淘宝放大镜的简单实现,原来道理很简单

前言:自己在学习过程中构思的淘宝放大镜的实现,大佬轻喷,小白可以跟我一起探讨学习。话不多说,我们来看效果图。 首先是html结构,结构主要就三块,放大镜,小图和大图区域,我们都用div...

扶墙哥
2018/08/02
0
0
基于 Vue 的商品主图放大镜方案

本文首发于政采云前端团队博客: 基于 Vue 的商品主图放大镜方案 前言 在做电商类应用时,难免会遇到商品主图实现放大镜效果的场景,现有的基于的第三方包不多并且无法直接复用,今天,我来分...

政采云前端团队
09/19
0
0
Google Chrome浏览器开发人员工具

准备工作 要开始使用开发人员工具,请先下载 Google Chrome 浏览器。在浏览器安装完成后,您可以打开自己感兴趣的网页或网络应用程序,然后通过下面任何一种方式进入开发人员工具: l 点击位...

张悟空
2014/08/20
91
0
EveryChart教程(一)----饼形图

EveryChart是一个使用简单,功能强大的JS绘制图表工具,这里介绍如何使用 Chart是各种图表的基类,不能被实例化,图表的公共属性有: title 标题(对象) width 宽 height 高 vivid 是否动画显示 sh...

兔宝宝
2011/08/30
3K
7
京东商城技术揭秘:.NET与Java博弈

【IT168 技术】春运期间,铁道部的现任老大12306网站在面对日均10亿多次的点击量时,频繁瘫痪,给我们带来的惨痛教训是,关键时刻不能掉链子,这也印证了科技是第一生产力。   而说起中国自...

作者:DoubleLife
2012/01/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
25分钟前
5
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
40分钟前
66
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
7
0
Spring Security 实战干货:必须掌握的一些内置 Filter

1. 前言 上一文我们使用 Spring Security 实现了各种登录聚合的场面。其中我们是通过在 UsernamePasswordAuthenticationFilter 之前一个自定义的过滤器实现的。我怎么知道自定义过滤器要加在...

码农小胖哥
今天
9
0
常见分布式事务解决方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇,很多互联网行业巨头、开源...

asdf08442a
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部