那些H5用到的技術(1)——素材加載


編碼環境

Sublime Text 3
插件包括:

  1. Autoprefixer 自動補全CSS
  2. ColorPicker 顏色選擇器
  3. ConvertToUTF8 轉碼
  4. GBK Support 支持GBK
  5. HTML-CSS-JS Prettify 前端代碼格式化
  6. SublimeCodeIntel 最好用的自動補全

Chrome 57.0.2950.5 m
用來預覽以及調試

gifcam
屏幕錄制gif神器
http://blog.bahraniapps.com/gifcam/

用到的js&css插件
Jquery http://jquery.com/
PreloadJS http://createjs.com/preloadjs
SoundJS
animate https://github.com/daneden/animate.css

前言

H5其實也就是HTML5,是新的HTML標准,自從HTML5標准發布普及之后,使各種不依賴其他插件就能實現酷炫功能的html頁面成為可能,這在營銷展示的時候非常的有效,H5這個簡稱也隨之而來,所以目前(以及本文)在提到H5,一般都是指那些酷炫的html頁面,里面涉及到很多技術內容。

我也一直對H5的相關技術感興趣,但是都在忙其他的項目,前段時間終於可以着手H5頁面的開發了,內容包括小游戲、品牌宣傳等等,學習並分享一下其中的內容。當然,這里面就不包括html+css+js的基礎內容講解了。
我將為此做一個系列文章,一步一步的完成豐富我們的h5頁面,首當其沖的應該就是素材加載了。

什么時候用到素材加載?

  1. 當h5頁面包含很多圖片素材的時候(可以考慮使用雪碧圖),特別是有大圖片的時候,如果是一般的圖片瀏覽,可以延遲加載,如果是類似游戲的話,就一定要保證用戶體驗,加載完才開始執行,否則場景都開始了,你給用戶顯示一片空白么?
  2. 當h5頁面包含音頻素材,並且需要立即播放,同樣是需要在一開始加載完才行,否則到時候預加載是無法保證速度的。
  3. 總之還是要看加載與否是否會影響用戶體驗,如果影響,那么務必在頁面加載完成后才顯示。

loading提示,讓用戶等待

首次素材加載當然越快越好,所以一般h5的素材我們能壓縮就壓縮,即使質量降低了,但是手機上看只要沒有明顯的馬賽克其實都可以理解……不排除網絡慢的情況,所以一般我們都會有個loading提示頁面來安撫用戶焦急的心態,否則加載的時候也是一片空白,如果這個界面越有趣,用戶當然就越安心~,讓用戶首次加載之后,后續瀏覽器打開頁面一般都會有緩存,loading幾乎都一閃而過。

常用的loading方案有3種

方案 優點 缺點
文字提示 方便直白、本身不用加載,可以提示具體進度 缺乏吸引力
css3動畫 美觀、本身不用加載,可以提示具體進度 效果實現困難
gif動畫 美觀,自由度高 本身是張圖片,也需要加載,無法提示具體進度

loading預覽圖

1是gif(本身有50kb),加載這個也是要時間的
2是css3+svg(copy自大神作品,css代碼就有1000行…),只是一個演示,一般沒人會搞那么復雜的。
3是文字

圖片的加載

對於一般只有圖片展示的h5,加載圖片有比較簡單的方法,對於需要加載的img,加上自定義的class用於選擇,這里使用deferred。

 
 
 
         
  1. <img class="deferred" src="http://i4.piimg.com/11340/7f638e192b9079e6.jpg" alt="">

后面借助dom元素的事件和jquery的deferred回調函數機制,加載完回調即可,deferred用法可參考
http://api.jquery.com/category/deferred-object/
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

 
 
 
         
  1. //簡單的圖片素材加載代碼
  2. var loading_deferred = $.Deferred();
  3. var loading_index = 0;
  4. var loading_length = $('.deferred').length;
  5. $.when(loading_deferred).done(function() {
  6. $('.container').removeClass('hide');
  7. // 淡入淡出效果
  8. $('.container').addClass('fadeIn animated');
  9. $('.loading').addClass('fadeOut animated');
  10. });
  11. if (loading_length > 0) {
  12. for (var i = 0; i < loading_length; i++) {
  13. var temp_src = $('.deferred').get(i).src;
  14. var temp_img = new Image;
  15. temp_img.onload = function() {
  16. loading_index++;
  17. //console.log(loading_index);
  18. $('.loading p').text('素材加載中(' + loading_index + '/' + loading_length + ')');
  19. var persent = (loading_index / loading_length) * 100 + "%";
  20. if (loading_index == loading_length) {
  21. loading_deferred.resolve();
  22. }
  23. };
  24. temp_img.onerror = function() {
  25. $('.loading p').text('素材加載失敗!');
  26. }
  27. temp_img.src = temp_src;
  28. }
  29. } else {
  30. loading_deferred.resolve();
  31. }

音頻的加載

本想着音頻的加載直接用Audio套用圖片加載的公式即可

 
 
 
         
  1. //Constructor for audio elements. The preload property of the returned object is set to auto and the src property is set to the argument value
  2. var audio= new Audio(src);
  3. audio.onloadeddata = function(){
  4. //加載完成
  5. };
  6. audio.onerror = function(){
  7. //加載失敗
  8. };

實際開發中,經過測試發現,瀏覽器的兼容性確實有問題,在Chrome瀏覽器上正常,但是在微信/IOS上就不正常了,默認音頻是不能自動加載的,就不會執行onloadeddate,很多h5其實都是在微信/IOS上傳播的,可以使用XMLHttpRequest代替,又不想重復造輪子,所以還是搜索一下現有的方案,發現了神器PreloadJS

利用神器PreloadJS

PreloadJS是CreateJS家族中的一個模塊,其他模塊還包括EaselJS、TweenJS、SoundJS,都是h5開發的大殺器。但是也不能保證瀏覽器的完全兼容,具體說明以及使用方法見官方文檔。
PreloadJS默認情況就是使用XHR進行素材加載的,你也可以強制使用標簽加載。
PreloadJS能夠加載幾乎所有的WEB資源文件,使用起來很方便,可以采用manifest進行統一的素材管理。加載代碼變換后如下:

 
 
 
         
  1. //建議使用資源清單,方便管理,如果資源較多,可以考慮獨立出json文件,腳本自動生成。
  2. var manifest = [
  3. "./img/1.jpg",
  4. "./img/2.jpg",
  5. "./img/3.jpg",
  6. "./img/4.jpg",
  7. "./img/5.jpg",
  8. "./img/6.jpg",
  9. "./img/7.jpg",
  10. "./img/8.jpg",
  11. "./img/9.jpg",
  12. "./img/10.jpg",
  13. "./img/11.jpg",
  14. "./img/12.jpg", {
  15. id: '告白氣球',
  16. src: './audio/107192078.m4a'
  17. }, {
  18. id: '一生有你',
  19. src: './audio/95484.m4a'
  20. },
  21. ]
  22. //PreloadJS加載代碼
  23. var loading_deferred = $.Deferred();
  24. $.when(loading_deferred).done(function() {
  25. $('.container').removeClass('hide');
  26. // 淡入淡出效果
  27. $('.container').addClass('fadeIn animated');
  28. $('.loading').addClass('fadeOut animated');
  29. });
  30. var queue = new createjs.LoadQueue(false);
  31. //SoundJS默認用的是復雜的Web Audio接口,這會導致加載音頻變慢,所以顯示注冊使用html的audio即可
  32. createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]);
  33. //如果需要加載音頻,需要注冊SoundJs插件
  34. queue.installPlugin(createjs.Sound);
  35. queue.on("complete", function() {
  36. var items = queue.getItems();
  37. for (var i = 0; i < items.length; i++) {
  38. $('.container').append(items[i].result);
  39. };
  40. loading_deferred.resolve();
  41. queue.getLoadedItems();
  42. createjs.Sound.play("告白氣球");
  43. }, this);
  44. queue.on("progress", function(event) {
  45. //console.log("Progress:", queue.progress, event.progress);
  46. var persent = Math.floor(queue.progress * 100) + "%";
  47. $('.loading p').text('素材加載中(' + persent + ')');
  48. });
  49. //設置並列加載,否則每次只加載一個,太耗時
  50. queue.setMaxConnections(5);
  51. queue.maintainScriptOrder = true;
  52. queue.loadManifest(manifest);

注意:使用XHR加載非本域名資源會遇到Cross-domain跨域加載的問題,資源服務器需要配合設置一下access-control-allow-origin頭,或者使用標簽模式進行加載new createjs.LoadQueue(false);

最終效果圖

總結

HTML5雖然給出了一系列的標准,但是各大瀏覽器廠商還是支持的程度不一樣,就拿CSS3的動畫來說,以前為了兼容,animate還要寫N個一樣的代碼,這非常的尷尬。現在的主流瀏覽器應該區別都不大了,但是!!Android的各種版本碎片化任舊是一大難題,而且目前所做的h5基本上都在微信上,微信的瀏覽器不同機型也會有各種坑,主要解決的也是各種效果的兼容以及視覺統一。上面的示例就在我android手機上是異常的,目測主要是不支持svg,好在微信上效果還是不錯的。

素材加載保證了整個頁面流程的用戶體驗,網速、素材大小、視覺效果設計都會對此有影響,得益於緩存機制,絕大多數情況用戶只會經歷一次煎熬。加載的過程給予用戶一些驚喜,用戶也許就會在第一時間愛上,就拿示例的小狗來說,其實我第一次看到這個CSS動畫是感覺驚艷的,非常好玩,拿來做加載動畫未嘗不可(前提是要有實力弄出來…)。

相信大家注意到了SoundJS的厲害之處,下一篇將講述一下h5音頻和視頻播放技術和遇到的坑。

demo地址:
https://github.com/leestar54/h5-demo/blob/master/loading.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM