網頁中的圖片預加載
圖片預加載對圖片畫廊及圖片占據很大比例的網站來說十分有利,它保證了圖片快速、無縫地發布,也可幫助用戶在瀏覽你網站內容時獲得更好的用戶體驗。我們知道在 Web 頁面中實現圖片的預加載其實很簡單,通常的做法是在 JS 中使用 Image 對象即可,代碼大致如下
var image = new Image()image.onload = function() { console.log('圖片加載完成')}image.src = 'http://misc.360buyimg.com/lib/img/e/logo-201305.png'
下面推薦幾篇網頁中實現圖片預加載的文章:
然而在微信小程序(以下簡稱小程序)里要實現圖片的預加載要更麻煩一些,因為小程序里并沒有提供類似 Image 這樣的 JS 對象。。
小程序必知必會
在進入正題前,需要了解以下小程序相關的知識(當然最好還是完整的學習一下官方文檔):
這里有個官方的簡單例子可以用來幫助理解
<!-- 模板文件 foo.wxml --><view> Hello {{name}}! </view><button bindtap="changeName"> Click me! </button>
//腳本文件 foo.jsPage({ data: { name: 'WeChat' }, changeName: function(e) { this.setData({ name: 'MINA' }) }})
運行這個頁面會看到一行 Hello WeChat! 的文字及一個按鈕,點擊按鈕后文字會變成 Hello MINA!
在小程序中加載圖片
小程序提供一個 image 組件(類似于 HTML 中的 img 標簽),可以設置 src 及加載成功或失敗的回調,使用起來很簡單
<!-- 模板文件 bar.wxml --><image src="http://misc.360buyimg.com/lib/img/e/logo-201305.png" bindload="imageOnLoad" binderror="imageOnLoadError" />
//腳本文件 bar.jsPage({ imageOnLoad(ev) { console.log(`圖片加載成功,width: ${ev.detail.width}; height: ${ev.detail.height}`) }, imageOnLoadError() { console.log('圖片加載失敗') }})
運行以上代碼,順利的話頁面上會顯示出一張圖片,同時控制臺會打印出帶圖片寬高的日志信息
將功能抽離成公用組件
接下來我們考慮實現這么一個功能,在頁面上載入一張尺寸和 K 數都很大的圖片,由于圖片很大,下載需要一定的時間,而在這段時間內,用戶看到的是空白或是不完整的圖片,體驗顯然不好。
一種常用的優化手段是先加載一張縮略圖,該縮略圖通過樣式設置為和原圖一樣的寬高,這樣用戶首先能很快速地看到一張模糊的圖片,此時再去對原圖做預加載,加載完成之后對縮略圖進行替換,因為此時圖片已經下載過了,所以界面上能無縫地切換為原圖顯示,效果如下:
單張圖片預加載
完成這個優化操作的關鍵就在于需要一個公共的圖片預加載組件的支持,接下來我們分步驟來看看如何實現
可以看出,由于小程序里無法動態地插入模板結構,所以相對于普通網頁端的組件調用,這里多出了在 WXML 文件中引入及使用模板這個步驟,而其他部分對于調用方(即Demo 頁面)來說則是相似的,下面是完整的 Demo 頁面的代碼
<!-- demo.wxml --><view class="img_wrap"> <image wx:if="{{ imgUrl }}" src="{{ imgUrl }}" /></view><button bindtap="loadImage">Click To Load Image</button><view class="msg">{{ msg }}</view><!-- 引入圖片預加載組件 --><import src="../../img-loader/img-loader.wxml"/><template is="img-loader" data="{{ imgLoadList }}"></template>
// ------ demo.js ------//引入圖片預加載組件const ImgLoader = require('../../img-loader/img-loader.js')//縮略圖 80x50 3KBconst imgUrlThumbnail = 'http://storage.360buyimg.com/mtd/home/lion1483683731203.jpg'//原圖 3200x2000 1.6MBconst imgUrlOriginal = 'http://storage.360buyimg.com/mtd/home/lion1483624894660.jpg'Page({ data: { msg: '', imgUrl: '' }, onLoad() { //初始化圖片預加載組件 this.imgLoader = new ImgLoader(this) }, loadImage() { //加載縮略圖 this.setData({ msg: '大圖正拼命加載..', imgUrl: imgUrlThumbnail }) //同時對原圖進行預加載,加載成功后再替換 this.imgLoader.load(imgUrlOriginal, (err, data) => { console.log('圖片加載完成', err, data.src) this.setData({ msg: '大圖加載完成~' }) if (!err) this.setData({ imgUrl: data.src }) }) }})
如果把圖片加載完成的回調統一指定成 Page 對象中的方法,則可以很方便地處理多張圖片的加載,這里也寫了個例子,效果如下:
多張圖片預加載
總的來說調用起來還算方便吧,img-loader 的組件代碼略多這里就不貼出來啦,有興趣的同學可以前往 Github 項目頁面 查看,目前此組件已應用在京東購物小程序版中。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
新聞熱點
疑難解答