PicView一个依赖JQuery的图片预览插件

PicView

A jQuery plugin to support mobile and PC image display
一个支持移动端和PC端的图片展示jQuery插件

View

PC展示
手机模拟

Setup

# install dependencies
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<script src="/picview.js"></script>

use

# use
HTML tag Attributes: <El data-ui="picview"></El>
OR
$('your EL').PicView()

# Get the bound instance
# 获取绑定的图片显示实例 
var elPicView = $('your EL').data('PicView');

# Get a bound list of images for the instance
# 获取显示的图片列表
var dataList = elPicView.getData();

# Setting up a display image list is dynamic
# 设置显示图片列表是动态的
var dataList = elPicView.setDataIsChange(true);

# If it is to upload pictures, and upload events triggered by the 
# picture, then set to display the default picture address needs to be removed
# 如果是上传图片,并且是通过图片触发上传事件,那么设置显示需要剔除的默认图片地址
var dataList = elPicView.setDefaultImg(true);

# Destroy the instance
# 销毁实例
var dataList = elPicView.destroy();

JS代码

(function ($) {
  'use strict';
  // 全局变量声明
  var name = 'PicView'; // modal name
  var globalId = 0; // 实例初始ID
  var viewMode_html = '<div id="{0}" class="PicViewBox" style="height:{2}px">\
  <div class="imgBox">\
      <figure class="figure">\
        <img class="imgView" src="{1}" style="max-height: {2}px;">\
      </figure>\
  </div>\
  <!--<div class="loader--audioWave"></div>-->\
  <button title="关闭" class="imgViewbtn close" type="button"></button>\
  <button title="上一张" class="imgViewbtn prev" type="button"></button>\
  <button title="下一张" class="imgViewbtn next" type="button"></button>\
</div>'; // 模板

  // The PicView modal class
  var PicView = function (element) {
    // 当前实例的名称
    this._name = name + globalId;
    // 当前实例的ID
    this._id = globalId;
    // 当前实例的DOM对象
    this._$ = $(element);
    // 当前实例的图片数量
    this._imgMaxLength = 0;
    // 当前实例的图片数据 Array
    this._imgData = null;
    // 当前实例打开图片预览的位置
    this._viewIndex = 0;
    // 当前实例图片预览的DOM对象
    this._$viewBox = null;
    // 当前实例图片预览的DOM对象是否显示
    this._viewBoxIsDisplay = false;
    // 当前实例的图片容器DOM
    this._$img = null;
    // 当前实例的图片是否会变化
    this._dataIsChange = false;
    // 当前实例的排除显示图片路径; 用于处理以图片触发上传的情况
    this._defaultImgSrc = '';
    // 公用初始化
    this.init();
  };

  // 添加原型方法
  PicView.prototype = {
    // 上一张控制器
    prev: function () {
      this._viewIndex > 0 ? this._viewIndex-- : (this._viewIndex = this._imgMaxLength);
      this.view();
      return this;
    },
    // 下一张控制器
    next: function () {
      this._viewIndex < this._imgMaxLength ? this._viewIndex++ : (this._viewIndex = 0);
      this.view();
      return this;
    },
    // 显示
    view: function (path) {
      this._$img.attr('src', path ? path : this._imgData[this._viewIndex]);
      return this;
    },
    // 格式化
    format: function () {
      if (arguments.length == 0){
        return null;
      }
      var str = arguments[0],
        params = arguments[1],
        al = params.length - 1;
      do {
        var re = new RegExp('\\{' + al + '\\}', 'gm');
        str = str.replace(re, params[al]);
        al--;
      } while (al > -1);
      return str;
    },
    // 初始化
    init: function () {
      var _this = this,
        view_HTML;
      // 初始化图片数据
      this.setData()
      // 初始化HTML标签
      view_HTML = this.format(viewMode_html, ['PicViewBox' + globalId, '/', window.innerHeight]);
      this._$viewBox = $(view_HTML);
      this._$img = this._$viewBox.find('img');
      $('body').append(this._$viewBox);
      // 图片点击事件
      this._$.on('click', 'img', function (e) {
        e.preventDefault();
        e.stopPropagation();
        // 获取当前图片的资源路径
        var imgPath = $(this).attr('src');
        if (imgPath !== _this.getDefaultImg()) {
          $('body').addClass('body_overflow');
          // 如果图片数据是变化的,重新设置展示图片数据
          _this.getDataIsChange() ? _this.setData() : '';
          // 设置当前展示图片的下标
          _this.setViewIndex($.inArray(imgPath, _this.getData()));
          // 展示图片
          _this.view(imgPath);
          // 如果图片展示DOM是隐藏的, 显示图片展示DOM
          if (!_this._viewBoxIsDisplay) {
            _this._$viewBox.css({
              'display': 'table',
              'top': window.scrollY
            }) //show(300);
            _this._viewBoxIsDisplay = true;
          }
        }
      })
      // 事件代理
      this._$viewBox.on('click', function (e) {
        e.preventDefault();
        e.stopPropagation();
        var className = e.target.className;
        switch (className) {
          // 上一图
          case 'imgViewbtn prev':
            _this.prev();
            break;
            // 下一图
          case 'imgViewbtn next':
            _this.next();
            break;
          case 'imgView':
            // 图片是下一图 
            _this.next();
            break;
            // 窗口点击
          default:
            $(this).hide(300);
            $('body').removeClass('body_overflow');
            _this._viewBoxIsDisplay = false;
            break;
        }
      });
      // 移动端支持
      var startPosition = {},
        deltaY, deltaX, endPosition = {};
      this._$viewBox.on('touchstart touchend', function (e) {
        e.preventDefault();
        e.stopPropagation();
        if (e.type === 'touchstart') {
          // 如果是开始事件 记录当前点的位置
          startPosition = {
            x: e.changedTouches[0].pageX,
            y: e.changedTouches[0].pageY
          }
        } else {
          // 否者记录结束位置的点
          endPosition = {
            x: e.changedTouches[0].pageX,
            y: e.changedTouches[0].pageY
          };
          var className = e.target.className;
          // 如果是图片
          if (className === 'imgView') {
            // 计算移动距离
            deltaY = endPosition.y - startPosition.y;
            deltaX = endPosition.x - startPosition.x;
            // 根据距离判断如何移动图片
            if (deltaX < 0) {
              _this.next();
            } else if (deltaX > 0) {
              _this.prev();
            } else {
              _this.next();
            }
          } else if (className === 'imgViewbtn prev') {
            _this.prev();
          } else if (className === 'imgViewbtn next') {
            _this.next();
          } else {
            $(this).hide(300);
            $('body').removeClass('body_overflow');
            _this._viewBoxIsDisplay = false;
          }
        }
      });
    },
    // 设置图片数据
    setData: function () {
      var _this = this;
      this._imgData = $.map(this._$.find('img'), function (item) {
        var src = $(item).attr('src'),
          className = $(item).attr('class');
        // 排除默认图片 和 模态内容展示图片
        if (src !== _this._defaultImgSrc && className !== 'imgView') {
          return src;
        }
      });
      // 设置图片数量
      this._imgMaxLength = this._imgData.length - 1;
      return this;
    },
    // 获取数据
    getData: function () {
      return this._imgData;
    },
    // 设置当前显示图片
    setViewIndex: function (index) {
      this._viewIndex = index;
      return this;
    },
    setDataIsChange: function (state) {
      this._dataIsChange = state;
      return this;
    },
    getDataIsChange: function () {
      return this._dataIsChange;
    },
    getDefaultImg: function () {
      return this._defaultImgSrc;
    },
    setDefaultImg: function (src) {
      this._defaultImgSrc = src;
      return this;
    },
    destroy: function () {
      this._$.off('click').removeData(name);
      this._$viewBox.off('click').off('touchstart touchend').remove(); 
      $('body').removeClass('body_overflow');
      delete this;
      return 'destroy'
    }
  }

  // 绑定图片展示插件
  $.fn.PicView = function () {
    // 循环初始化
    return this.each(function () {
      // 设置当前图片区域DOM
      var $this = $(this);
      // 获取当前DOM元素绑定的图片展示实例
      var data = $this.data(name);
      if (!data) {
        // 如果实例不存在,创建实例并保存到当前图片区域DOM
        $this.data(name, (data = new PicView(this)));
        // 实例ID增加
        globalId++;
      };
      return data;
    });
  };
  // 让图片展示插件构造函数指向图片展示类
  $.fn.PicView.Constructor = PicView;
  // 初始化
  $(function () {
    $('[data-ui="picview"]').PicView();
  });
})(jQuery);

CSS

[data-ui='picview'] img{
  cursor: zoom-in;
}
.body_overflow{
  overflow: hidden;
}
.PicViewBox {
  text-align: center;
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  cursor: zoom-out;
  z-index: 100000;
  background-color:  rgba(34,34,34,0.6);
  display: none;
}

.PicViewBox .imgBox{
  position: relative;
  display: table-cell;
  box-sizing: border-box;
  vertical-align: middle;
  margin: 0 auto;
  text-align: center;
  transition: transform 0.2s,opacity 0.2s;
  transform: scale(1);
  z-index: 100003;
}
.PicViewBox .imgBox .figure {
  margin: 0;
}
.PicViewBox .imgBox .figure .imgView{
  max-width: 100%;
  box-sizing: border-box;
  margin: 0 auto;
  cursor: pointer;
  user-select: none;
}
.PicViewBox .imgViewbtn {
  position: absolute;
  opacity: .65;
  margin: -55px 0 0;
  top: 50%;
  padding: 0;
  width: 90px;
  height: 110px;
  overflow: visible;
  cursor: pointer;
  background: 0 0;
  border: 0;
  -webkit-appearance: none;
  display: block;
  outline: 0;
  z-index: 100004;
  box-shadow: none;
  touch-action: manipulation;
  transition: opacity 0.2s;
}

.PicViewBox .imgViewbtn.prev{
  left:0;
}
.PicViewBox .imgViewbtn.next{
  right: 0;
}
.PicViewBox .imgViewbtn.close{
  right: 0;
  top:0;
  display: block;
  z-index: 100006;
}

.PicViewBox .imgViewbtn.prev:after, .PicViewBox .imgViewbtn.prev:before,
.PicViewBox .imgViewbtn.next:after, .PicViewBox .imgViewbtn.next:before,
.PicViewBox .imgViewbtn.close:after, .PicViewBox .imgViewbtn.close:before {
  position: absolute;
  content: '';
  opacity: .65;
  right: 50%;
  top: 50%;
  margin: -2px 0 0 -1px;
  width: 2px;
  height: 35px;
  background-color: #fff;
}

.PicViewBox .imgViewbtn.prev:after{
  transform: rotateZ(-45deg);
  -ms-transform:rotate(-45deg);
}
.PicViewBox .imgViewbtn.prev:before{
  margin: -27px 0 0 -1px;
  transform: rotateZ(45deg);
  -ms-transform:rotate(45deg);
}


.PicViewBox .imgViewbtn.next:after{
  transform: rotateZ(45deg);
  -ms-transform:rotate(45deg);
}
.PicViewBox .imgViewbtn.next:before{
  margin: -27px 0 0 -1px;
  transform: rotateZ(-45deg);
  -ms-transform:rotate(-45deg);
}

.PicViewBox .imgViewbtn.close:after, .PicViewBox .imgViewbtn.close:before{
  right: 40px;
  top: 65px;
}
.PicViewBox .imgViewbtn.close:after{
  transform: rotateZ(-45deg);
  -ms-transform:rotate(-45deg);
}
.PicViewBox .imgViewbtn.close:before{
  transform: rotateZ(45deg);
  -ms-transform:rotate(45deg);
}
.PicViewBox .imgViewbtn:hover,.PicViewBox .imgViewbtn:hover:after,.PicViewBox .imgViewbtn:hover:before{
  opacity: 1;
}
@media screen and (max-width: 900px) {
  .PicViewBox .imgViewbtn, .PicViewBox:after, .PicViewBox:before{
    display: none;
  }
}

NPM: https://www.npmjs.com/package/picview

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值