最近寫移動端,遇到一個問題就是用fixed屬性布局的時候由於手機的原因會出現很多問題,比如說手機端底部固定一塊,然后里面有輸入框,(類似於手機QQ或者微信底部的輸入框一樣的布局)這個時候在調用軟鍵盤的時候會出現軟鍵盤遮擋輸入框的情況,如圖
這是正常的情況下,下面是喚起軟鍵盤的圖片
很明顯擋住了一半的輸入框,這個時候可以用以下方式解決(在這里要感謝葉小釵的博客,是從他那里學來的)
虛擬鍵盤導致fixed元素錯位
fixed元素一定會伴隨虛擬鍵盤的出現,但是虛擬鍵盤只是“貼”在了viewport上,表面上不會對dom產生“任何”影響,但是這個時候fixed元素表現卻變得怪異起來,會錯位。
應用層面解決問題方案是,虛擬鍵盤彈出時將fixed元素設置為static,虛擬鍵盤消失時候設置回來。
由於虛擬鍵盤出現並未拋出事件,而檢測scroll或者resize事件,皆會有一定延遲,會出現閃爍現象,所以現有最好的方案是setinterval定時器監控當前獲取焦點元素是否為文本元素,若是是的話便需要處理,如此便可解決fixed元素錯誤問題。
fixed元素滑動慣性平滑度
我們常常遇到這種產品需求,tab標簽欄開始固定,當滾動向下超過該標簽欄后便會變成fixed元素,一直出現在頭部,這樣的需求在電腦上沒有問題,但是在iPhone5s以下的手機常常會出現小范圍錯位或者快速移動大范圍錯位的問題。
這個時候我們可以引起reflow迫使瀏覽器重繪以解決這個問題,這里推薦一個奇怪的hack寫法:同時設置三個image元素的src屬性,便可以全范圍解決該難題, 該方案被團隊證實並得到應用。
//三圖片src,引發reflow,處理fixed方案慣性問題
var el = this.els.ctlc.find('img');
$(el[0]).attr("src", 'http://res.m.ctrip.com/html5/Content/images/144.png');
$(el[1]).attr("src", 'http://res.m.ctrip.com/html5/Content/images/144.png');
$(el[2]).attr("src", 'http://res.m.ctrip.com/html5/Content/images/144.png');
另外,上圖中的tab標簽下面的藍線具有動畫,但是在小米或者三星手機上可能不會移動,這個時候也可以動態引起reflow解決這個BUG。
其它
l CSS選擇器盡量使用id與class,避免過度層疊
l 避免使用數值,比如:border: none不會引起渲染,而boder: 0會
l 動畫時候讓元素脫離文檔流,以免導致大量reflow
l 避免逐條修改DOM樣式,改以className實現同樣功能
l 操作DOM時將display設置為none,因為這種元素不會影響渲染,或者操作fragment對象取代操作顯示在頁面上的DOM
l 避免將獲取DOM樣式屬性的操作寫在循環中,可能引起重復reflow
以上解決了使用fixed后產生的遮擋和平滑滑動的問題。親測有效!