從未兼容過IE8的girl,在看到自己滿心歡喜寫的頁面在IE8里打開的時候,是崩潰的。
兼容的過程經歷下來有一種洗心革面又兵、破繭成蝶的感覺(尷尬而不失禮貌的微笑臉)。
1.html中的注釋怎么判斷IE8/非IE8
<!--[if lte IE 8 ]><html class="ie" lang="zh-cn"><![endif]-->
<!--[if (gt IE 8)|!(IE)]><!-->
<html class="modern"
lang="zh-cmn-Hans">
<!--<![endif]-->
如上,[if lt IE 8]
的意思是:小于或等于沛厨。[if (gt IE 8)|!(IE)]
的意思是:大于(切不包含)IE8宙地,或,非IE8逆皮。至于lte宅粥、gt都是什么意思呢?
- gt: greater than电谣,選擇條件版本以上版本秽梅,不包含條件版本
- lt: less than,選擇條件版本以下版本剿牺,不包含條件版本
- gte : greater than or equal企垦,選擇條件版本以上版本,包含條件版本
- lte : less than or equal牢贸,選擇條件版本以下版本竹观,包含條件版本
- ! : 選擇條件版本以外所有版本,無論高低
- &:并
- |:或
- ():子表達式
在這里留個問題給今后的自己(偏偏在問了俊哥的時候豁然開朗):
為什么有些注釋是這種寫法
<!--[if (gt IE 8)|!(IE)]><!-->
something doesn't show in ie
<!--<![endif]-->
而有些確是
<!--[if lte IE 8 ]>
something you want to show in ie
<![endif]-->
2. 一個關于meta的故事
對于360瀏覽器來說潜索,<meta name="renderer" content="webkit">
意味著在360瀏覽器中啟用極速模式(頁面默認用極速核)臭增,取之的有IE兼容內核:<meta name="renderer" content="ie-comp">
和IE標準內核:<meta name="renderer" content="ie-stand">
3. 學會觀察控制臺中的render
故事的起因是這樣的:
前提:頁面有一個每秒一次的定時器。
我呢用了一個外引得超細字體竹习,發(fā)現這些字體每秒都會閃一下(文字粗細顏色深淺來回轉換)誊抛。這個現象被文博一眼看透,他說“閃爍整陌,說明瀏覽器每秒都在渲染這個區(qū)域拗窃,看下rendering吧...”
兩步:
- 找到控制臺中的Rendering
- 勾選上Paint flashing之類的
勾選上了paint flashing之后會發(fā)現,那個定時器造成了幾乎整個頁面的每秒渲染一次泌辫。這個時候那個神奇的要使用will-change
的原理就浮出水面了随夸。所以解決辦法之一,就是在定時器作用的<span>
上加上will-change: transform
4. 不要高估IE8/9對偽元素的渲染能力
為什么這么說呢震放?
用偽元素span::before
的transform:translateY()
模擬數字滾輪(當然在IE8/9中宾毒,我乖乖地把transform改為了top):
發(fā)現在IE11的模擬器下模擬IE8/9的時候,瀏覽器可以準時并精準地把某一時刻::before
的top
位置渲染出來殿遂。然而在真實的瀏覽器中诈铛,IE8卡!啄浮幢竹!了!(IE9甚至渲染找不到top位置恩静,一次都賦值不上;篮痢)就連強制執(zhí)行$targetElem.offsetLeft
以求強制render,也是沒有任何效果的。
無奈之下咬荷,只能在IE8/9中放棄偽元素冠句,直接把數字innerHTML到相應的span中。
所以結論是幸乒,如果想要頁面兼容IE8/9并且?guī)в袆赢嫷脑捙车祝饔脗卧氐亩ㄎ蛔兓?/p>
5. a標簽中的rel="noopener noreferrer"
vscode中一些插件(如HTML Snippets)已經把a:blank的補全自動加上了該屬性。
可以看下此文的解釋:
當給a標簽加上target="_blank"
的時候罕扎,待跳轉的頁面是可以通過window.opener
獲取到當前頁面的部分訪問的聚唐。所以,新開的tab頁也就能夠再用window.opener.location
跳轉到其他(比如某個釣魚的)網頁腔召,或者代表當前頁面執(zhí)行一些JS操作杆查。而用戶往往是信任從當前頁跳轉的新tab頁的。
比如臀蛛,用一個萌貓的圖片吸引你分享到facebook亲桦,然而當你在分享前需要登錄的時候,卻是一個fake的facebook登錄頁浊仆。如果你分不清的話客峭,就是會乖乖地輸入你的賬號和密碼的。
那么解決方式呢抡柿。舔琅。。
就是在target="_blank"
的a標簽中加上rel="noopener"
洲劣,鑒于FF是不認noopener
的备蚓,所以還要為了FF加上noreferer
,所以完整寫來就是:rel="noopener noreferer"
舉個例子實踐一下:
new page a囱稽、page b郊尝。page a 中有一個target="_blank"
的a標簽,link到了page b战惊,當點擊鏈接打開新標簽也就是page b的時候:
試著在page b的console中輸入
window.opener.location
虚循,能夠看到原頁面page a的地址。然后样傍,將window.opener.location設置為其他頁面地址的時候,page a就乖乖跳轉了:在我們加上了
noopener
之后铺遂,新打開的page b中就無法訪問到window.opener
當中的屬性了衫哥。值得注意的是,用JS實現新建標簽打開頁面襟锐,也伴有同樣的問題撤逢,所以我們不要直接用
window.open('http://www.google.com')
,而是要像這樣:
var otherWindow = window.open();
otherWindow.opener = null;
otherWindow.location = url;
6. 漸變的文字
所有的IE都不支持文字的漸變
優(yōu)雅降級的處理方式是:-webkit內核者,漸變蚊荣;IE核初狰,純色。
文字的漸變實際上是依靠背景的漸變來實現的:
-
background-image: linear-gradient(to right,#ffd823 30%,#0f9);
:給文字設置一個漸變的背景 -
-webkit-background-clip: text;
:文字以外的部分都cut掉 -
-webkit-text-fill-color: transparent;
:文字部分設置為透明互例,以此來把背景部分透露出來奢入。
不難看出,基本原理還是靠操作背景媳叨。所以不僅是文字漸變腥光,鏤空的文字也可以通過background: whatever;
再加上-webkit-text-fill-color: transparent;-webkit-background-clip: text;
來實現。
有關knockout text的實現可參考css-tricks上的這篇糊秆。
7. 幀動畫的實現
幀動畫武福,也就是把動畫分解,每一幀做成一張圖片痘番,再把所有幀圖拼成一個長圖捉片。最后利用改變background-position
來實現動畫。
舉例:
animation: lightning 2s steps(20) infinite;
在animation
中寫下自定義的動畫名lightning
之后汞舱,設置一個steps(20)
(表示一共執(zhí)行20步伍纫,每一步的時間被2s平均分配)就可以了。
@keyframes lightning {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -3350px;
}
}
ps: 開發(fā)一定要和動效師確認好每一幀的停留時間(一般來說是40ms)兵拢。