# 常见的兼容性问题 浏览器有着大量不同的版本,不同种类的浏览器的内核也不尽相同,所以不同浏览器对代码的解析会存在差异,这就导致对页面渲染效果不统一的问题。 ## 初始化样式 因浏览器兼容的问题,不同的浏览器对标签的默认样式值不同,如果不初始化会造成不同浏览器之间的显示差异,布局出现错乱,所以要初始化样式,达到统一的布局。 最粗暴的方案就是使用`*`初始化样式,但是其会对于所有的标签加载样式以及计算样式优先级,可能会对性能有所影响。 ```css * { margin: 0; padding: 0; } ``` 通常使用`Normalize.css`抹平默认样式差异,当然也可以根据样式定制自己的`reset.css`。 ```html ``` ## 内核样式兼容 在`CSS3`标准还未确定时,部分浏览器已经根据最初草案实现了部分功能,为了与之后确定下来的标准进行兼容,所以每种浏览器使用了自己的私有前缀与标准进行区分,当标准确立后,各大浏览器将逐步支持不带前缀的`CSS3`新属性,目前已有很多私有前缀可以不写了,但为了兼容老版本的浏览器,可以仍沿用私有前缀和标准方法,逐渐过渡。 |内核| 代表浏览器 | 前缀 | | --- | --- | --- | | Trident | IE浏览器 | -ms | | Gecko | Firefox | -moz | | Presto | Opera | -o | | Webkit | Chrome、Safari | -webkit | ## 透明属性 用来设定元素透明度的`opacity`是`CSS 3`里的一个属性,现代浏览器都已经支持,对于老版本浏览器可以通过加入私有前缀来支持,对于`IE6-IE8`可以通过`filter`属性来支持,`IE4-IE9`都可以通过滤镜写法提供兼容支持。 ```css 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`来作为兼容性解决方案。 ```html ``` ## HTML5标签 对于`IE9`以下浏览器不支持`HTML5`新标签的问题,可以使用`document.createElement`创建元素并设置其`CSS`样式即可,通常使用`html5shiv.js`来作为兼容性解决方案。 ```html ``` ```html ``` ## placeholder兼容性 `placeholder`是`html5`新增的一个属性,当`input`或者`textarea`设置了该属性后,该值的内容将作为灰字提示显示在文本框中,当文本框获得焦点或输入内容时,提示文字消失。对于其兼容性首先需要判断`input`是否支持`placeholder`,然后在不支持的情况下可以通过`input`的`onfocus`与`onblur`事件监听来实现`placeholder`效果。 ```html ``` ## 事件监听句柄 在`IE9`之前,必须使用`attachEvent`而不是使用标准方法`addEventListener`来注册元素的监听器,事件兼容的问题,通常需要会封装一个适配器的方法,过滤事件句柄绑定、移除。 ```javascript 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`会同时阻止默认行为与事件传播,通常也会封装一个方法来实现默认行为的阻止。 ```javascript 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;`,通常也会封装一个方法来实现阻止事件冒泡。 ```javascript handler.stopPropagation = function(event) { event = event || window.event; if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = false; } } ``` ## 滚动高度 获取窗口的滚动高度`scrollTop`需要采用兼容性写法,即使声明``浏览器对于文档的处理也会有所不同。 ```javascript var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; ``` ## 日期时间 使用`new Date()`构造函数生成日期时间对象,对于`new Date("2020-06-29")`语法在一些早期的浏览器会输出`invalid date`,这主要是因为早期浏览器不支持表达日期的`-`,而`/`才是被广泛支持的,所以在处理早期浏览器的兼容性时需要将`-`替换为`/`。 ```javascript new Date("2020-06-29".replace(/-/g, "/")); ``` ## IE条件注释 `IE`专门提供的一种语法,只有IE能识别运行,其他浏览器只会作为注解。 ```html ``` ```html ``` ```html ``` ## 每日一题 ``` https://github.com/WindrunnerMax/EveryDay ``` ## 参考 ``` https://www.jianshu.com/p/c0b758a88c7c https://juejin.im/post/5b3da006e51d4518f140edb2 https://juejin.im/post/59a3f2fe6fb9a0249471cbb4 ```