图片预览插件的使用

2017-10-19 · xiejiahe

找到了3款图片预览插件进行了比较, 主要是用在移动端

Viewer 官网

Viewer 支持手机端和PC端, 有JQuery版本和js版本, 手势放大缩小不太好用,他是固定比例的

photoswipe 官网

photoswipe 支持手机端和PC端, github有1.5K star, 这个配置很复杂,在移动端体验上不太好。

mui 官网

mui 一个前端框架,图片预览支持手机端和PC端, github接近7.3k star。 使用感觉后比前2个好用, mui是基于移动端框架的,更接近原生

mui demo 我已经详细写了注释了,应该很好理解

点击这里在线预览

或者扫一扫下面二维码

完整仓库代码

下面是html, 遇到了一个坑,就是所有a标签阻止了默认事件无法跳转。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>图片预览支持手机端PC端</title>
	<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no, minimum-scale=1.0">
	<meta name="apple-mobile-web-app-capable" content="yes">
	<meta name="apple-mobile-web-app-status-bar-style" content="black">
	<link href="https://cdn.bootcss.com/mui/3.4.0/css/mui.min.css" rel="stylesheet">
	<style>
		/* 自己定义的css */
		* {
			margin: 0;
			padding: 0;
		}
		img {
			width: 100%
		}

		/*
		 *  下面这些样式不包含在mui里面,可以根据你的需求是改, 必须
		 */
		.mui-preview-image.mui-fullscreen {
			position: fixed;
			z-index: 20;
			background-color: #000;
		}
		.mui-preview-header,
		.mui-preview-footer {
			position: absolute;
			width: 100%;
			left: 0;
			z-index: 10;
		}
		.mui-preview-header {
			height: 44px;
			top: 0;
		}
		.mui-preview-footer {
			height: 50px;
			bottom: 0px;
		}
		.mui-preview-header .mui-preview-indicator {
			display: block;
			line-height: 25px;
			color: #fff;
			text-align: center;
			margin: 15px auto 4;
			width: 70px;
			background-color: rgba(0, 0, 0, 0.4);
			border-radius: 12px;
			font-size: 16px;
		}
		.mui-preview-image {
			display: none;
			-webkit-animation-duration: 0.5s;
			animation-duration: 0.5s;
			-webkit-animation-fill-mode: both;
			animation-fill-mode: both;
		}
		.mui-preview-image.mui-preview-in {
			-webkit-animation-name: fadeIn;
			animation-name: fadeIn;
		}
		.mui-preview-image.mui-preview-out {
			background: none;
			-webkit-animation-name: fadeOut;
			animation-name: fadeOut;
		}
		.mui-preview-image.mui-preview-out .mui-preview-header,
		.mui-preview-image.mui-preview-out .mui-preview-footer {
			display: none;
		}
		.mui-zoom-scroller {
			position: absolute;
			display: -webkit-box;
			display: -webkit-flex;
			display: flex;
			-webkit-box-align: center;
			-webkit-align-items: center;
			align-items: center;
			-webkit-box-pack: center;
			-webkit-justify-content: center;
			justify-content: center;
			left: 0;
			right: 0;
			bottom: 0;
			top: 0;
			width: 100%;
			height: 100%;
			margin: 0;
			-webkit-backface-visibility: hidden;
		}
		.mui-zoom {
			-webkit-transform-style: preserve-3d;
			transform-style: preserve-3d;
		}
		.mui-slider .mui-slider-group .mui-slider-item img {
			width: auto;
			height: auto;
			max-width: 100%;
			max-height: 100%;
		}
		.mui-android-4-1 .mui-slider .mui-slider-group .mui-slider-item img {
			width: 100%;
		}
		.mui-android-4-1 .mui-slider.mui-preview-image .mui-slider-group .mui-slider-item {
			display: inline-table;
		}
		.mui-android-4-1 .mui-slider.mui-preview-image .mui-zoom-scroller img {
			display: table-cell;
			vertical-align: middle;
		}
		.mui-preview-loading {
			position: absolute;
			width: 100%;
			height: 100%;
			top: 0;
			left: 0;
			display: none;
		}
		.mui-preview-loading.mui-active {
			display: block;
		}
		.mui-preview-loading .mui-spinner-white {
			position: absolute;
			top: 50%;
			left: 50%;
			margin-left: -25px;
			margin-top: -25px;
			height: 50px;
			width: 50px;
		}
		.mui-preview-image img.mui-transitioning {
			-webkit-transition: -webkit-transform 0.5s ease, opacity 0.5s ease;
			transition: transform 0.5s ease, opacity 0.5s ease;
		}
		@-webkit-keyframes fadeIn {
			0% {
				opacity: 0;
			}
			100% {
				opacity: 1;
			}
		}
		@keyframes fadeIn {
			0% {
				opacity: 0;
			}
			100% {
				opacity: 1;
			}
		}
		@-webkit-keyframes fadeOut {
			0% {
				opacity: 1;
			}
			100% {
				opacity: 0;
			}
		}
		@keyframes fadeOut {
			0% {
				opacity: 1;
			}
			100% {
				opacity: 0;
			}
		}
		.mui-content p img {
			max-width: 100%;
			height: auto;
		}
	</style>
</head>
<body>

<!-- 
   把图片包含在 .mui-content 里面
   data-preview-src=""  必须指定不管是否为空,意思是点击预览后图片的地址,他默认是src的图片, 做缩略图有用
   
   data-preview-group="1" 代表组,同一个组当点击预览后可以滑动浏览下一张
 -->

<div class="mui-content">
	<img src="./images/2.jpg" data-preview-src="" data-preview-group="1" draggable="false">
	<img src="./images/1.jpg" data-preview-src="" data-preview-group="1" draggable="false">
</div>
</body>
<!-- 引入mui核心库 -->
<script src="https://cdn.bootcss.com/mui/3.4.0/js/mui.min.js"></script>
<!-- 引入mui缩放插件 -->
<script src="./js/mui.zoom.js"></script>
<!-- 引入mui图片预览插件 -->
<script src="./js/mui.previewimage.js"></script>
<script>
	// 只要执行这个就好了
	mui.previewImage();
</script>
</html>

photoswipe

在线预览

或者扫一扫二维码

完整仓库代码

html代码, 遇到一个坑是在SPA应用预览图片后会在URL追加参数#&gid=1&pid=1

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>photoswipe图片预览</title>
	<link rel='stylesheet' href='./css/photoswipe.min.css?v=4.1.1'>
	<link rel='stylesheet' href='./css/default-skin.min.css?v=4.1.1'>
	<style>
        * {
            margin: 0;
            padding: 0;
        }

		.my-gallery {
			width: 100%;
			float: left;
		}
		.my-gallery img {
			width: 100%;
			height: auto;
		}
		.my-gallery figure {
			display: block;
			float: left;
			margin: 0 5px 5px 0;
			width: 150px;
		}
		.my-gallery figcaption {
			display: none;
		}
	</style>
</head>
<body>


<div class="my-gallery" itemscope itemtype="http://schema.org/ImageGallery">
    <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
        <!-- data-size 是图片的大小必须填,不然有坑 -->
        <!-- a链接是原图地址, img是小图地址 -->
		<a href="./images/da.jpg" itemprop="contentUrl" data-size="1024x1024">
			<img src="./images/xiao.jpg" itemprop="thumbnail">
		</a>
	</figure>
</div>


<!-- 这个就是点击后预览的组件,包括按钮什么的 -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
	<div class="pswp__bg"></div>
	<div class="pswp__scroll-wrap">
		<div class="pswp__container">
			<div class="pswp__item">
			</div>
			<div class="pswp__item">
			</div>
			<div class="pswp__item">
			</div>
		</div>
		<div class="pswp__ui pswp__ui--hidden">
			<div class="pswp__top-bar">
				<div class="pswp__counter">
				</div>
				<button class="pswp__button pswp__button--close"></button>
				<div class="pswp__preloader">
					<div class="pswp__preloader__icn">
						<div class="pswp__preloader__cut">
							<div class="pswp__preloader__donut">
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
				<div class="pswp__share-tooltip">
				</div>
			</div>
			</button>
			</button>
			<div class="pswp__caption">
				<div class="pswp__caption__center">
				</div>
			</div>
		</div>
	</div>
</div>

<script src='./js/photoswipe.min.js?v=4.1.1'></script>
<script src='./js/photoswipe-ui-default.min.js?v=4.1.1'></script>
<script>
var initPhotoSwipeFromDOM = function(gallerySelector) {
    var parseThumbnailElements = function(el) {
        var thumbElements = el.childNodes,
            numNodes = thumbElements.length,
            items = [],
            figureEl,
            linkEl,
            size,
            item;
        for(var i = 0; i < numNodes; i++) {
            figureEl = thumbElements[i];
            if(figureEl.nodeType !== 1) {
                continue;
            }
            linkEl = figureEl.children[0];

            size = linkEl.getAttribute('data-size').split('x');
            item = {
                src: linkEl.getAttribute('href'),
                w: parseInt(size[0], 10),
                h: parseInt(size[1], 10)
            };
            if(figureEl.children.length > 1) {
                item.title = figureEl.children[1].innerHTML; 
            }
            if(linkEl.children.length > 0) {
                item.msrc = linkEl.children[0].getAttribute('src');
            } 

            item.el = figureEl;
            items.push(item);
        }
        return items;
    };
    var closest = function closest(el, fn) {
        return el && ( fn(el) ? el : closest(el.parentNode, fn) );
    };
    var onThumbnailsClick = function(e) {
        e = e || window.event;
        e.preventDefault ? e.preventDefault() : e.returnValue = false;
        var eTarget = e.target || e.srcElement;
        var clickedListItem = closest(eTarget, function(el) {
            return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
        });
        if(!clickedListItem) {
            return;
        }
        var clickedGallery = clickedListItem.parentNode,
            childNodes = clickedListItem.parentNode.childNodes,
            numChildNodes = childNodes.length,
            nodeIndex = 0,
            index;
        for (var i = 0; i < numChildNodes; i++) {
            if(childNodes[i].nodeType !== 1) { 
                continue; 
            }
            if(childNodes[i] === clickedListItem) {
                index = nodeIndex;
                break;
            }
            nodeIndex++;
        }
        if(index >= 0) {
            openPhotoSwipe( index, clickedGallery );
        }
        return false;
    };
    var photoswipeParseHash = function() {
        var hash = window.location.hash.substring(1),
        params = {};
        if(hash.length < 5) {
            return params;
        }

        var vars = hash.split('&');
        for (var i = 0; i < vars.length; i++) {
            if(!vars[i]) {
                continue;
            }
            var pair = vars[i].split('=');  
            if(pair.length < 2) {
                continue;
            }           
            params[pair[0]] = pair[1];
        }

        if(params.gid) {
            params.gid = parseInt(params.gid, 10);
        }

        return params;
    };

    var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
        var pswpElement = document.querySelectorAll('.pswp')[0],
            gallery,
            options,
            items;

        items = parseThumbnailElements(galleryElement);
        options = {
            galleryUID: galleryElement.getAttribute('data-pswp-uid'),
            getThumbBoundsFn: function(index) {
                var thumbnail = items[index].el.getElementsByTagName('img')[0],
                    pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
                    rect = thumbnail.getBoundingClientRect(); 
                return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
            }
        };
        if(fromURL) {
            if(options.galleryPIDs) {
                for(var j = 0; j < items.length; j++) {
                    if(items[j].pid == index) {
                        options.index = j;
                        break;
                    }
                }
            } else {
                options.index = parseInt(index, 10) - 1;
            }
        } else {
            options.index = parseInt(index, 10);
        }
        if( isNaN(options.index) ) {
            return;
        }
        if(disableAnimation) {
            options.showAnimationDuration = 0;
        }
        gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
        gallery.init();
    };
    var galleryElements = document.querySelectorAll( gallerySelector );
    for(var i = 0, l = galleryElements.length; i < l; i++) {
        galleryElements[i].setAttribute('data-pswp-uid', i+1);
        galleryElements[i].onclick = onThumbnailsClick;
    }
    var hashData = photoswipeParseHash();
    if(hashData.pid && hashData.gid) {
        openPhotoSwipe( hashData.pid ,  galleryElements[ hashData.gid - 1 ], true, true );
    }
};
// 执行函数
initPhotoSwipeFromDOM('.my-gallery');
</script>
</body>
</html>

关于viewer.js

这里有详细介绍

JavaScriptHTML
原创文章,转载请注明出处。