兼容性

JavaScript之浏览器兼容问题

JS浏览器兼容问题说明

兼容问题介绍

由于每个版本的浏览器对JS的支持都不同,当实现某个功能时,就需要惦记惦记前端开发的三个祖宗:IE6 IE7 IE8。

WEB前端开发

  • 在技术上:必须能做到掌握兼容性,提供兼容性问题的解决方案。
  • 在需求上:商量着来,提供最准确的呈现方案,比如:给前端开发人员展示的页面,就没有必要支持IE那些低版本的浏览器。

兼容解决思路

很多时候,JS解决问题可以是很巧妙的,回避那些兼容性问题,在视觉上达到最终的效果,然后选一种最优化的方法,这是一种思路,不要去和浏览器较劲,绕着点。

表单的兼容性问题

示例1:修改表单的type属性

<!doctype html>
<html>
	<head>
		<meta charset="utf-8"/>
		<title>修改表单的type属性</title>
	</head>
	<body>
		<input type="button" id="chgInp"/>
		<script type="text/javascript">
			var oInput = document.getElementById('chgInp');
			oInput.onclick = function () {
				oInput.type = 'checkbox';
			};
		</script>
	</body>
</html>

NOTE

  • 以上代码在IE6、IE7、IE8下就会报语法错误,而在IE9+和其它非IE浏览器下则不会报错

解决方法:

  • 这段代码所要实现的效果无非是想点击button之后,更换成checkbox,其实只要点击button之后,让button隐藏起来,让checkbox在button的位置上显示出来即可。

中文路径的兼容性问题

示例1:img标签src路径判断问题

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>判断图片的地址问题</title>
</head>
<body>
	<img src="../images/图片1.gif" id="img1"/>

	<script type="text/javascript">
		var oImg = document.getElementById('img1');
		var oTxt = document.getElementById('txt1');
		var _arr = oImg.src.split('/');
		alert(_arr[_arr.length - 1] == '图片1.gif');
	</script>
</body>
</html>

上述代码的输出结果:

  • IE6+ 输出:**true **
    图片1.gif -> 解析成 -> 图片1.gif
  • FireFox、Chrome 输出:false
    图片1.gif -> 解析成 -> %E5%9B%BE%E7%89%871.gif

NOTE

  • 虽然在src中写的是相对路径,但是在js中获取的却是绝对地址,所以上述代码中截取了最后一个斜杠(/)后面的内容进行比较。
  • 通过输出结果可以得到,不同的浏览器对中文文件名(路径)的解析是不同的,所以中文文件名(路径)尽量不要拿来比较,如:img的src、link和a的href等等。

CSS样式操作的兼容性问题

示例1:JS中对浮动的操作

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>兼容性问题:浮动</title>
	<style type="text/css">
		#div1{width:200px;height:200px;background:pink;text-align:center;
			line-height:200px;color:#fff;cursor:pointer;}
	</style>
</head>
<body>
	<div id="div1">我是div</div>
	<script type="text/javascript">
		var oDiv = document.getElementById('div1');
		oDiv.onclick = function () {
			// oDiv.style.float = 'right'; IE9+ 、 FireFox、Chrome支持
			oDiv.style.styleFloat = 'right';    // IE6+支持
			oDiv.style.cssFloat = 'right';  // IE9+、FireFox、Chrome支持
		};
	</script>
</body>
</html>

NOTE

  • JS中操作CSS的浮动有三种写法:
    -- 1、elem.style.float = 'right'; //IE9+、FireFox、Chrome支持
    -- 2、oDiv.style.styleFloat = 'right'; // IE6+支持,也就是仅IE支持
    -- 3、oDiv.style.cssFloat = 'right'; // IE9+、FireFox、Chrome支持

所以使用JS的方式去操作浮动,是需要写两行代码来兼容浏览器的,这种方式是比较麻烦的,还有一种思路就是使用JS增加class属性来控制浮动样式:

解决方法

  • 解决思路
    提前写好样式:.right{float:right;},然后使用JS将right增加到class属性值中,修改class的属性值即可。

  • 代码示例

<!doctype html>

兼容性问题:浮动
我是div
> ```

示例2:JS需要控制的hover样式

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>hover</title>
	<style type="text/css">
		.active{padding:5px 8px;background:pink;color:#fff;
			text-align:center;line-height:26px;text-decoration:none;}
		.active:hover{background:cyan;}
	</style>
</head>
<body>
	<a class="active" href="javascript:void(0);">hover样式</a><br/><br/>
	<span class="active">hover样式</span><br/><br/>
	<strong class="active">hover样式</strong><br/><br/>
	<em class="active">hover样式</em>
</body>
</html>

NOTE

  • 虽然hover伪类样式是属于CSS的内容,但是在JS中还是需要注意一下的,在IE6中,只有a标签才支持hover伪类,所以如果使用其他标签控制鼠标移入移出样式,就需要使用JS的onmouseover和onmouseout进行控制了。

示例3:JS获取页面元素的CSS样式

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>JS获取页面元素的CSS样式</title>
	<style type="text/css">
		#div1{width:350px;height:100px;background:red;}
	</style>
	<script type="text/javascript">
		window.onload = function () {
			var oDiv = document.getElementById('div1');
			oDiv.style.width = '200px';
			oDiv.style.cssText = 'width:300px;';

			/**
			 *  获取已定义的单一样式
			 */
			alert(getStyle(oDiv, 'height'));// 100px
			alert(getStyle(oDiv, 'width')); // 300px

			/**
			 *  获取已定义的复合样式
			 *  Chrome:输出rgb(255, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box
			 *  FireFox:输出''空字符串
			 *  IE6:输出undefined
			 *  IE9:输出''空字符串
			 */
			alert(getStyle(oDiv, 'background'));
			/**
			 *  获取未定义的样式
			 *  Chrome、FireFox:输出0px
			 *  IE:输出auto
			 */
			alert(getStyle(oDiv, 'marginLeft'));
			/**
			 * 封装函数getStyle
			 * @param obj
			 * @param attr
			 * @returns {*}
			 */
			function getStyle(obj, attr) {
				return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
			}
		};
	</script>
</head>
<body>
	<div id="div1" style="width:100px;"></div>
</body>
</html>

NOTE

  • JS获取页面元素的4种方式:
    -1:elem.style.样式【获取行内样式中指定的样式】
    -2:elem.style.cssText【获取行内样式的全部样式】
    -3:elem.currentStyle.样式【获取页面元素最终样式中指定的样式,支持的浏览器:IE6、7、8】
    -4:getComputedStyle(elem).样式【获取页面元素最终样式中指定的样式,支持的浏览器:IE9+、Chrome、FireFox】
  • 虽然上述代码中封装的getStyle函数已经解决了浏览器的兼容性问题,但是使用这个函数的时候还是有注意事项的:
    -1:不要使用getStyle函数去获取复合样式进行比较操作,如:background、border、margin等。
    -2:不要使用getStyle函数去获取没有定义的样式进行比较操作。
    ----------------------------------------详细原因见代码注释

示例4:FireFox低版本的getComputedStyle参数Bug(已过时)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>FireFox的getComputedStyle参数问题(已过时)</title>
	<style type="text/css">
		#div1{width:100px;height:100px;}
	</style>
	<script type="text/javascript">
		window.onload = function () {
			var oDiv = document.getElementById('div1');
			alert(getComputedStyle(oDiv, 'old FireFox is 250').width);
		};
	</script>
</head>
<body>
	<div id="div1"></div>
</body>
</html>

NOTE

关于getComputedStyle这个函数,在很多时候会见到其他人的代码里面,会写第二个参数,这个参数可以写任意的内容,比如说:0、false、字符串、对象等等。

其实这是一个历史遗留问题,在火狐的4.0之前,getComputedStyle函数有这样一个bug,如果后面不加第二个参数,就获取不到你想要的样式,只要你加了这个参数,任何参数内容都可以,就能够获取到样式了。

还是那句话,FireFox是联网自动更新,现在很少有人在用低版本的FireFox了,除非他不联网,所以这个Bug可能早就过时了,当然这个参数写也行,不写也行。


作用域的兼容性问题

示例1:FireFox低版本的作用域Bug(已过时)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title>FireFox低版本的作用域Bug</title>
</head>
<body>
	<script type="text/javascript">
		if (true) {
			var a = 1;

			function fn1() {
				// 正常情况下,该函数属于全局作用域下定义的
				console.log('Hello JavaScript!!!');
			}
		}
		alert(fn1);
	</script>
</body>
</html>

NOTE

  • 上述代码正确的运行结果应该是:整个函数连同注释一并弹出来
function fn1() {
// 正常情况下,该函数属于全局作用域下定义的
console.log('Hello JavaScript!!!');

}

- 因为在JavaScript中是不存在块作用域的,包括if、while、do...while、for,所以定义在这些块中变量、函数都会绑定在外部的作用域中,所以正常fn1函数在外部作用域中是可以找得到的。


**但是在FireFox的低版本浏览器中,则会报错,找不到fn1函数,而在IE6+和Chrome等浏览器中都没有问题,当然也不需要担心这个问题,因为FireFox浏览器是联网自动更新的,现在已经解决了这个Bug,但是还是建议将变量和函数的定义拿到外面去。**
posted @ 2015-10-17 19:42  ScFontEnd  阅读(171)  评论(0)    收藏  举报