常見的兼容性問題
瀏覽器有着大量不同的版本,不同種類的瀏覽器的內核也不盡相同,所以不同瀏覽器對代碼的解析會存在差異,這就導致對頁面渲染效果不統一的問題。
初始化樣式
因瀏覽器兼容的問題,不同的瀏覽器對標簽的默認樣式值不同,如果不初始化會造成不同瀏覽器之間的顯示差異,布局出現錯亂,所以要初始化樣式,達到統一的布局。
最粗暴的方案就是使用*
初始化樣式,但是其會對於所有的標簽加載樣式以及計算樣式優先級,可能會對性能有所影響。
* {
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