標籤:des android style class blog code
webapp的一大優勢便是在view切換時候可以擁有媲美與native的動畫效果,但是很多時候那隻是一種想法,真正的情況卻不是這樣產生此問題的原因有:① 手機CPU爛!② 手機顯卡爛!就算四核其渲染也很有問題③ 高端手機瀏覽器會有BUG④ 低端手機支援不好(國內山寨機笑而不語)因為以上原因,事實上做webapp的都會不同程度的弱化動畫,或者在局部地區使用動畫問題雖難,總有方案,事實上的情況是,幾行代碼搞死人,就我們的這個動畫問題,前後過手幾輪最後又回到了我手上,中間甚至經手了國內著名的前端,其中兩位還出過書,所以說動畫老大難問題在移動端是真心難,今天就我所知的動畫做一次分享,希望對各位有協助,若是有好方案,麻煩賜教一番難在何處
dom樹過多view的移動與簡單的圖片slider組件相差甚劇!原因便是其dom結構可能很複雜,大dom樹的移動在移動端效果很差就簡單列表頁來說,當項目超過100個時,使用IScroll類外掛程式都應該很謹慎,這類移動可能非常卡!而且dom樹複雜度與業務直接相關,我們沒有任何辦法去控制dom樹,因為業務代碼可能不會經過我們的手,就算經過,你又肯定自己做出來的dom樹有多小?不見得吧
長短頁問題所謂長短頁便是一個view很長一個view很短,這裡問題處理十分討厭首先我們每次做切換需要將view位置切換至頭部(window.scroll(0, 0))如此的話ios中會引起頁面viewport的變化(系統自動發生),或者會觸發低端工具列的出現,這個時候頁面抖動無可避免若是每次不執行window.scroll(0, 0),切換時候又會導致短的view不可見我現階段想到的解決方案是,移動時候將scroll設得比較大,移動時候將bview的top值與scrollTop相同最後仍然需要執行window.scroll(0, 0)的操作,所以,這個問題只能緩解,無法解決
手機渲染問題只要是做移動端的朋友,一定會對三星機或者一些低端機的渲染嗤之以鼻!具體表現為多次操作style後,後面的操作瀏覽器不會搭理你解決方案是:① 引起瀏覽器強烈重繪② 臨時增刪一個dom結構但是涉及view切換動畫的話,很有可能會出現一些莫名其妙的問題!動畫的掙紮以上是幾個不可避免會遇到的問題,所謂解決方案,也不過自欺欺人如果不能提高效率,動畫時候最大程度的減小DOM結構便是唯一方法,就算減少render Tree也是一種進步其基本想法是只顯示視口處的元素,其餘不予理睬http://sandbox.runjs.cn/show/5szc5wcf
1 var FastRender = new inherit({ 2 3 initialize: function(opts) { 4 this.handleOpts(opts); 5 this.init(); 6 }, 7 8 handleOpts: function(opts) { 9 if (!opts || !opts.doms || !opts.doms.length) throw ‘FastRender param error‘;10 this.doms = opts.doms;11 this.container = opts.container || $(window);12 this.renderContainer = {};13 this.step = 50;14 15 },16 17 init: function() {18 this.initImgContainer();19 this.initRender();20 this.bindEvents();21 },22 23 bindEvents: function() {24 25 //為container綁定事件26 this.container.on(‘scroll.fastRender‘, $.proxy(function() {27 this.initRender();28 },29 this));30 },31 32 initImgContainer: function() {33 var el, i, len, offset;34 for (i = 0, len = this.doms.length; i < len; i++) {35 el = $(this.doms[i]);36 offset = el.offset();37 38 //這塊卡39 // (function (el) {40 // setTimeout(function () {41 el.css({42 ‘width‘: offset.width,43 ‘height‘: offset.height44 });45 // }, 0);46 // })(el);47 48 if (!this.renderContainer[offset.top]) {49 this.renderContainer[offset.top] = [];50 }51 this.renderContainer[offset.top].push(el);52 }53 54 },55 56 /*57 這裡需要對對象遍曆做最佳化,以座標搜尋替換數值搜尋58 59 */60 initRender: function() {61 var height = this.container.height();62 var srollHeight = this.container.scrollTop();63 var k, _imgs, el, i, len, els;64 65 this.doms.removeClass(‘wl‘);66 67 for (k in this.renderContainer) {68 // if ((parseInt(k) < srollHeight + height + this.step) && (parseInt(k) > srollHeight - this.step)) {69 if ((parseInt(k) < srollHeight + height - this.step) && (parseInt(k) > srollHeight + this.step)) {70 71 els = this.renderContainer[k];72 for (i = 0, len = els.length; i < len; i++) {73 el = $(els[i]);74 el.find(‘.lazy_wrapper‘).show();75 }76 } else {77 els = this.renderContainer[k];78 for (i = 0, len = els.length; i < len; i++) {79 el = $(els[i]);80 el.find(‘.lazy_wrapper‘).hide();81 }82 83 }84 } // for85 86 },87 88 destroy: function() {89 //為container綁定事件90 this.container.off(‘.fastRender‘);91 }92 93 });94 95 var f = new FastRender({96 doms: $(‘.js_hotel_detail‘)97 });
這個demo想法很美好,若是可實現的話,無疑是移動端一大功臣,事實上是
瀏覽器:10分
IOS(4000):6分
android小米(1800):5分
化為4核:4分(1800)
其表現在瀏覽器上很好,手機上便不行了,所以今日的論證失敗,該方案還需最佳化
這個結果其實可以預見,在渲染上手機根本跟不上,所以平滑度就跟不上,方案拋棄
換個方向想,若是可以繞過DOM樹過多問題也是可取,比如移動時候直接以一個白頁做動畫,這個方案比較可恥
另一個方案是使用cavas為本頁面產生一個縮圖,每次移動實際上是縮圖,如此動畫是順暢了,但是此方案甚難,還可能引起其它問題,此方案我得再做驗證
結局
結局並不美好,此問題我未找到很好的解決方案,移動端的動畫還有很長的路要走......