從未兼容過IE8的girl,在看到自己滿心歡喜寫的頁(yè)面在IE8里打開的時(shí)候,是崩潰的。
兼容的過程經(jīng)歷下來有一種洗心革面、破繭成蝶的感覺(尷尬而不失禮貌的微笑臉)。
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,選擇條件版本以下版本,包含條件版本
- ! : 選擇條件版本以外所有版本,無(wú)論高低
- &:并
- |:或
- ():子表達(dá)式
在這里留個(gè)問題給今后的自己(偏偏在問了俊哥的時(shí)候豁然開朗):
為什么有些注釋是這種寫法
<!--[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. 一個(gè)關(guān)于meta的故事
對(duì)于360瀏覽器來說,<meta name="renderer" content="webkit">
意味著在360瀏覽器中啟用極速模式(頁(yè)面默認(rèn)用極速核),取之的有IE兼容內(nèi)核:<meta name="renderer" content="ie-comp">
和IE標(biāo)準(zhǔn)內(nèi)核:<meta name="renderer" content="ie-stand">
3. 學(xué)會(huì)觀察控制臺(tái)中的render
故事的起因是這樣的:
前提:頁(yè)面有一個(gè)每秒一次的定時(shí)器。
我呢用了一個(gè)外引得超細(xì)字體,發(fā)現(xiàn)這些字體每秒都會(huì)閃一下(文字粗細(xì)顏色深淺來回轉(zhuǎn)換)。這個(gè)現(xiàn)象被文博一眼看透,他說“閃爍,說明瀏覽器每秒都在渲染這個(gè)區(qū)域,看下rendering吧...”
兩步:
- 找到控制臺(tái)中的Rendering
- 勾選上Paint flashing之類的
Rendering
Paint flashing
勾選上了paint flashing之后會(huì)發(fā)現(xiàn),那個(gè)定時(shí)器造成了幾乎整個(gè)頁(yè)面的每秒渲染一次。這個(gè)時(shí)候那個(gè)神奇的要使用will-change
的原理就浮出水面了。所以解決辦法之一,就是在定時(shí)器作用的<span>
上加上will-change: transform
4. 不要高估IE8/9對(duì)偽元素的渲染能力
為什么這么說呢?
用偽元素span::before
的transform:translateY()
模擬數(shù)字滾輪(當(dāng)然在IE8/9中,我乖乖地把transform改為了top):
發(fā)現(xiàn)在IE11的模擬器下模擬IE8/9的時(shí)候,瀏覽器可以準(zhǔn)時(shí)并精準(zhǔn)地把某一時(shí)刻::before
的top
位置渲染出來。然而在真實(shí)的瀏覽器中,IE8卡!住!了!(IE9甚至渲染找不到top位置,一次都賦值不上!)就連強(qiáng)制執(zhí)行$targetElem.offsetLeft
以求強(qiáng)制render,也是沒有任何效果的。
無(wú)奈之下,只能在IE8/9中放棄偽元素,直接把數(shù)字innerHTML到相應(yīng)的span中。
所以結(jié)論是,如果想要頁(yè)面兼容IE8/9并且?guī)в袆?dòng)畫的話,慎用偽元素的定位變化。
5. a標(biāo)簽中的rel="noopener noreferrer"
vscode中一些插件(如HTML Snippets)已經(jīng)把a(bǔ):blank的補(bǔ)全自動(dòng)加上了該屬性。
可以看下此文的解釋:
當(dāng)給a標(biāo)簽加上target="_blank"
的時(shí)候,待跳轉(zhuǎn)的頁(yè)面是可以通過window.opener
獲取到當(dāng)前頁(yè)面的部分訪問的。所以,新開的tab頁(yè)也就能夠再用window.opener.location
跳轉(zhuǎn)到其他(比如某個(gè)釣魚的)網(wǎng)頁(yè),或者代表當(dāng)前頁(yè)面執(zhí)行一些JS操作。而用戶往往是信任從當(dāng)前頁(yè)跳轉(zhuǎn)的新tab頁(yè)的。
比如,用一個(gè)萌貓的圖片吸引你分享到facebook,然而當(dāng)你在分享前需要登錄的時(shí)候,卻是一個(gè)fake的facebook登錄頁(yè)。如果你分不清的話,就是會(huì)乖乖地輸入你的賬號(hào)和密碼的。
那么解決方式呢。。。
就是在target="_blank"
的a標(biāo)簽中加上rel="noopener"
,鑒于FF是不認(rèn)noopener
的,所以還要為了FF加上noreferer
,所以完整寫來就是:rel="noopener noreferer"
舉個(gè)例子實(shí)踐一下:
new page a、page b。page a 中有一個(gè)target="_blank"
的a標(biāo)簽,link到了page b,當(dāng)點(diǎn)擊鏈接打開新標(biāo)簽也就是page b的時(shí)候:
試著在page b的console中輸入
window.opener.location
,能夠看到原頁(yè)面page a的地址。然后,將window.opener.location設(shè)置為其他頁(yè)面地址的時(shí)候,page a就乖乖跳轉(zhuǎn)了:在我們加上了
noopener
之后,新打開的page b中就無(wú)法訪問到window.opener
當(dāng)中的屬性了。值得注意的是,用JS實(shí)現(xiàn)新建標(biāo)簽打開頁(yè)面,也伴有同樣的問題,所以我們不要直接用
window.open('http://www.google.com')
,而是要像這樣:
var otherWindow = window.open();
otherWindow.opener = null;
otherWindow.location = url;
6. 漸變的文字
所有的IE都不支持文字的漸變
優(yōu)雅降級(jí)的處理方式是:-webkit內(nèi)核者,漸變;IE核,純色。
文字的漸變實(shí)際上是依靠背景的漸變來實(shí)現(xiàn)的:
-
background-image: linear-gradient(to right,#ffd823 30%,#0f9);
:給文字設(shè)置一個(gè)漸變的背景 -
-webkit-background-clip: text;
:文字以外的部分都cut掉 -
-webkit-text-fill-color: transparent;
:文字部分設(shè)置為透明,以此來把背景部分透露出來。
不難看出,基本原理還是靠操作背景。所以不僅是文字漸變,鏤空的文字也可以通過background: whatever;
再加上-webkit-text-fill-color: transparent;-webkit-background-clip: text;
來實(shí)現(xiàn)。
有關(guān)knockout text的實(shí)現(xiàn)可參考css-tricks上的這篇。
7. 幀動(dòng)畫的實(shí)現(xiàn)
幀動(dòng)畫,也就是把動(dòng)畫分解,每一幀做成一張圖片,再把所有幀圖拼成一個(gè)長(zhǎng)圖。最后利用改變background-position
來實(shí)現(xiàn)動(dòng)畫。
舉例:
animation: lightning 2s steps(20) infinite;
在animation
中寫下自定義的動(dòng)畫名lightning
之后,設(shè)置一個(gè)steps(20)
(表示一共執(zhí)行20步,每一步的時(shí)間被2s平均分配)就可以了。
@keyframes lightning {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -3350px;
}
}
ps: 開發(fā)一定要和動(dòng)效師確認(rèn)好每一幀的停留時(shí)間(一般來說是40ms)。