首先這個標題再詳細的說就是如何解決font-face在IE8下間歇性出現圖標字體渲染失敗的解決方案。javascript
若是你還不知道什麼是圖標字體,能夠先閱讀:連接1,連接2,連接3css
先看在IE8下的問題:html
而正常的應該是這樣:java
能夠看到因此圖標都顯示不了,最關鍵的是還顯示出他自己的字符,這絕對是不能忍的,必須解決。jquery
這個頁面是爲了快速一覽圖標字體的頁面,這兩個截圖都是在IE8下截圖的,因此能夠看到font-face不是不兼容IE8,而是間歇性的撂挑子(出問題),至於問題緣由:git
我猜想:是由於字體並不阻塞頁面顯示,當第一次打開頁面,字體文件沒有緩存,且字體在頁面打開後才載入進來,致使瀏覽器沒有從新渲染頁面中使用圖標字體的字符,才致使此問題出現的github
首先要100%復現問題,肯定bug緣由。我是win8的開發機,用Oracle VM VirtualBox創建虛擬機,IE6 8 9各一臺,如今用IE8測試web
開發環境是Visual Studio 2013,把項目跑起來後,開啓Fiddler作虛擬機的代理服務器,也就是將Fiddler做爲個人真實機的反向代理服務器,這樣可讓虛擬機鏈接個人真實機的localhost地址,來達到遠程VS調試的功能。bootstrap
固然你能夠直接把web文件發佈到局域網內網IP,而後虛擬機訪問,在本例中是能夠的,可是那樣VS是沒法使用調試(debug)功能的。promise
如上圖所示虛擬機成功鏈接真實的localhost,但目前是沒問題的,咱們須要利用Fiddler來模擬網絡問題。
猜想是字體返回過慢,因此能夠利用Fiddler的 BreakPoints ,即斷點功能。
使用Fiddler-【Rules】-【Automatic Breakpoints】-【After Response】斷點功能。
啓用【After Response】即響應後斷點,即響應已經發送至服務器,服務器也將資源返回給Fiddler,此時Fiddler等待其餘資源都響應完成後,再返回給瀏覽器,以人爲製造上述猜測的發生場景,過程以下圖:
順便一提,在本例中使用【Before Request】也是能夠的,由於對於瀏覽器而言,使用請求前斷點和響應後斷點都是同樣的。
接下來在虛擬機中的IE8按Ctrl+F5,強制全部資源均重新加載,在Fiddler中,把全部非字體資源文件都【Run to Completion】經過,轉發給瀏覽器,最後再將字體轉發給瀏覽器。
能夠看到,問題又復現了:
若是此時關閉斷點,再在虛擬機中清空緩存,並按Ctrl+F5 多少次,也沒法復現此問題,只要使用Fiddler斷點,就能夠100%復現此問題。
問題找到了,就是後加載進來沒法渲染,想辦法強制觸發渲染就能夠了。
你們應該都知道,調整瀏覽器大小會形成網頁重繪與迴流,會讓頁面幾乎全部元素從新繪製。由於從新繪製樣式了,因此天然也就能夠了解決圖標字體渲染失敗的問題。
缺點天然不用說,這等於沒解決,不過咱們能夠利用重繪後圖標生效的特性來讓強制令其頁面迴流重繪。
既然咱們要讓全部圖標字體都生效,那麼最好的辦法是讓頁面發生大面積迴流,以觸發整頁從新渲染。那麼咱們就須要先知道有哪些操做能夠致使迴流:
如下操做會觸發迴流:
一、調整窗口大小
二、改變字體
三、增長或者移除樣式表
四、內容變化,好比用戶在input框中輸入文字
五、激活 CSS 僞類,好比 :hover (IE 中爲兄弟結點僞類的激活
六、操做 class 屬性
七、腳本操做 DOM
八、計算 offsetWidth 和 offsetHeight 屬性
九、設置 style 屬性的值
十、其餘會致使迴流的操做
因此就有了如下失敗的嘗試:
給body頂部插入元素,設定body的寬度,設定絕對定位再設置回來,強制修改font-face的字體再改回來等等,最終解決是沒成功,若是各位有什麼好辦法歡迎留言。
最終經過設置 !important 來覆蓋全部font-face的css,再從新應用就能夠實現了。
代碼:
<style> html.fix-ie-font-face :before, html.fix-ie-font-face :after { content: none !important; }
</style> <script> //重設僞類,使字體強制生效 !(function redrawFontFace() { if ($.support.leadingWhitespace) return; $(window).one("load", function() { console.log("onload!!!!!!!!!!!"); $('html').addClass('fix-ie-font-face'); setTimeout(function() { $('html').removeClass('fix-ie-font-face'); }, 10); }); }()); </script>
原理就是先讓全部圖標字體失效,再讓他們生效,就能夠了。
須要注意的一點是:必須註冊爲 window 的 onload 事件。
最經常使用的$.ready()是不行的,他的本質是 DOMContentLoaded ,他會在DOM加載結束後就觸發,咱們須要在圖標字體文件加載後再執行,由於沒有字體加載後的load事件(若是有請必定告訴我),因此必需要在整頁全部資源都加載完成後再觸發本函數。
順便附上jquery中的 $.ready 實現方法源碼:
//jquery-1.9.1.js #885 jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready ); // Standards-based browsers support DOMContentLoaded } else if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed, false ); // If IE event model is used } else { // Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // detach all dom ready events detach(); // and execute any waiting functions jQuery.ready(); } })(); } } } return readyList.promise( obj ); };
一、IE8下圖標字體很是有鋸齒感怎麼解決?如圖
解決方案:作一張1*1大小的透明PNG圖,而後給全部的圖標字體的類樣式增長IE特有的 filter 屬性,以下:
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=images/IEfix.png, sizingMethod=crop);
zoom: 1;
增長濾鏡後效果:
圖標看上去還算說得過去,至於文字的鋸齒,不是本文探討的範圍內,辣個要去電腦中設置了。
缺點就是會下降頁面打開速度,增長頁面CPU佔用量,會讓頁面變卡,固然前提是你頁面使用了太多圖標字體。
二、待補充…
本文代碼已託管至Github:
https://github.com/xxcanghai/cnblogsFiles/tree/master/fix-IE-bootstrap-font-face
(完)
原文地址-http://www.cnblogs.com/xxcanghai/p/5000984.html