PhotoSwipe-一个好用的图片放大缩小插件
通过GitHub 下载PhotoSwipe https://github.com/dimsemenov/PhotoSwipe 相关的库
<link rel="stylesheet" href="css/photoswipe.css" /> <link rel="stylesheet" href="css/default-skin/default-skin.css" /> <script src="js/photoswipe.min.js"></script> <script src="js/photoswipe-ui-default.js"></script> <script src="js/connect.js"></script> //引入相关的css和js文件及皮肤
connect.js
1 document.writeln("<!-- Root element of PhotoSwipe. Must have class pswp. -->"); 2 document.writeln("<div class=\"pswp\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">"); 3 document.writeln(""); 4 document.writeln(" <!-- Background of PhotoSwipe."); 5 document.writeln(" It\'s a separate element as animating opacity is faster than rgba(). -->"); 6 document.writeln(" <div class=\"pswp__bg\"><\/div>"); 7 document.writeln(""); 8 document.writeln(" <!-- Slides wrapper with overflow:hidden. -->"); 9 document.writeln(" <div class=\"pswp__scroll-wrap\">"); 10 document.writeln(""); 11 document.writeln(" <!-- Container that holds slides."); 12 document.writeln(" PhotoSwipe keeps only 3 of them in the DOM to save memory."); 13 document.writeln(" Don\'t modify these 3 pswp__item elements, data is added later on. -->"); 14 document.writeln(" <div class=\"pswp__container\">"); 15 document.writeln(" <div class=\"pswp__item\"><\/div>"); 16 document.writeln(" <div class=\"pswp__item\"><\/div>"); 17 document.writeln(" <div class=\"pswp__item\"><\/div>"); 18 document.writeln(" <\/div>"); 19 document.writeln(""); 20 document.writeln(" <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->"); 21 document.writeln(" <div class=\"pswp__ui pswp__ui--hidden\">"); 22 document.writeln(""); 23 document.writeln(" <div class=\"pswp__top-bar\">"); 24 document.writeln(""); 25 document.writeln(" <!-- Controls are self-explanatory. Order can be changed. -->"); 26 document.writeln(""); 27 document.writeln(" <div class=\"pswp__counter\"><\/div>"); 28 document.writeln(""); 29 document.writeln(" <button class=\"pswp__button pswp__button--close\" title=\"Close (Esc)\"><\/button>"); 30 document.writeln(""); 31 document.writeln(""); 32 document.writeln(" <button class=\"pswp__button pswp__button--fs\" title=\"Toggle fullscreen\"><\/button>"); 33 document.writeln(""); 34 document.writeln(" <button class=\"pswp__button pswp__button--zoom\" title=\"Zoom in\/out\"><\/button>"); 35 document.writeln(""); 36 document.writeln(" <!-- Preloader demo http:\/\/codepen.io\/dimsemenov\/pen\/yyBWoR -->"); 37 document.writeln(" <!-- element will get class pswp__preloader--active when preloader is running -->"); 38 document.writeln(" <div class=\"pswp__preloader\">"); 39 document.writeln(" <div class=\"pswp__preloader__icn\">"); 40 document.writeln(" <div class=\"pswp__preloader__cut\">"); 41 document.writeln(" <div class=\"pswp__preloader__donut\"><\/div>"); 42 document.writeln(" <\/div>"); 43 document.writeln(" <\/div>"); 44 document.writeln(" <\/div>"); 45 document.writeln(" <\/div>"); 46 document.writeln(""); 47 document.writeln(" <div class=\"pswp__share-modal pswp__share-modal--hidden pswp__single-tap\">"); 48 document.writeln(" <div class=\"pswp__share-tooltip\"><\/div>"); 49 document.writeln(" <\/div>"); 50 document.writeln(""); 51 document.writeln(" <button class=\"pswp__button pswp__button--arrow--left\" title=\"Previous (arrow left)\">"); 52 document.writeln(" <\/button>"); 53 document.writeln(""); 54 document.writeln(" <button class=\"pswp__button pswp__button--arrow--right\" title=\"Next (arrow right)\">"); 55 document.writeln(" <\/button>"); 56 document.writeln(""); 57 document.writeln(" <div class=\"pswp__caption\">"); 58 document.writeln(" <div class=\"pswp__caption__center\"><\/div>"); 59 document.writeln(" <\/div>"); 60 document.writeln(""); 61 document.writeln(" <\/div>"); 62 document.writeln(""); 63 document.writeln(" <\/div>"); 64 document.writeln(""); 65 document.writeln("<\/div>"); 66 //因为作者没有把相关的div放进js里,所以这边通过打印,具体可以观看官方文档得知为什么要这么做。 67 (function() { 68 69 var initPhotoSwipeFromDOM = function(gallerySelector) { 70 71 var parseThumbnailElements = function(el) { 72 var thumbElements = el.childNodes, 73 numNodes = thumbElements.length, 74 items = [], 75 el, 76 childElements, 77 thumbnailEl, 78 size, 79 item; 80 81 for(var i = 0; i < numNodes; i++) { 82 el = thumbElements[i]; 83 84 // include only element nodes 85 if(el.nodeType !== 1) { 86 continue; 87 } 88 89 childElements = el.children; 90 91 size = el.getAttribute('data-size').split('x'); 92 93 // create slide object 94 item = { 95 src: el.getAttribute('href'), 96 w: parseInt(size[0], 10), 97 h: parseInt(size[1], 10), 98 author: el.getAttribute('data-author') 99 }; 100 101 item.el = el; // save link to element for getThumbBoundsFn 102 103 if(childElements.length > 0) { 104 item.msrc = childElements[0].getAttribute('src'); // thumbnail url 105 if(childElements.length > 1) { 106 item.title = childElements[1].innerHTML; // caption (contents of figure) 107 } 108 } 109 110 111 var mediumSrc = el.getAttribute('data-med'); 112 if(mediumSrc) { 113 size = el.getAttribute('data-med-size').split('x'); 114 // "medium-sized" image 115 item.m = { 116 src: mediumSrc, 117 w: parseInt(size[0], 10), 118 h: parseInt(size[1], 10) 119 }; 120 } 121 // original image 122 item.o = { 123 src: item.src, 124 w: item.w, 125 h: item.h 126 }; 127 128 items.push(item); 129 } 130 131 return items; 132 }; 133 134 // find nearest parent element 135 var closest = function closest(el, fn) { 136 return el && ( fn(el) ? el : closest(el.parentNode, fn) ); 137 }; 138 139 var onThumbnailsClick = function(e) { 140 e = e || window.event; 141 e.preventDefault ? e.preventDefault() : e.returnValue = false; 142 143 var eTarget = e.target || e.srcElement; 144 145 var clickedListItem = closest(eTarget, function(el) { 146 return el.tagName === 'A'; 147 }); 148 149 if(!clickedListItem) { 150 return; 151 } 152 153 var clickedGallery = clickedListItem.parentNode; 154 155 var childNodes = clickedListItem.parentNode.childNodes, 156 numChildNodes = childNodes.length, 157 nodeIndex = 0, 158 index; 159 160 for (var i = 0; i < numChildNodes; i++) { 161 if(childNodes[i].nodeType !== 1) { 162 continue; 163 } 164 165 if(childNodes[i] === clickedListItem) { 166 index = nodeIndex; 167 break; 168 } 169 nodeIndex++; 170 } 171 172 if(index >= 0) { 173 openPhotoSwipe( index, clickedGallery ); 174 } 175 return false; 176 }; 177 178 var photoswipeParseHash = function() { 179 var hash = window.location.hash.substring(1), 180 params = {}; 181 182 if(hash.length < 5) { // pid=1 183 return params; 184 } 185 186 var vars = hash.split('&'); 187 for (var i = 0; i < vars.length; i++) { 188 if(!vars[i]) { 189 continue; 190 } 191 var pair = vars[i].split('='); 192 if(pair.length < 2) { 193 continue; 194 } 195 params[pair[0]] = pair[1]; 196 } 197 198 if(params.gid) { 199 params.gid = parseInt(params.gid, 10); 200 } 201 202 return params; 203 }; 204 205 var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) { 206 var pswpElement = document.querySelectorAll('.pswp')[0], 207 gallery, 208 options, 209 items; 210 211 items = parseThumbnailElements(galleryElement); 212 213 // define options (if needed) 214 options = { 215 216 galleryUID: galleryElement.getAttribute('data-pswp-uid'), 217 218 getThumbBoundsFn: function(index) { 219 // See Options->getThumbBoundsFn section of docs for more info 220 var thumbnail = items[index].el.children[0], 221 pageYScroll = window.pageYOffset || document.documentElement.scrollTop, 222 rect = thumbnail.getBoundingClientRect(); 223 224 return {x:rect.left, y:rect.top + pageYScroll, w:rect.width}; 225 }, 226 227 addCaptionHTMLFn: function(item, captionEl, isFake) { 228 if(!item.title) { 229 captionEl.children[0].innerText = ''; 230 return false; 231 } 232 captionEl.children[0].innerHTML = item.title + '<br/><small>Photo: ' + item.author + '</small>'; 233 return true; 234 } 235 236 }; 237 238 239 if(fromURL) { 240 if(options.galleryPIDs) { 241 // parse real index when custom PIDs are used 242 // http://photoswipe.com/documentation/faq.html#custom-pid-in-url 243 for(var j = 0; j < items.length; j++) { 244 if(items[j].pid == index) { 245 options.index = j; 246 break; 247 } 248 } 249 } else { 250 options.index = parseInt(index, 10) - 1; 251 } 252 } else { 253 options.index = parseInt(index, 10); 254 } 255 256 // exit if index not found 257 if( isNaN(options.index) ) { 258 return; 259 } 260 261 262 263 var radios = document.getElementsByName('gallery-style'); 264 for (var i = 0, length = radios.length; i < length; i++) { 265 if (radios[i].checked) { 266 if(radios[i].id == 'radio-all-controls') { 267 268 } else if(radios[i].id == 'radio-minimal-black') { 269 options.mainClass = 'pswp--minimal--dark'; 270 options.barsSize = {top:0,bottom:0}; 271 options.captionEl = false; 272 options.fullscreenEl = false; 273 options.shareEl = false; 274 options.bgOpacity = 0.85; 275 options.tapToClose = true; 276 options.tapToToggleControls = false; 277 } 278 break; 279 } 280 } 281 282 if(disableAnimation) { 283 options.showAnimationDuration = 0; 284 } 285 286 // Pass data to PhotoSwipe and initialize it 287 gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options); 288 289 // see: http://photoswipe.com/documentation/responsive-images.html 290 var realViewportWidth, 291 useLargeImages = false, 292 firstResize = true, 293 imageSrcWillChange; 294 295 gallery.listen('beforeResize', function() { 296 297 var dpiRatio = window.devicePixelRatio ? window.devicePixelRatio : 1; 298 dpiRatio = Math.min(dpiRatio, 2.5); 299 realViewportWidth = gallery.viewportSize.x * dpiRatio; 300 301 302 if(realViewportWidth >= 1200 || (!gallery.likelyTouchDevice && realViewportWidth > 800) || screen.width > 1200 ) { 303 if(!useLargeImages) { 304 useLargeImages = true; 305 imageSrcWillChange = true; 306 } 307 308 } else { 309 if(useLargeImages) { 310 useLargeImages = false; 311 imageSrcWillChange = true; 312 } 313 } 314 315 if(imageSrcWillChange && !firstResize) { 316 gallery.invalidateCurrItems(); 317 } 318 319 if(firstResize) { 320 firstResize = false; 321 } 322 323 imageSrcWillChange = false; 324 325 }); 326 327 gallery.listen('gettingData', function(index, item) { 328 if( useLargeImages ) { 329 item.src = item.o.src; 330 item.w = item.o.w; 331 item.h = item.o.h; 332 } else { 333 item.src = item.m.src; 334 item.w = item.m.w; 335 item.h = item.m.h; 336 } 337 }); 338 339 gallery.init(); 340 }; 341 342 // select all gallery elements 343 var galleryElements = document.querySelectorAll( gallerySelector ); 344 for(var i = 0, l = galleryElements.length; i < l; i++) { 345 galleryElements[i].setAttribute('data-pswp-uid', i+1); 346 galleryElements[i].onclick = onThumbnailsClick; 347 } 348 349 // Parse URL and open gallery if it contains #&pid=3&gid=1 350 var hashData = photoswipeParseHash(); 351 if(hashData.pid && hashData.gid) { 352 openPhotoSwipe( hashData.pid, galleryElements[ hashData.gid - 1 ], true, true ); 353 } 354 }; 355 356 initPhotoSwipeFromDOM('.photoswipe'); 357 358 })();
我们通过名为photoswipe的class通知要用到的子元素。
a里的图片为放大之后的图片,img里的图片为可实际查看的小图,data-size为要放大的图片大小。
1 <div class="photoswipe"> 2 <a href="img/1-max.jpeg" data-size='1000x1000' > 3 <img src="img/1-450.jpeg"/> 4 </a> 5 <a href="http://img3.imgtn.bdimg.com/it/u=4166721891,1503444760&fm=26&gp=0.jpg" data-size='1000x1000' > 6 <img src="http://img3.imgtn.bdimg.com/it/u=4166721891,1503444760&fm=26&gp=0.jpg"/> 7 </a> 8 <a href="http://www.91danji.com/attachments/201511/19/10/24kf5fidw.jpg" data-size='1000x1000' > 9 <img src="http://www.91danji.com/attachments/201511/19/10/24kf5fidw.jpg"/> 10 </a> 11 </div>
拓展:因项目需要,以及通过后台渲染出的图片大小或外链的图片,总不可能一个个设置data-size,于是用jQuery配合js写了几段代码。
1 $(document).ready(function(){ //如果认为代码写的很乱可以自行修改 2 var pic=$("[data-size]"); 3 pic.each(function(){ 4 var _this = $(this); 5 var images = new Image(); //实例化图片 6 images.src = _this.find('img').attr('src'); //获取小图的链接 进行计算 7 images.onload = function(){ //当图片加载完 8 var tpW = images.width; //图片实际宽度 9 var tpH = images.height //图片实际高度 10 var winW = $(window).width(); //浏览器实际宽度 11 var winH = $(window).height(); //浏览器实际高度 12 var tpRatio = Math.min((winW/tpW),(winH/tpH)); 13 var getW = tpW * tpRatio; 14 var getH = tpH * tpRatio; // 屏幕高度 * 图片宽度 / 图片高度 15 _this.attr("data-size",parseInt(getW,10)+"x"+parseInt(getH,10)); 16 } 17 }); 18 });
该插件是自适应的,具体可以通过谷歌浏览器查看该插件的炫酷之处。