浏览器占比现状
在各大浏览器厂商的发展过程当中,他们其实对web的标准都有不一样的实现,由于实现的标准的不一样,因此会有兼容性的产生,早期IE是在浏览器的世界中,占据主导地位。因此它自身实现了不少不一样于标准浏览器的东西,有css的,也有js的。css
从IE8开始,IE浏览器渐渐遵循标准,到IE9后因为你们都一致认为标准很重要,能够说在兼容性上比较好了,可是在中国来讲,因为xp的占有率问题,仍是有不少xp系统ie七、8浏览器。
国家互联网应急中心(CNCERT)2018年第四季度国内操做系统及浏览器占比状况分析:




js兼容问题及解决
一、js中 style、currentStyle和getComputedStyle的区别
1.1
style
:各大浏览器都兼容,能设置样式和获取样式,可是获取不了外部样式。
写法:ele.style.attr(这样为获取),ele.style.attr="值";
1.2.
currentStyle
:该属性只兼容IE,不兼容火狐和谷歌
ele.currentStyle.attr
;
1.3.
getComputedStyle
:该属性是兼容火狐谷歌,不兼容IE8及如下
window.getComputedStyle(ele,null).attr
一般使用
getComputedStyle
读取样式,经过
element.style
修改样式。
可选[pseudoElt]属性:指定一个要匹配的伪元素的字符串。不须要伪元素能够为null
配合该属性能够从伪元素拉取样式信息:好比,
::after, ::before
getComputedStyle(oDiv, '::after').content;
html
//兼容性写法:
function getStyle(ele,attr){
html5
if(ele.currentStyle){
css3
return ele.currentStyle[attr]
web
}else{
正则表达式
return getComputedStyle(obj,false)[attr]
chrome
}
浏览器
}
框架
2. 使用event对象
以主流浏览器 IE、谷歌、火狐为例:
(1) IE 在IE中,event 是一个全局的变量,不存在做用域的问题。也就是说,谁触发了事件,那在事件绑定的函数中,你能够直接使用event的属性作任何操做,没有做用域的限制,也没有其余函数格式的要求。
(2)Chrome 谷歌 谷歌作的也不错,使用也没有什么问题。在 Chrome 中,event并非全局变量。他是在每一个事件绑定的函数中都默认传入了一个形参event,注意函数的第一个形参就是event对象,并且咱们不须要去写这个形参。若是你要在事件绑定的函数中使用 event,那直接 event . 点他的属性便可。系统默认将event对象以参数的形式传递到了函数中。这里不须要你作任何操做,只管用,简单粗暴。
IE 和 Chrome 虽然看起来用法同样,其实仍是有本质区别的,只是浏览器封装的好而已。
(3)Firebox 火狐 火狐就麻烦一点了。由于火狐中压根就没有event这个变量。不过解决方法也是很简单的:
1.2.1 用户不传参:
想要使用 event,咱们就须要先使用以下语句
var e = arguments.callee.caller.arguments[0] || window.event
arguments.callee.caller.arguments[0]:
函数体自己-->函数体的调用函数体--> function onclick()
argument.callee.caller.arguments[0]
即为传参集合的第一个形参event了.
1.2.2. 传参(event)
3.获取目标元素:
兼容写法:
event.srcElement ? event.srcElement : event.target;
srcElement:ie
4. attachEvent和addEventListener
4.1 attachEvent是IE有的方法,它不遵循W3C标准,而其余的主流浏览器如FF等遵循W3C标准的浏览器都使用addEventListener,因此实际开发中需分开处理。
4.2 屡次绑定后执行的顺序是不同的,attachEvent是后绑定先执行,addEventListener是先绑定先执行。
ele.attachEvent('onclick',function(){
console.log('test...')
dom
})//ie11以及以上不支持 chrome不支持 ff不支持
ele.addEventListener("click",function(){
console.log('ceshi...')
},false) //ie8及如下 不支持
5. 获取dom节点:
parentElement
获取对象层次中的父元素。
parentNode
获取文档层次中的父结点。

在Dom文档结构中,HTML页面每一部分都是由节点组成的,节点的类型一共有3种,元素节点,文本节点,属性节点,从图中能够看出属性节点属于元素节点的分支,通常不常考虑。
二者在一般状况下都是同样的,由于包含元素的节点只有多是元素节点,这里可能会有一个误区,有些人可能会想文本节点是否能够包含元素节点,来做为父节点,这里是不行的,文本节点只是文本自己,自身算一个节点,文本节点的父节点直接是元素节点。
两者惟一区别:
由于
parentElement
找的是
元素,所以当找到根部document时候就是出现值为null的报错,并且
parentNode
找的是
节点,固然就能够显示出来了!
bodyDom.parentNode.parentNode.parentNode.parentNode
---#document
bodyDom.parentElement.parentElement.parentElement.parentElement
---null
六、日期函数处理
IE8如下:
new Date().getFullYear() === new Date().getYear()
:获得的是当前年份 2019
IE九、标准浏览器:
new Date().getYear()
为 119
:获得的是当前年份(2019)与1900年的差值 119
七、集合类对象问题
问题说明:IE下,可使用 () 或 [] 获取集合类对象;Firefox下,只能使用 [ ]获取集合类对象。
解决方法:统一使用 [] 获取集合类对象。
八、鼠标按键编码的兼容
W3C标准下:0,1,2分别表明左,中,右三个键;
在ie11及以上 + 主流浏览器下 是符合W3C标准的,可是在ie10以及如下:
左中右分别为:1 4 2
function but(evt){
var e = evt || window.event;
if(evt){
return e.button;
} else if (window.event){
switch(e.button){
case 1: return 0;
case 4: return 1;
case 2: return 2;
}
}
}
九、8引出的其它问题:
ie中的
window.event
全局对象和 事件访问对象(传递的参数evt) 的区别:
1.DOM标准描述了一个Event对象,提供了触发事件的元素信息,并容许在脚本中获取该元素。
2. ie中的事件处理:
ie的全局event对象的属性不一样于DOM标准的event对象,但提供的数据相似。
区别:
DOM事件模型与IE事件模型之间的主要区别是事件信息的访问方式,以及获取引起事件的元 素的方式。
DOM是须要传送事件引用给处理函数,IE中直接经过全局的event访问;
DOM中获取获取引起事件的元素对象是经过tarfet属性,而IE是经过
srcElement
属性。
css兼容性问题
首先是<!DOCTYPE>的声明 位于位于HTML文档中的第一行,处于 <html> 标签以前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会致使文档以兼容模式呈现。
标准模式的排版 和JS运做模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点没法工做。
一、reset
最主要也是最多见的,就是浏览器对标签的默认支持不一样,因此咱们要统一,就要进行CSS reset 。可是不要为了reset而reset:
可是不少时候咱们的CSS reset过于臃肿,主要有两个问题:
1.1 把不少浏览器对元素的默认属性有设置了一边,好比div的padding和margin为0啊什么的,这是没有必要的
1.2 把一些很不经常使用的元素的设置也写进了CSS reset。
二、上下margin重合问题
相邻的两个div margin-left margin-right 不会重合,但相邻的margin-top margin-bottom会重合。
三、td高度的问题
table中td的宽度都不包含border的宽度,可是oprea和ff中td的高度包含了border的高度 。
解决: 设置line-height和height同样。在ie中若是td中的没有内容,那么border将不会显示。
四、兼容ie8 或者ie9 或任意ie版本浏览器
4. 1.条件注释法(IE10+已经不支持条件注释)
大于 gt || 大于等于 gte || 小于 lt || 小于等于 lte(
<!--[if gte IE 8]><![endif]-->
)
用ie浏览器独有的文档注释的方式。像这样:
<!DOCTYPE html>
<!--[if IE 8 ]> <html class="ie8" lang="en"> <![endif]-->
<!--[if IE 9 ]> <html class="ie9" lang="en"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html lang="en"> <!--<![endif]-->
能够独立的维护处理兼容ie浏览器的样式表,又不会淹没在一大堆css hack标识中,只须要在独立对ie8应用样式规则的地方
4.2. 非IE(IE10+也能识别),此处多加的<-->,在IE中被看成内部注释,而在非IE浏览器中会闭合以前的注释(<!--[if !IE]><--><![endif]-->)
<!--[if !IE]><-->
<div class="box" id="box"></div>
<![endif]-->
五、对于360双核浏览器
能够添加如下头部meta信息可使得网页用webkit内核渲染:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
IE=edge:保持使用最高级别模式显示内容;
chrome=1:谷歌的外挂插件Google Chrome Frame(谷歌内嵌浏览器框架GCF),使用IE浏览网页时其实是使用Chrome浏览器内核渲染,最低支持IE6,但前提是客户端已经安装GCF。
但实际上这个meta标识是ie浏览器所识别的,并非公认的标准,因此有时你会发现360并不能老是以chrome内核渲染你的按现代标准开发的网页。
能够试试经过添加:
<meta name="renderer" content="webkit">
六、ie8的css兼容
6.1 使用meta标签调节浏览器的渲染方式:
IE8中有一个“兼容性视图”的概念,当初IE8发布时,相对于IE6/7已经作出了很是大的改进,可是不少老站点仅针对IE6/7进行了优化,使用IE8渲染反而会一团糟。IE8加入了“兼容性视图”功能,这样的话就能够在IE8中使用IE6或IE7的内核渲染页面。这个固然不是咱们想要的,因此须要使用meta标签来强制IE8使用最新的内核渲染页面,代码以下:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
IE=edge表示强制使用IE最新内核,
chrome=1表示若是安装了针对IE6/7/8等版本的浏览器插件Google Chrome Frame(可让用户的浏览器外观依然是IE的菜单和界面,但用户在浏览网页时,实际上使用的是Chrome浏览器内核),那么就用Chrome内核来渲染。
对比360:
<meta name="renderer" content="webkit">
6.2 ie8中的一些css 不支持
6.2.1 ie8支持:
first-child
,但不支持:
last-child
。由于前者是css2.1标准,后者是css3标准。
推荐的作法不是使用last-child,而是给最后一个元素设置一个.last的class,而后对此进行样式设置,这样就所有兼容了。
6.2.2
html5shiv.js
IE8不支持HTML5的新标签,如
<header>
、
<nav>
等标签在IE8没法渲染。html5shiv.js可帮助IE6-8浏览器兼容HTML5语义化标签。
使用方法:在页面中引用html5shiv.js文件。必须添加在页面的<head>元素内,由于IE浏览器必须在元素解析前知道这个元素,因此这个js文件不能在页面底部引用。
6.2.3.
Respond.js
IE8不支持CSS媒体查询,对响应式设计大大不利。Respond.js可帮助IE6-8兼容“
min/max-width
”媒体查询条件。
使用方法:在页面中全部css文件的引用位置以后引用
Respond.js
。并且
Respond.js
的引用得越早,用户看到页面闪烁的机会越小。
6.2.4. CSS3字体单位“rem”兼容方案:
rem.js
CSS3引入了新的字体大小单位rem,与em的“相对于其父元素来设置字体大小”的功能不一样,rem是相对于根元素<html>的字体大小比率单位,成了目前主流的单位之一。IE9+开始支持,IE8就只能经过引入js库来支持了。
使用方法:在页面中引用rem.js文件。须要引用在页脚,也就是<body>末尾,在全部css文件引用和DOM元素以后。
6.2.5. 一些其它不支持的属性:
border-radius 圆角
box-shadow 盒子阴影
CSS3 Background 背景渐变
七、placeholder
不支持ie10-如下的版本(能够经过使用一个span标签来模拟提示。)
关于css优化问题:
一、不要使用*{} 相似的通配符
这种方法虽然写起来简单,可是渲染起来,浏览器引擎要遍历全部的标签,很影响效率。为了对浏览器友好,能够把本身常常用的标签进行重置操做。
二、尽可能少用绝对定位和浮动等高性能属性
虽然绝对定位能够很简洁的实现很棒的效果,可是因为浏览器的渲染机制,网页中若是用过多的绝对定位,会让网页加载速度变得很慢。
三、利用CSS继承减小代码量
咱们知道有一部分CSS代码是能够继承的,若是父元素已经设置了该样式,子元素就不须要去设置该样式,这个也是提升性能的行之有效的方法。
常见的能够继承的属性好比:
color,font-size,font-family,text-align,line-height等等
不可继承的好比:
position,display,float,display,background。width等等
四、CSS Sprites减小http请求
小图标 经过一张雪碧图 控制background-position来请求
五、合写css:
font
background
padding
margin
六、不要用标签或 class 来限制 ID 规则
不少人会写出#test.info或者div#test这样的选择器,这个只能说是多此一举,id已经能够惟一并且最快的定位一个元素了
七、避免通配选择器
CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,因此优化选择器的原则是应尽可能避免须要消耗更多匹配时间的选择器。而在这以前咱们须要了解CSS选择器匹配的机制,如例子的子选择器规则:
#header a {font-weight:blod;}
咱们中的大多数人都是从左到右的阅读习惯,可能也会习惯性的设定浏览器也是从左到右的方式进行匹配规则,由于会推测这条规则的开销并不高。咱们这样假象浏览器会像这样的方式工做:找到惟一的id为header为的元素,而后把这个样式规则应用到直系子元素中的a元素上。咱们知道文档中只有一个id为header的元素,而且它只有几个a类型的子节点,因此这个CSS选择器应该至关高效。
事实上,却刚好相反,CSS选择器是从右到左进行规则匹配。了解这个机制后,例子中看似高效的选择器在实际中的匹配开销是很高的,浏览器必须遍历页面中全部的a元素而且肯定其父元素的id是否为header。
若是把例子的子选择器改成后代选择器则会开销更多,在遍历页面中全部a元素后还需向其上级遍历直到根节点。
#header a {font-weight:blod;}
理解了CSS选择器从右到左匹配的机制后,能够理解选择器中最右边的规则每每决定了浏览器继续左移匹配的工做量,咱们把最右边选择规则称之为关键选择器。
通配选择器使用 * 符合表示,可匹配文档中的每个元素。以下例规则将全部元素的字体大小设置为20px:
* { font-size:20px;}
通配选择器做用于全部的元素,如规则最右边为通配符:
.selected * {color: red;}
浏览器匹配文档中全部的元素后分别向上逐级匹配class为selected的元素,直到文档的根节点,所以其匹配开销是很是大的,一般比开销最小的ID选择器高出1~3个数量级,因此应避免使用关键选择器是通配选择器的规则。
八、避免单规则的属性选择器
属性选择器根据元素的属性是否存在或其属性值进行匹配,以下例规则会把herf属性值等于”#index”的连接元素设置为红色:
.selected [href=”#index”] {color: red;}
但其匹配开销是很是大的,浏览器先匹配全部的元素,检查其是否有href属性而且herf属性值等于”#index”, 而后分别向上逐级匹配class为selected的元素,直到文档的根节点。因此应避免使用关键选择器是单规则属性选择器的规则。
九、避免类正则的属性选择器
CSS3添加了复杂的属性选择器,能够经过类正则表达式的方式对元素的属性值进行匹配。固然这些类型的选择器定是会影响性能的,正则表达式匹配会比基于类别的匹配会慢不少。大部分状况下咱们应尽可能避免使用 *=, |=, ^=, $=, 和 ~=语法的属性选择器。
十、移除无匹配的样式:
移除无匹配的样式,有两个好处:
第一,删除无用的样式后能够缩减样式文件的体积,加快资源下载速度;
第二,对于浏览器而言,全部的样式规则的都会被解析后索引发来,即便是当前页面无匹配的规则。移除无匹配的规则,减小索引项,加快浏览器查找速度;