常見的相容性問題
瀏覽器有著大量不同的版本,不同種類的瀏覽器的核心也不盡相同,所以不同瀏覽器對程式碼的解析會存在差異,這就導致對頁面渲染效果不統一的問題。
初始化樣式
因瀏覽器相容的問題,不同的瀏覽器對標籤的預設樣式值不同,如果不初始化會造成不同瀏覽器之間的顯示差異,佈局出現錯亂,所以要初始化樣式,達到統一的佈局。
最粗暴的方案就是使用*
初始化樣式,但是其會對於所有的標籤載入樣式以及計算樣式優先順序,可能會對效能有所影響。
* {
margin: 0;
padding: 0;
}
通常使用Normalize.css
抹平預設樣式差異,當然也可以根據樣式定製自己的reset.css
。
<link href="https://cdn.bootcss.com/normalize/7.0.0/normalize.min.css" rel="stylesheet">
核心樣式相容
在CSS3
標準還未確定時,部分瀏覽器已經根據最初草案實現了部分功能,為了與之後確定下來的標準進行相容,所以每種瀏覽器使用了自己的私有字首與標準進行區分,當標準確立後,各大瀏覽器將逐步支援不帶字首的CSS3
新屬性,目前已有很多私有字首可以不寫了,但為了相容老版本的瀏覽器,可以仍沿用私有字首和標準方法,逐漸過渡。
核心 | 代表瀏覽器 | 字首 |
---|---|---|
Trident | IE瀏覽器 | -ms |
Gecko | Firefox | -moz |
Presto | Opera | -o |
Webkit | Chrome、Safari | -webkit |
透明屬性
用來設定元素透明度的opacity
是CSS 3
裡的一個屬性,現代瀏覽器都已經支援,對於老版本瀏覽器可以通過加入私有字首來支援,對於IE6-IE8
可以通過filter
屬性來支援,IE4-IE9
都可以通過濾鏡寫法提供相容支援。
opacity: 0.5;
-moz-opacity:0.5;
filter: alpha(opacity = 50); //IE6-IE8
filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50); //IE4-IE9
媒體查詢
對於IE9
以下瀏覽器不支援CSS3
媒體查詢的問題,通常使用respond.js
來作為相容性解決方案。
<script type="text/javascript" src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
HTML5標籤
對於IE9
以下瀏覽器不支援HTML5
新標籤的問題,可以使用document.createElement
建立元素並設定其CSS
樣式即可,通常使用html5shiv.js
來作為相容性解決方案。
<script>
document.createElement('header');
</script>
<style>
header{display: block;}
</style>
<script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
placeholder相容性
placeholder
是html5
新增的一個屬性,當input
或者textarea
設定了該屬性後,該值的內容將作為灰字提示顯示在文字框中,當文字框獲得焦點或輸入內容時,提示文字消失。對於其相容性首先需要判斷input
是否支援placeholder
,然後在不支援的情況下可以通過input
的onfocus
與onblur
事件監聽來實現placeholder
效果。
<!-- 簡單示例 -->
<input type="text" value="Tips" onFocus="this.value = '';" onBlur="if (this.value == '') {this.value = 'Tips';}">
事件監聽控制程式碼
在IE9
之前,必須使用attachEvent
而不是使用標準方法addEventListener
來註冊元素的監聽器,事件相容的問題,通常需要會封裝一個介面卡的方法,過濾事件控制程式碼繫結、移除。
var handler = {}
//繫結事件
handler.on = function(target, type, handler) {
if(target.addEventListener) {
target.addEventListener(type, handler, false);
} else {
target.attachEvent("on" + type,
function(event) {
return handler.call(target, event);
}, false);
}
};
//取消事件監聽
handler.remove = function(target, type, handler) {
if(target.removeEventListener) {
target.removeEventListener(type, handler);
} else {
target.detachEvent("on" + type,
function(event) {
return handler.call(target, event);
}, true);
}
};
阻止預設行為
W3C
推薦的阻止預設行為的方式是event.preventDefault()
,此方法只會阻止預設行為而不會阻止事件的傳播。IE9
之前的瀏覽器阻止預設行為需要使用window.event.returnValue = false
。直接在事件處理函式中return false
也能阻止預設行為,只在DOM0
級模型中有效。此外,在jQuery
中使用return false
會同時阻止預設行為與事件傳播,通常也會封裝一個方法來實現預設行為的阻止。
handler.preventDefault = function(event) {
event = event || window.event;
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
阻止事件冒泡
W3C
推薦的阻止冒泡的方法是event.stopPropagation()
,IE9
之前則是使用window.event.cancelBubble = true;
,通常也會封裝一個方法來實現阻止事件冒泡。
handler.stopPropagation = function(event) {
event = event || window.event;
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = false;
}
}
滾動高度
獲取視窗的滾動高度scrollTop
需要採用相容性寫法,即使宣告<DOCTYPE>
瀏覽器對於文件的處理也會有所不同。
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
日期時間
使用new Date()
建構函式生成日期時間物件,對於new Date("2020-06-29")
語法在一些早期的瀏覽器會輸出invalid date
,這主要是因為早期瀏覽器不支援表達日期的-
,而/
才是被廣泛支援的,所以在處理早期瀏覽器的相容性時需要將-
替換為/
。
new Date("2020-06-29".replace(/-/g, "/"));
IE條件註釋
IE
專門提供的一種語法,只有IE能識別執行,其他瀏覽器只會作為註解。
<!--[if lt IE 9]>
<script type="text/javascript" src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->
<!--[if !IE]> 除IE外都可識別 <![endif]-->
<!--[if IE]> 所有的IE可識別 <![endif]-->
<!--[if IE 6]> 僅IE6可識別 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6以下版本可識別 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可識別 <![endif]-->
<!--[if IE 7]> 僅IE7可識別 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7以下版本可識別 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可識別 <![endif]-->
<!--[if IE 8]> 僅IE8可識別 <![endif]-->
<!--[if IE 9]> 僅IE9可識別 <![endif]-->
<!--
! NOT運算子
lt 小於運算子
lte 小於或等於運算子
gt 大於運算子
gte 大於或等於運算子
& AND運算子
| OR運算子
() 子表示式運算子 用於與布林運算子建立更復雜的表示式
-->
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://www.jianshu.com/p/c0b758a88c7c
https://juejin.im/post/5b3da006e51d4518f140edb2
https://juejin.im/post/59a3f2fe6fb9a0249471cbb4