图片查看 ImagesViewer

项目中需要有图片的浏览功能。以前都是去网上找现成的插件,但是突然心血来潮,想自己写一个,于是乎把以前的代码拿来组合一下,在修修改改就完成了一个简单的版本。

话不多说,先上代码,再说问题。

  1 (function () {
  2     var eventNames = {
  3         touchstart: "touchstart",
  4         touchmove: "touchmove",
  5         touchend: "touchend",
  6         touchcancel: "touchcancel"
  7     };
  8 
  9     var isTouchable = function () {
 10         var iosDevices = ['iphone', 'ipad', 'ipod'];
 11         var touchDevices = ['android', 'phone', 'blackbery'].concat(iosDevices);
 12         var appVersion = navigator.appVersion.toLowerCase();
 13         for (var i = 0; i < touchDevices.length; i++) {
 14             if (appVersion.indexOf(touchDevices[i]) > -1) {
 15                 return true;
 16             }
 17         }
 18         return false;
 19     };
 20 
 21     if (window.ImagesScroller) {
 22         return;
 23     }
 24 
 25     window.ImagesScroller = function (wrapperSelector) {
 26         this.$wrap = $(wrapperSelector);
 27         this.$ul = this.$wrap.find("ul");
 28         this.itemWidth = this.$wrap.width();
 29         //this.itemHeight = this.$wrap.height();
 30         this.itemWidth = this.itemWidth;
 31         var $lis = this.$wrap.find("ul li");
 32         $lis.width(this.itemWidth);
 33         $lis.height(this.itemHeight);
 34         this.count = $lis.length;
 35         this.$ul.width(this.itemWidth * this.count);
 36         this.$ul.height(this.itemWidth);
 37         this.currentIndex = 0;
 38         this._isMoving = false;
 39         this.speed = 200;
 40         this.onNext = null;
 41         this.onPrev = null;
 42         this.onChange = null;
 43         this.onItemClick = null;
 44         this.sensitivity = 2; // 1-9
 45         this._isTouchable = isTouchable();
 46         this._touchStartPosition = null;
 47         this._touchEndPosition = null;
 48         this._isHorizontal = null;
 49     };
 50 
 51     ImagesScroller.prototype = {
 52         init: function () {
 53             var me = this;
 54             me.bindEvents();
 55         },
 56         bindEvents: function () {
 57             var me = this;
 58             if (me._isTouchable) {
 59                 me._bindTouchEvents();
 60             } else {
 61                 me._enableMouseDrag();
 62             }
 63         },
 64         _bindTouchEvents: function () {
 65             var me = this;
 66             me.$ul[0].addEventListener(eventNames.touchstart, function (e) {
 67                 me._isHorizontal = null;
 68                 me._touchStartPosition = me._getTouchPosition(e);
 69             });
 70             me.$ul[0].addEventListener(eventNames.touchmove, function (e) {
 71                 me._touchEndPosition = me._getTouchPosition(e);
 72                 if (me._isHorizontal == null) {
 73                     try {
 74                         var x = Math.abs(me._touchEndPosition.x - me._touchStartPosition.x);
 75                         var y = Math.abs(me._touchEndPosition.y - me._touchStartPosition.y);
 76                         me._isHorizontal = (x >= y);
 77                     } catch(e) {
 78 
 79                     } 
 80                 }
 81                 if (me._isHorizontal == true) {
 82                     e.preventDefault();
 83                     me._move();
 84                 }
 85             });
 86             me.$ul[0].addEventListener(eventNames.touchend, function (e) {
 87                 if (me._isHorizontal == true) {
 88                     e.preventDefault();
 89                     me._touchEnd();
 90                 }
 91                 me._isHorizontal = null;
 92             });
 93         },
 94         _enableMouseDrag: function () {
 95             var me = this;
 96             me.$ul.mousedown(function (e) {
 97                 e.stopPropagation();
 98                 me._touchStartPosition = me._getTouchPosition(e);
 99             });
100             me.$ul.mousemove(function (e) {
101                 e.stopPropagation();
102                 me._touchEndPosition = me._getTouchPosition(e);
103                 me._move();
104             });
105             me.$ul.mouseup(function (e) {
106                 e.stopPropagation();
107                 me._touchEnd();
108             });
109 
110             me.$ul.mouseout(function(e) {
111                 e.stopPropagation();
112                 me._touchEnd();
113             });
114         },
115         _move: function () {
116             var me = this;
117             if (me._isMoving) {
118                 return;
119             }
120             if (me._touchStartPosition && me._touchEndPosition) {
121                 var left = -(me.itemWidth * me.currentIndex);
122                 var offset = me._touchEndPosition.x - me._touchStartPosition.x;
123                 me.$ul.css("left", (left + offset) + "px");
124             }
125         },
126         _touchEnd: function () {
127             var me = this;
128             if (me._touchStartPosition && me._touchEndPosition) {
129                 var needOffset = me.itemWidth * me.sensitivity / 10;
130                 var offset = me._touchEndPosition.x - me._touchStartPosition.x;
131                 if (Math.abs(offset) >= needOffset) {
132                     if (offset > 0) {
133                         me.prev();
134                     } else {
135                         me.next();
136                     }
137                 } else {
138                     me._restore();
139                     me._itemClick(offset);
140                 }
141             } else {
142                 me._itemClick(null);
143             }
144             me._touchStartPosition = me._touchEndPosition = null;
145         },
146         toIndex: function (index) {
147             var me = this;
148             var oldIndex = me.currentIndex;
149             if (me._isMoving) {
150                 return;
151             }
152             if (index >= me.count) {
153                 index = me.count - 1;
154             }
155             if (index < 0) {
156                 index = 0;
157             }
158             me.currentIndex = index;
159             var left = -(me.itemWidth * index);
160             me._isMoving = true;
161             $(me.$ul).animate({
162                 left: left
163             }, me.speed, function () {
164                 me._isMoving = false;
165                 me.onChange && me.onChange();
166                 if (oldIndex < me.currentIndex) {
167                     me.onNext && me.onNext();
168                 } else if (oldIndex > me.currentIndex) {
169                     me.onPrev && me.onPrev();
170                 }
171             });
172         },
173         next: function () {
174             var me = this;
175             me.toIndex(me.currentIndex + 1);
176         },
177         prev: function () {
178             var me = this;
179             me.toIndex(me.currentIndex - 1);
180         },
181         _itemClick: function (offset) {
182             var me = this;
183             if (Math.abs(offset) <= 2) {
184                 me.onItemClick && me.onItemClick();
185             }
186         },
187         _bindClick: function (selector, func) {
188             var me = this;
189             if (me._isTouchable == false) {
190                 $(selector).click(function (e) {
191                     if ($(this).hasClass("disabled")) {
192                         return;
193                     }
194                     func.call(this, e);
195                 });
196                 return;
197             }
198 
199             var isMoving = false;
200             var startTime = null;
201             $(selector).bind(eventNames.touchstart, function (e) {
202                 e.stopPropagation();
203                 isMoving = false;
204                 startTime = new Date();
205                 $(this).addClass("touching");
206             });
207             $(selector).bind(eventNames.touchmove, function (e) {
208                 e.stopPropagation();
209                 isMoving = true;
210             });
211             $(selector).bind(eventNames.touchend, function (e) {
212                 e.stopPropagation();
213                 var $me = $(this);
214                 if ($me.hasClass("disabled")) {
215                     return;
216                 }
217                 $me.removeClass("touching");
218                 var duration = new Date() - startTime;
219                 if (!isMoving && duration < 1000) {
220                     $me.addClass("clicking");
221                     func.call(this, e);
222                     setTimeout(function () {
223                         $me.removeClass("clicking");
224                     }, 500);
225                 }
226             });
227         },
228         _restore: function () {
229             var me = this;
230             me.toIndex(me.currentIndex);
231         },
232         _getTouchPosition: function (event) {
233             try {
234                 var touch = event.targetTouches[0];
235                 if (touch == undefined) {
236                     return null;
237                 }
238                 return {
239                     x: touch.pageX,
240                     y: touch.pageY
241                 };
242             } catch (ex) {
243                 return {
244                     x: event.clientX,
245                     y: event.clientY
246                 };
247             }
248         }
249     };
250 
251 })();

遇到的问题:

1、 性能问题。在某些手机浏览器中(比如腾讯的QQ浏览器,微信自带的浏览器,主要是移动设备),图片切换的时候很卡。Chrome、Safari和大部分手机浏览器中都能正常的执行。但这确确实实是一个问题。猜想是没有阻止事件传播。于是加了e.stopPropagation(),但是没有解决,也没有发现问题的所在。纠结了很久,然后漫无目的的试了一下e.preventDefault(),没想到这个方法就可以了。赶紧看了一下他们之间的差别。我就不讲了,直接献上链接:http://blog.csdn.net/woshixuye/article/details/7422985

2、 在移动设备端,由于监听了touch事件,并阻止了默认的行为。因而在想上下滚动页面内容的时候,当你touch在图片上的时候,页面无法滑动的。后面换了一个思路,在start的时候不阻止事件,而是在move的时候,先判定滑动方向,在阻止事件。

3、图片拖动问题。主要是在PC端,鼠标拖动图片的时候,浏览器就直接把图片拖出来了,新建一个窗口打开图片或者搜索图片的信息。后面在img标签上加了一个 draggable="false",可以解决Chrome的拖动问题。但是在IE10以下的浏览器和Firefox中,还是有这个问题,我尝试了ondrag 和onselect的相关事件来阻止拖动,然而却发现没什么用。现在也没有能够解决这个问题。还好项目主要是针对移动端。如果大家有什么方法的话,不妨传授一下,感激不尽。    //todo

 当然,光有js肯定是不行的,还需要html和css的配合。下面是html代码:

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title>ImagesScroller Test</title>
 5     <style type="text/css">
 6         body {
 7             margin: 0;
 8             padding: 0;
 9         }
10          div.content {
11              text-align: center;
12              padding-top: 100px;
13              padding-bottom: 1000px; 
14          }
15         div.imagescrollerwrapper {
16             overflow: hidden;
17             background: #ccc;
18             margin: auto;
19             width: 40%;
20         }
21         ul.pictures-wrapper {
22             display: block;
23             padding: 0;
24             margin: 0;
25             height: 150px;
26             overflow: hidden;
27             position: relative;
28             list-style-type: none;
29         }
30         ul.pictures-wrapper li {
31             float: left;
32             display: block;
33             padding: 0;
34             margin: 0;
35             vertical-align: baseline;
36         }
37         ul.pictures-wrapper li img {
38             width: 100%;
39             height: 100%;
40         }
41     </style>
42     <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
43     <script src="ImagesScroller.js"></script>
44     <script type="text/javascript">
45         $(function() {
46             var viewer = new ImagesScroller("#divPictureScroller");
47             viewer.onChange = function () {
48                 $("#divImageIndexInfo").html((viewer.currentIndex + 1) + " / " + viewer.count);
49             };
50             viewer.init();
51         });
52     </script>
53 </head>
54     <body>
55         <div class="content">
56             <div class="imagescrollerwrapper" id="divPictureScroller">
57                 <ul class="pictures-wrapper">
58                     <li>
59                         <img draggable="false" alt="Image01" title="Image01" src="http://img4.duitang.com/uploads/item/201408/15/20140815022116_AahUY.thumb.700_0.png">
60                     </li>
61                     <li>
62                         <img draggable="false" alt="Image02" title="Image02" src="http://tupian.qqjay.com/u/2012/1018/13_193427_10.jpg">
63                     </li>
64                     <li>
65                         <img draggable="false" alt="Image03" title="Image03" src="http://img4.duitang.com/uploads/item/201202/24/20120224124613_ndzQh.jpg">
66                     </li>
67                     <li>
68                         <img draggable="false" alt="Image04" title="Image04" src="http://pic4.zhongsou.com/image/4805cee61cdc2021563.jpg">
69                     </li>
70                 </ul>
71             </div>
72             <div id="divImageIndexInfo">
73                 1 / 4
74             </div>
75         </div>
76     </body>
77 </html>

 代码还有很多需要优化的,比如自动轮播,图片的循环,切换效果... 代码也有一些问题,但是现在没什么时间,等以后有时间再慢慢来完善吧...

 希望大家多多把你们的意见或建议和我分享。

 demo下载地址:https://files.cnblogs.com/files/AaronAndJoe/ImageViewer.rar【链接失效,可以直接copy代码使用】

原文地址:https://www.cnblogs.com/AaronAndJoe/p/4521284.html