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

2019-04-15 14:15发布

PicView

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

View

PC展示
手机模拟

Setup

# install dependencies

use

# use HTML tag Attributes: "picview"> 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 = '
'
; // 模板 // 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