Magnifier笔记

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Magnifier</title>
<!--
20161109学习了一个jq写放大镜的demo。
需要注意的几点:
1、在样式设计上,浮动一定是所有的同级元素,比如下面结构中的span按钮和中间的包裹图片的div盒子,一开始,我只给按钮加了浮动,忘了中间包裹图片的div,结果,你们知道的哈,我调试了半个小时……
2、还有一点是非常需要注意的,那就是下面的图片大图显示区还有获取局部图片的盒子以及最终效果的放大镜,说白了,就是三个盒子,他们的宽高必须是倍数的关系,不然最后你的放大镜会出现放大偏移的bug。
3、没了,暂时就是这些,视频教学里,只是把代码复制了一遍,也没教这些实现的原理是怎样的,蛋疼的我,研究了一下午,得出以下代码注释结论,如果你发现了错误,请来跟我交流哦。
-->
<style>
/*公共样式:略*/
*{margin: 0;padding: 0;list-style: none;}

/*zoom:最外面的盒子,及父盒子,可以有可以没有*/
.zoom{width: 800px;height: 700px;position: relative;margin: auto;}
/*zoomMin:这个命名其实给错了,不想改了,他的意思是大图展示区*/
.zoomMin{position: relative;width: 380px;height:380px;border: 1px solid indianred;margin-bottom: 3px; }
.zoomMin img{width: 100%;height: 380px;}
/*大图展示区里的取图片局部的“放大镜”*/
.zoomMin .mask{width: 126px;height: 126px;background: red;opacity: 0.5;position: absolute;left: 0;top:0;display: none;}

/*zoomSmall:存放所有小图的盒子*/
.zoomSmall{width: 380px}
/*里面还包含两个按钮*/
.zoomSmall span{cursor: pointer;float: left;width: 10px;height:60px;line-height: 60px;border-radius: 2px;background: #82878c; }

/*wrapSallImg:它被包含在zoomSmall里,是具体的备选小图的集合容器*/
.wrapSallImg{width: 359px;overflow: hidden;margin-right:1px;float: left;/*因为两个按钮和他是同级别的,所以也要给浮动。*/}
.wrapSallImg ul{width:1450px;position: relative;/*这里最好是给这个relative相对定位,他表示被定位,但是还占位,使用absolute后,你可以试试……*/}
/*清浮动:略*/
.wrapSallImg ul:after{content: "";display: block;clear: both;}
.wrapSallImg ul li{cursor: pointer;float: left;width: 68px;height: 60px;border: 1px solid #ccc;margin: 0 1px; _display: inline;/*兼容ie6的margin问题*/}
.wrapSallImg>ul>li img{width: 100%;height: 60px;}
.wrapSallImg ul .action{border: 1px solid red; }

/*zoom_arge:最终的放大镜就是这个了*/
.zoom_arge{width: 250px;height: 250px; border: 1px solid saddlebrown;position: absolute;top:0;
right:0;overflow: hidden;display: none;}
.zoom_arge img{height: 760px; width: 760px;position: absolute;}
</style>
<script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="zoom">
<div class="zoomMin">
<img src="http://attach.bbs.miui.com/forum/201408/17/102430y8d11dmnp7stnz5d.jpg.thumb.jpg" alt="">
<div class="mask"></div>
</div>
<div class="zoomSmall">
<span class="leftBtn">&lt;</span>
<div class="wrapSallImg">
<ul>
<li class="action"><img src="http://attach.bbs.miui.com/forum/201408/17/102430y8d11dmnp7stnz5d.jpg.thumb.jpg" alt=""></li>
<li><img src="http://attach.bbs.miui.com/forum/201408/17/102517tcktmhlz04ppwtck.jpg.thumb.jpg" alt=""></li>
<li><img src="http://attach.bbs.miui.com/forum/201408/17/102537fzhin5jjce5mcsrf.jpg.thumb.jpg" alt=""></li>
<li><img src="http://attach.bbs.miui.com/forum/201408/17/102539zuxem000ump9z11m.jpg.thumb.jpg" alt=""></li>
<li><img src="http://t1.mmonly.cc/uploads/allimg/tuku2/10293325N-0.jpg" alt=""></li>
<li><img src="http://t1.mmonly.cc/uploads/allimg/tuku2/1029331950-4.jpg" alt=""></li>
<li><img src="http://attach.bbs.miui.com/forum/201408/17/102517tcktmhlz04ppwtck.jpg.thumb.jpg" alt=""></li>
<li><img src="http://attach.bbs.miui.com/forum/201408/17/102537fzhin5jjce5mcsrf.jpg.thumb.jpg" alt=""></li>
</ul>
</div>
<span class="rightBtn">&gt;</span>
</div>
<div class="zoom_arge"><img src="http://attach.bbs.miui.com/forum/201408/17/102430y8d11dmnp7stnz5d.jpg.thumb.jpg" alt=""></div>
</div>
<input type="text" woshizidingyishuxing="用来测试你的各种运行值对不对的一个框">
</body>
<script>
var oZoomMin=$(".zoomMin");
var oZoomMinImg=$(".zoomMin img");
var aSmallImgUl=$(".wrapSallImg ul");
var aSmallImgLi=$(".wrapSallImg ul li");
var aSmallImLiWidth=aSmallImgLi.outerWidth(true);//true:这样就把元素的边框和margin或padding值都计算进来了。
var aSmallImgLiImgs=$(".wrapSallImg ul li img");
var oLbtn=$(".leftBtn");
var oRbtn=$(".rightBtn");
var now=0;/*计数器:等价于自定义的循环参数 i 一样的道理*/
$(function () {
aSmallImgLi.on("mouseover",function () {
$(this).addClass("action").siblings().removeClass("action");
/*1.aSmallImgLi:所有小图集合;
* 2.添加鼠标移入事件mouseover
* 3.$(this):等于是jq自动帮你循环遍历了这个集合,而$(this)就是指当前被鼠标移入的小图。
* 4.执行结果:给当前触发事件的元素添加一个class类名叫action,其他的兄弟们删掉这个class类名。
* */
});
aSmallImgLiImgs.on("click",function () {
var aSmallImgLiImgSrc= $(this).attr("src");
oZoomMinImg.prop("src",aSmallImgLiImgSrc);
$(".zoom_arge img").prop("src",aSmallImgLiImgSrc);
/*1.上面是鼠标移入事件,那这个就时点击事件,我叫他确认事件。选半天了,总得确认一个吧。
* 2.有所不同的是上面的是给li加的class,而这个是给包含在li里面的img做的事件哦
* 3.执行结果:当你点击小图片后,会通过prop()方法把你的attr属性的值得到,然后赋给大图展示区和放大镜的最终盒子,前提是他们里面都要包含一个img来接收这个地址。
* 4.值得一提的是:attr()和prop()方法功能是一样的,都是获取元素的属性的,这里的属性不是指css样式啊,这个不要搞混同学,css样式要用css()获取。那么,老定义了,(“写一个值就是获取”,“写两个值就是改值,并且要用双引号啊,不然就是变量了”)
* 好,基本功能是一样的,但是,切记,这是最容易被忽略的芝士:attr可以获取你自己定义的属性,而prop只能是获取到元素本身就有的属性。自定义属性:比如你这样写<input type='text' value='123' papapa='red'>
* 那么,这个input里的papapa=‘red’就是你自定义的属性。一样,通过arrt()方法,你也可以动态的给元素添加自定义属性
**/
});
oLbtn.on("click",function () {

if (now==0){
now=0;
}else {
now--;
aSmallImgUl.animate({"left":"+="+aSmallImLiWidth},500);
}
/*1.我的天啊,这里是我一开始最头痛的地方,这到底是为了什么,难死爸爸了。不过认真的分析后,嗨,太简单了。
* 2.事件:左按钮被点击了。
* 3.然后进入判断
* 4.我们的计数器now初始化值就是0,所以第一个条件成立,如果这时候你点击左按钮,他会不鸟你,原因就在于,人家在第一次判断中胜利了。这也是我们想要的结果,如果还不太明白,你可以把else里的语句拿到if判断外面点击一下左按钮,就会幡然醒悟。
* 5.其实关键的在于计数器now--:在事件外面的计数器now初始值是0,那么作为全局变量的它很微妙,在你点击右键的时候,他其实被赋值为+1了,这个其实就相当于我们使用的for循环,这个计数器就相当于 i ,这也是js的一个非常方便的机制,全局变量可以共享函数里的值,甚至被传入其他函数中。
* 6.那么当我们通过点击右键给计数器赋值成为1后,那么你再点击左按钮,哎?对了,第一个判断语句不会生效了,那么好的,执行else语句吧。这里计数器--,就是now=now-1;这样1-1后又是0了,你再点击,好的,第一天判断生效,就不给你执行下面的语句了。这,就是实现思路。
* 7.关于“+=”,看过相关教程的应该都知道,就是让值累加,这样才能实现点一个走一个,不然,只会原地踏步。
* */
});
oRbtn.on("click",function () {
if (now==3){
now=3;
}else {
now++;
aSmallImgUl.animate({"left":-now*aSmallImLiWidth},500)
}
/*由上面的逻辑,同样, 你可以推算出这个右按钮的执行逻辑。
* 这个参数3指的是被隐藏的那3个图片的下标
* */
});
oZoomMin.on("mousemove",function (e) {
$(".zoom_arge").show(); //当大图展示区被鼠标移入的时候,我们就让放大镜区显示
var oZoomMinOffset=$(this).offset(); //这里有很多算法,数学不好的我,真是相当的蛋疼啊,不过,我们可以一点一点的推算,这,到底是为了什么?
var X=e.pageX-oZoomMinOffset.left - $(".mask").width()/2;
var Y=e.pageY-oZoomMinOffset.top - $(".mask").height()/2;
/*1.首先是获取:声明一个变量来接收大图展示区$(this)的offset()方法。这个方法里装着两个值offset().left和offset().top;
* 简单解释一下这是什么值哈:就是距离文档的位置,譬如:div在body里,那么他的文档距离就是他自己的margin或者padding,如果div里有一个p表情,那他的距离就是距离的div的,跟body甚至document都没有关系了。
* 2.ok,获取了之后呢就要赋值了,首先,我们要获取到鼠标移动的坐标,函数(e),然后e.pageX,不清楚的百度哈,这个很简单了,就是鼠标的值,然后
* 这个值要进过一系列的计算,按照运算规则,应该是先计算最后面那个除以2,好,我们就先来看这个除以2.
* a.$(".mask")是我们局部图片的拾取器,他的宽除以2还剩下一半的宽,我们只需要记住,这样写,是为了,让鼠标移动到拾取器盒子的中间才会开始带着拾取器去“漫游”,你可以先把我这除以二去掉看看执行结果。
* b.那么剩下的就是大图展示区距离文档的距离 - 去了还剩一半尺寸的拾取器,最后他们两剪完的数值还被鼠标的数值给减去了,好吧,我都不想写注释了,但,做人就要做到底。
* c.鼠标距离是指在当前这个元素的整个尺寸上,我们鼠标所在的坐标位置,它同样具备横向和纵向,他的left就是X,top就是Y,那么他减去当前元素距离文档的距离得出的是这个鼠标所在的真实位置;
* d.这样说你可能不明白,你可以做一个例子,如果,你的这个div就是贴在左上角的,没有margin和padding,手欠的你还写了*{margin:0;padding:0};那么offset()这个值就可以不用写了,不信,你可以试试,在这种情况下
* 你把offset()去掉,当然也就不用减去oZoomMinOffset.left了,这时候,你会发现,我擦,居然也可以啊。但是,记住,但是,如果你给div,这div就是指最外面那个大盒子了,如果你给他了margin或者padding,嘿嘿,自己体验吧。
* */
if (X<=0){
X=0;
}else if (X>=oZoomMin.width()-$(".mask").width()){
X=oZoomMin.width()-$(".mask").width()
}
if (Y<=0){
Y=0;
}else if (Y>=oZoomMin.height()-$(".mask").height()){
Y=oZoomMin.height()-$(".mask").height()
}
/*1.判断条件一的功能是让我们的拾取器不会超过父盒子可视区;
* 2.首先还是判断,如果X的值等于0,那好我们就让她等于0;下面的不执行
* 3.如果不等于0;那么看看是是不是大于或者等于这个值呢?
* 4.重点来了,这个值是干嘛的,首先:oZoomMin我们的大图展示区,他的宽减去拾取器的宽,还减去他的高度,就等于是在他身上挖去一块拾取器大小的尺寸。
* 5.这个尺寸干嘛用啊?看下面;
* /
/*比例尺*/
var percentageX=X/(oZoomMin.width()-$(".mask").width());
var percentageY=Y/(oZoomMin.height()-$(".mask").height());
/*这个东西叫比例尺
* 它是什么呢他就是经过上面判断出来的那剩下的一大块尺寸然后呢除以了大图展示区减去拾取器的尺寸,哎?这不就是自己除以自己嘛?对啊,1/1=1吧;2/2=1吧,3/3=1吧;
* 比例尺,要的,就是这个1等1的比例如果你像把比例放大,即做到放大更多倍数的话,就把比例加大就好了,当然,那样会显示的很怪异,建议不要做。
* */
$("input").val(percentageX+"and"+percentageY);//显示我们比例尺的
$(".zoom_arge img").css({
"left":-percentageX*($(".zoom_arge img").width()-$(".zoom_arge").width())+"px",
"top":-percentageY*($(".zoom_arge img").height()-$(".zoom_arge").height())+"px"
});
/*1.最终的这个放大镜展示区,就是用比例尺,当然,是负数的。如果是正数呢,拾取器就只会获取我们的左上角那一块;只需记住,正数显示不对的就给个负数。
* 2.我们放大镜展示区里的图的尺寸是它父亲的3倍多一点,这个尺寸是有一定规律的,好好想想,必须是倍数,不然我们最终的显示就会变形。
* 3.大图宽度减去放大镜盒子宽度被鼠标控制的比例尺乘,会是什么结果呢,被放大了呗。并且是按比例放大的。其实,这里的减法,我不是很明白,如果换我写,我想不明白为什么要这样。。。。
* 反正,最后就是我们放大镜里的大图展示的定位坐标,是通过这么一系列蛋疼的算法得出来的。
* 用jq写已经是超级省代码了,原生的,你就哭吧。
* */
$(".mask").show().css({ //同样的还有我们用来获取局部图片的放大镜拾取器吧,这样叫吧,想不出别的名字了。
"left":X+"px", //这里的X和Y ,如果你觉得被上面一系列算法污染了,可以拿到最顶部,一样可以执行,不会被影响。
"top":Y+"px"
});
});
oZoomMin.on('mouseout',function () {
/*这里就是尾声了,很简单,鼠标移出,消失不见*/
$(".mask").hide();
$(".zoom_arge").hide();
});

/* var arr=[
oZoomMinImg=null,
aSmallImgLi=null,
aSmallImgLiImgs=null
]; */ //用完之后集体销毁,不再占用内存。


});
/*稍加修改,把他变成自己的插件吧。*/


</script>
</html>
posted @ 2016-11-09 20:26  宋宇  阅读(375)  评论(0编辑  收藏  举报