• 图片查看 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代码使用】

  • 相关阅读:
    Visual Studio 2012 中的ASP.NET Web API
    CentOS配置RPMForge软件源
    CentOS设置Mono环境变量
    使用 MEF 轻松实现云部署
    WiX 3.6——强大的.NET部署工具
    Redis应用场景
    How does it work in Mono's C# compiler?
    .NET程序员应该关注开源社区
    ASP.NET Web API和依赖注入
    [招聘帖]IT应用开发工程师
  • 原文地址:https://www.cnblogs.com/AaronAndJoe/p/4521284.html
Copyright © 2020-2023  润新知