預覽圖片是一個很經常使用的業務功能,好比掘金的預覽圖片功能,下面咱們就來模擬實現一個相似掘金的簡單預覽圖片功能(PS:最終實現動畫效果不如掘金,可自行擴展,還有就是嵌套的元素與掘金的方式也有區別)。css
首先新建一個js
文件,命名爲viewer.js
,而後在這個js
文件中,咱們來建立一個函數,命名爲ewViewer
。而後參數是一個圖片元素,能夠是jquery
的圖片元素,也能夠是js dom
圖片元素,咱們作一個判斷而後分別調用不一樣的實現方法,以下所示:html
function ewViewer(el){ //判斷頁面內容是否存在jquery而且傳入的el元素是不是一個jquerydom雲阿蘇 if(typeof window.jQuery !== 'undefined' && el instanceof window.jQuery){ this.previewjQuery(el); }else{ this.previewJS(el); } return this; } 複製代碼
實現的思路就是放置兩個元素,第一個是遮罩層元素,而且設置相關的樣式,子元素就是存放圖片的元素,咱們經過設置子元素的background-image
屬性來顯示圖片,代碼以下(每一步的註釋都解釋了):node
ewViewer.prototype.previewJS = function(el){ const isDom = function(e){ return typeof HTMLElement === 'object' ? e instanceof HTMLElement : e && typeof e === 'object' && e.nodeType === 1 && typeof e.nodeName === 'string' || e instanceof HTMLCollection || e instanceof NodeList; } // 若是傳入的不是一個dom元素則不執行後續代碼 if(!isDom(el))return; const curElement = document.querySelector('#preview-img-mask'); // 判斷當前遮罩層元素是否存在 if(!curElement){ // 建立遮罩層元素 const element = document.createElement('div'); // 克隆一個節點 const child = element.cloneNode(true); element.id = "preview-img-mask"; // 添加遮罩層元素樣式 element.style.cssText += `position:fixed;left:0;top:0;right:0;display:none;z-index:10000;overflow:auto;width:100%;height:100%;background:rgba(0,0,0,0.5)`; // 子元素添加樣式 child.style.cssText += `background-repeat: no-repeat;background-position: center;background-size: contain;`; element.appendChild(child); document.body.appendChild(element); } // 從新獲取遮罩層元素 const maskLayer = document.querySelector('#preview-img-mask'); // 判斷若是傳入的元素不是一個圖片元素則不執行以下代碼 if (el.length || el.tagName.toLowerCase().indexOf('img') === -1)return; // 獲取圖片的原始寬高 var imgNaturalWidth = el.naturalWidth, imgNaturalHeight = el.naturalHeight; // 移動端以及頁面縮放作判斷 const isMobile = window.navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i); // 獲取頁面寬度 const pageWidth = (function(){ return window.innerWidth; })(); // 若是當前頁面寬度小於600,或是移動端設備,則將原始寬高縮放0.6倍 if (isMobile || pageWidth <= 600) { imgNaturalWidth = imgNaturalWidth * 0.6; imgNaturalHeight = imgNaturalHeight * 0.6; } // 獲取頁面寬高 var viewportWidth = window.innerWidth, viewportHeight = window.innerHeight; // 獲取圖片元素的src路徑 var imgUrl = el.getAttribute('src'); // 顯示遮罩層 setTimeout(() => { maskLayer.style.display = "block"; },600); // 獲取遮罩層的子元素 var maskLayerDiv = maskLayer.querySelector('div'); // 設置子元素的樣式 maskLayerDiv.style.cssText += `background-image:url('${imgUrl}');background-size:${imgNaturalWidth}px ${imgNaturalHeight}px;width:0;height:0;`; // 判斷圖片寬度是否大於頁面寬度,而後設置子元素的寬度 if (imgNaturalWidth > viewportWidth) { maskLayerDiv.style.width = imgNaturalWidth + "px"; } else { maskLayerDiv.style.width = "100%"; } // 判斷圖片高度是否大於頁面高度,而後設置子元素的高度 if (imgNaturalHeight > viewportHeight) { maskLayerDiv.style.height = imgNaturalHeight + "px"; } else { maskLayerDiv.style.height = "100%"; } // 點擊遮罩層關閉預覽 maskLayer.onclick = function(){ setTimeout(() => { this.style.display = 'none'; },600); } } 複製代碼
實現思路相似js版本,只不過是有些代碼作了變換而已。jquery
ewViewer.prototype.previewjQuery = function(el){ const curElement = $('#preview-img-mask'); // 判斷若是頁面不存在遮罩層元素,則添加該元素 if (!curElement.length) { $(`<div id="preview-img-mask"><div></div></div>`).appendTo("body"); } // 獲取遮罩層元素 var maskLayer = $('#preview-img-mask'); // 設置遮罩層樣式 maskLayer.css({ position:'fixed', left:0, top:0, right:0, display:'none', 'z-index':10000, overflow:'auto', width:'100%', height:'100%', background:'rgba(0,0,0,0.5)' }); // 判斷傳入的若是不是一個img元素 if (el.prop('tagName').toLowerCase().indexOf('img') === -1)return; var imgNaturalWidth = el[0].naturalWidth, imgNaturalHeight = el[0].naturalHeight; // 移動端以及頁面縮放作判斷 const isMobile = window.navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i); // 獲取頁面寬度 const pageWidth = (function(){ return $(window).width(); })(); // 判斷頁面寬度是否小於600以及是不是移動端 if (isMobile || pageWidth <= 600) { imgNaturalWidth = imgNaturalWidth * 0.6; imgNaturalHeight = imgNaturalHeight * 0.6; } // 獲取頁面的寬高 var viewportWidth = $(window).width(), viewportHeight = $(window).height(); // 獲取圖片的路徑 var imgUrl = el.attr('src'); maskLayer.fadeIn(600); // 獲取子元素 var maskLayerDiv = maskLayer.children(); // 設置子元素樣式 maskLayerDiv.css({ "background-image": "url(" + imgUrl + ")", "background-size": imgNaturalWidth + "px " + imgNaturalHeight + "px", "width": "", "height": "", "background-repeat": "no-repeat", "background-position": "center", "background-size": "contain" }); // 判斷圖片原始寬高與頁面寬高,從而決定子元素的寬高 if (imgNaturalWidth > viewportWidth) { maskLayerDiv.css('width', imgNaturalWidth); } else { maskLayerDiv.css('width', '100%'); } if (imgNaturalHeight > viewportHeight) { maskLayerDiv.css('height', imgNaturalHeight); } else { maskLayerDiv.css('height', '100%'); } // 點擊遮罩層關閉 maskLayer.off("click").on("click", function () { $(this).fadeOut(600); }); } 複製代碼
並且咱們還作了判斷,在移動端設備以及頁面寬度小於600px
的時候,咱們將按照原圖的寬高比例縮放0.6
倍顯示。調用方式也很簡單,如如下一個示例:ios
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>預覽圖</title> </head> <body> <img src="/static/image/1.jpg" alt=""> <img src="/static/image/1.jpg" alt=""> </body> <script src="./viewer.js"></script> <script src="./static/plugin/jquery.min.js"></script> <script> //js方式調用代碼以下: // let imgElements = document.querySelectorAll('img'); // [].slice.call(imgElements).forEach((img) => { // img.onclick = function(){ // const viewer = new ewViewer(this); // console.log(viewer); // } // }); //jquery調用方式代碼以下 $('img').click(function(){ const viewer = new ewViewer($(this)); console.log(viewer); }); </script> </html> 複製代碼
這只是實現簡單預覽圖的第一步,若是能夠,還能夠在這上面擴展,進而實現viewer.js
那樣的預覽圖片庫了。不過本文旨在介紹簡單的預覽功能,後續就不贅述了。markdown