一直都想写一个图片轮播,可是却一直都没有静下心来,今天终于有时间,就来做个图片查看器吧
功能:拖拽,缩放,还原,轮播,透明度
拖拽实现原理:鼠标按下onmousedown,鼠标移动onmousemove,鼠标松开onmouseup释放鼠标按下和移动的函数,一定是按下鼠标的同时进行移动,这里指的都是鼠标左键!
这里的难点就是清除默认事件,反正我是这样认为的,花了好几个小时才弄出来。写完之后发现,鼠标点一下再松开,图片就粘再指针上了,一直跟着指针跑,郁闷了好久,为什么会发生这种事,仔仔细细看了几十遍代码,才发现原来是写的onmouseup事件没有触发,鼠标按下去肯定会松开,不清除默认事件,自定义的onmouseup是不会执行的,突然间恍然大悟(⊙o⊙),急忙在onmousedown下添加event.preventDefault,这下总行了吧,果然可以。可是IE7,8怎么都不行,查了一下,又是兼容性!万恶的IE,我也是醉了。。。returnValue加上了,再看IE,怎么还是不行,先让我一个人静静。。。等等,发现怎么效果和没清除默认事件之前是相同的,可是确实清除了默认事件啊,肯定是这句的问题,网上各种百度,终于找到了一种说法,把清除默认事件的语句放在onmousemove中,有点不理解,可是确实没了bug,我觉得应该是onmousemove也有一个onmouseup默认事件
缩放实现原理:改变每张图片的宽度和高度,style.width,style.height
图片轮播原理:把每一张图片放在数组中,这时,数组中的栈方法push,pop和队列方法shift,unshift就可以发挥作用了;不知道这几个方法的看最下面。
简单解释一下方法
例:点击下一张图片
1 arr = [imgObj[0],imgObj[1],imgObj[2]]; 2 arr.push(arr[0]);//第一项添加到数组最后
3 arr.shift();//删除数组第一项
4 //这时数组变为[imgObj[1],imgObj[2],imgObj[0]];
这样第二张图片就移动到数组第一个元素了,
同理可以用unshift()和pop()方法来实现上一张图片。
这样处理的好处是每次只需要对数组的第一个元素进行处理,因为数组第一个元素就是当前的这张图片。
还原实现原理:把图片重置成网页加载完成时的样子,left,top,width,height,opacity,filter等。
改变透明度:看了下腾讯体育http://news.qq.com/photo.shtml的轮播器,貌似就是改变透明度,opacity从0变到1,看起来像动画效果
要注意的就是兼容性,万恶的IE8以前的版本,都不支持opacity,改变透明度的属性是filter=alpha(opacity=100)'【范围0-100】===opacity=1这俩是一个效果
透明度增加,这里用到了定时器setInterval(),透明度大于100时就没有效果了,所以在大于100时要清除定时器clearInterval()
HTML
1 <div id="divInput"> 2 <input type="button" value="上一张"/> 3 <input type="button" value="放大"/> 4 <input type="button" value="还原"/> 5 <input type="button" value="缩小"/> 6 <input type="button" value="下一张"/> 7 </div> 8 <div id="div"> 9 <li><img class="active" src="../img/1.jpg" /></li> 10 <li><img class="" src="../img/2.jpg" /></li> 11 <li><img class="" src="../img/3.jpg" /></li> 12 </div>
JavaScript
拖拽
1 //imgObj图片对象 2 imgObj.onmousedown = function(ev){ 3 var event = window.event || ev;//兼容ie7 8 4 var position = {x:0,y:0}; 5 position.x = event.clientX - imgObj.offsetLeft;//鼠标点击位置到图片左边的一段距离 6 position.y = event.clientY - imgObj.offsetTop; 7 document.onmousemove = function(ev){ 8 var event = window.event || ev; 9 (event.preventDefault)?event.preventDefault():event.returnValue = false;//阻止默认事件 10 var x = event.clientX - position.x;//移动后的left值 11 var y = event.clientY - position.y; 12 imgObj.style.left = x + 'px'; 13 imgObj.style.top = y + 'px'; 14 }; 15 document.onmouseup = function(){//松开鼠标左键 16 document.onmousedown = null; 17 document.onmousemove = null; 18 }; 19 };
放大
1 var imgObj = document.getElementsByTagName("img"); 2 for(var i = 0;i<imgObj.length;i++){ 3 if(imgObj[i].className == 'active'){//对当前图片进行操作 4 imgObj[i].style.width = imgObj[i].offsetWidth * 1.1 + 'px'; 5 imgObj[i].style.height = imgObj[i].offsetHeight * 1.1 + 'px'; 6 break; 7 }; 8 };
还原
1 for(var i=0;i<imgObj.length;i++){ 2 imgObj[i].style.width = '500px'; 3 imgObj[i].style.height = '309px'; 4 imgObj[i].style.left = '0'; 5 imgObj[i].style.top = '0'; 6 imgObj[i].style.opacity = 1; 7 imgObj[i].style.filter = 'alpha(opacity = 100)'; 8 };
下一张
1 var liObj = document.getElementById('div').children; 2 if(arr[0] == undefined){ 3 for(var i = 0;i<liObj.length;i++){ 4 arr.push(liObj[i].children[0]); 5 }; 6 }; 7 arr.push(arr[0]);//数组变化为 123->1231->231 8 arr.shift(); 9 change(); 10 arr[0].className = 'active'; 11 arr[1].className = ''; 12 arr[2].className = '';
定时器改变透明度
var alpha = 40;//从40开始变化 var speed = 3;//变化速度 var timer = setInterval(function(){ alpha =alpha + speed; arr[0].style.filter = 'alpha(opacity='+alpha+')';//兼容ie7 8 arr[0].style.opacity = alpha/100; if(alpha >= 100){ clearInterval(timer);//清除定时器 }; },30); arr[1].style.opacity = 0.4;//非active图片透明度为40 arr[2].style.opacity = 0.4;
总结:总的来说这次做非常的不顺手,刚开始感觉无从下手,不过后来理了一下思路,就没有那种感觉了。我觉得清除默认事件是难点,是因为我在这个点上折腾的时间最长,好几个小时,不过毕竟做出来了,还是有些成就感的,兼容了IE7、8。还记得以前看见华为官网的无缝滚动轮播,感觉高端大气上档次,下次俺也用jquery做个无缝滚动的轮播器玩玩。
Array内置方法
栈方法:push(x)将x推入数组最后一项,pop()删除数组最后一项;
队列方法:unshift(x)将x添加到数组第一项,shift()删除数组的第一项。