DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> HTML基礎知識 >> HTML5詳解 >> 【HTML5疑難雜症】脫離文檔流時的渲染BUG
【HTML5疑難雜症】脫離文檔流時的渲染BUG
編輯:HTML5詳解     

BUG重現

最近機票團隊在一個頁面布局復雜的地方發現一個BUG,非常奇怪並且不好定位,這類問題一般最後都會到我這裡,這個問題是,改變dom結構,頁面卻不渲染!!!

如圖所示,我動態的改變了dom結構,結果頁面那一坨變得什麼都沒有,相當奇怪!!!在PC模擬iPhone就可以重現,iPhone、note4等手機上也可重現,由於這種BUG我不是第一次碰到,很快便引起了注意,總結起來可以歸結於:

JS代碼改變fixed元素的Html結構(一般是動畫後並且布局相對復雜),頁面不會渲染

問題定位-分離法

本著發現問題,定位問題,解決問題的步驟,我開始了定位,這裡的難點是,這類問題往往非常難以定位,因為他的dom tree相當復雜,首先我做了一個事情,直接將其HtmlCSS分離出來,擺脫JS的原因,直接顯示該dom。

於是問題不在了,這個很令人費解,難道是JS對其造成了影響?經過一輪糾纏,定位失敗開始二輪定位。

問題定位-最小化問題

這種問題確實不好處理的時候,光靠看頁面可能不能處理了,這個時候便把機票的代碼拿到本地,部署起來,做了幾件事情:

① 去掉該頁多余的業務代碼,基本上不完成任何功能

② 去掉多余的dom結構(由於我們是單頁應用,dom可能相對比較復雜)

打開對應業務代碼一看,洋洋灑灑3000行,立馬想吐:

這個時候一行行去讀代碼就是2B的行為了,直接找到那個顯示日歷的代碼:

然後稍作改動,把其它業務邏輯全部搞掉,事件綁定也搞掉,只留下顯示日歷的事件,直接一來點擊顯示日歷,這個時候形成的dom結構由4000多行變成了1000多行,但是依舊有BUG

問題定位-CSS重置

由於機票對日歷的樣式,做了重置,所以有理由懷疑是他們自己的css導致的問題,於是想去掉他們的CSS引用試了試,雖然樣式難看了點,但是問題依舊存在......

問題定位-JS邏輯

這個時候便有理由懷疑其日歷顯示後,本身有一定邏輯功能導致出錯,於是看到了日歷show後面干的事情,並且為了防止dom結構過大,將月份顯示設置為1月。

都這個樣子了,他居然還是渲染不處理,有點傷害自尊!!!

因為這個日歷顯示時候有一個從右到左的動畫,這個時候將其動畫關掉,卻發現問題解決了!!!其中的代碼為zepto的實現,不是關鍵

$el.css({
      "-webkit-transform": prepareCss,
      transform: prepareCss
})
  .show()
  .animate({
    "-webkit-transform": "translate(0, 0)",
    transform: "translate(0, 0)"
  }, 500, "ease-in-out", function() {
    $el.CSS({
      "-webkit-transform": "",
      transform: ""
    });
  });

問題定位成功-脫離文檔流的渲染

最後問題定位成功,至少從表現和處理來說是定位成功的,簡單來說:

動畫執行結束後,如果我改變的是fixed元素中的一個子單元的Html,不會有反應,但是我們同時改變static元素便會引起一次渲染,尼瑪這是神馬鬼!!!

問題探索-渲染的差異

為了弄懂這個原因,我們得看到渲染的細節,這裡做了一個對比:

不引起static dom變化

引起static dom變化

這裡注意觀察最後一次paint便可以看見渲染出來的東西不一樣,導致這種的差異是什麼呢,我們一次次的對比幾次不同

這裡做一個差異對比,因為這裡的static元素與fixed元素還有一些管理,我們這裡操作與之完全無關的元素試試。事實證明沒有什麼影響,所以這類問題的解決方案是:

移動端過多定位元素布局時,偶爾操作fixed元素Html不會渲染,解決方案是同步改變與之相關的static元素,便會引導渲染

剛剛使用的是設置Html,這裡完全可以使用這種做法:

el.html(el.Html())

可以達到相同的功能,但是問題導致原因依舊不可知......不可說不是一種遺憾!

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved