时间:2021-05-18
其最经典的运用莫过于通用的addEvent函数: function addEvent(element, type, handler) { if (element.attachEvent) { //IE8及以下浏览器 element.attachEvent('on' + type, handler); } else { //W3C标准浏览器 element.addEventListener(type, handler, false); } };
函数可以通过检测attachEvent函数是否存在,以决定使用attachEvent或者addEventListener,这也是最简单的一种特性检测,因而通常在需要时才进行实时的检测。另一种特性检测由于检测的过程较为麻烦,因此会预先完成检测,将检测的结果(通常是Boolean类型)保存在某个变量中。
本文的主要目标是分析、说明在jQuery1.4中浏览器特性检测新增的内容,同时加深浏览器兼容性方面几个细节的记忆。
jQuery1.4主要增加了以下几个浏览器特性标识,本文针对它们一一进行分析:
使用以下代码可以检测该特性:
<input id="checkOn" type="checkbox" /> <script type="text/javascript"> alert(document.getElementById('checkOn').value); </script>以下为各浏览器中运行结果:
IE6onIE7onIE8onIE9 betaonFirefox 3.6onChrome 7[空字符串]Safari 5on经测试,除Chrome外,所有浏览器都会给没有value的checkbox一个默认的value值”on”。
该特性被jQuery用来获取checkbox和radio的值,兼容的判断语句如下:
//不支持checkOn的浏览器都不存在property/attribute混用问题,因此需要明确使用getAttribute return support.checkOn ? element.value : (element.getAttribute('value') === null ? 'on' : element.value);使用以下代码可以检测该特性:
<select id="optSelected"> </select> <script type="text/javascript"> var select = document.getElementById('optSelected'), option = document.createElement('option'); select.appendChild(option); alert(option.selected); </script>以下为各浏览器中运行结果:
IE6falseIE7falseIE8falseIE9 betafalseFirefox 3.6trueChrome 7trueSafari 5false经测试,IE系列和Safari使用appendChild对空的select元素添加一个option后,该option的selected属性不会被默认设置为true。
该问题引起的BUG描述如下:
部分浏览器在获取option的selected属性时,会错误地返回false。
该问题的解决方案是在访问selected属性时,先访问其父级select元素的selectedIndex属性,强迫浏览器计算option的selected属性,以得到正确的值。需要注意的是option元素的父元素不一定是select,也有可能是optgroup。具体代码如下:
if (!support.optSelected) { var parent = option.parentNode; parent.selectedIndex; //处理optgroup时的情况 if (parent.parentNode) { parent.parentNode.selectedIndex; } } return option.selected;使用以下代码可以检测该特性:
<select id="optDisabled" disabled="disabled"> <option></option> </select> <script type="text/javascript"> var select = document.getElementById('optDisabled'), option = select.getElementsByTagName('option')[0]; alert(option.disabled); </script>以下为各浏览器中运行结果:
IE6falseIE7falseIE8falseIE9 betafalseFirefox 3.6falseChrome 7falseSafari 5true经测试,Safari会将设置了disabled的select中的option也同样设置上disabled。
这个特性用来获取select元素的value值,特别是当select渲染为多选框时,需要注意从中去除disabled的option元素,但在Safari中,获取被设置为disabled的select的值时,由于所有option元素都被设置为disabled,会导致无法获取值。
因此有optDisabled(true表示option不会被自动设置disabled)后,可以有这样的代码:
//如果optDisabled为true,则disabled属性返回的是option的真实状态 //否则判断disabled属性是否为null var disabled = support.optDisabled ? option.disabled : option.getAttribute('disabled') !== null; if (!disabled) { return option.value; }使用以下代码可以检测该特性:
<div id="checkClone"> <input type="radio" name="checkClone" checked="checked" /> </div> <script type="text/javascript"> var fragment = document.createDocumentFragment(), div = document.getElementById('checkClone'), radio = div.getElementsByTagName('input')[0]; fragment.appendChild( radio ); alert(fragment.cloneNode(true).cloneNode(true).lastChild.checked); </script>需要注意的是,重现这个问题,需要给input显式地指定一个name属性,并且在复制fragment对象时连续调用2次cloneNode函数。
以下为各浏览器中运行结果:
IE6trueIE7trueIE8trueIE9 betatrueFirefox 3.6trueChrome 7trueSafari 5trueSafari 4false由结果可以看出,该问题出现在Safari 4中,并且已经在Safari 5得到修复,介于Safari在市场中的占有率以及版本较老的原因,这个问题确实不需要太多的重视。
这个特性的使用场合极少,在开发中几乎不会有如此严格的环境(对DocumentFragment连续调用2次cloneNode),在jQuery中,该特性用做buildFragment这个内部函数中的缓存功能,jQuery会对比较简单的创建DOM元素的字符串的创建结果缓存到DocumentFragment中,但当遇到创建radio时,如果cloneNode为false,则强制不进行缓存。
这是一个历史久远的问题,IE7以下版本并不支持display: inline-block;样式,而是使用display: inline;并通过其他样式触发其hasLayout形成一种伪inline-block的状态(具体请点击这里)。
inline-block与inline的一个重要区别在于,inline-block的元素可以显式地设置宽和高,因此可以用以下代码检测该特性:
<div id="inlineBlockNeedsLayout" style="width: 1px; padding-left: 1px; display: inline; zoom: 1;"> </div> <script type="text/javascript"> var div = document.getElementById('inlineBlockNeedsLayout'); alert(div.offsetWidth); </script>以下为各浏览器中运行结果:
IE62IE72IE81IE9 beta1Firefox 3.61Chrome 70Safari 50对于inline元素,width样式是无效的,在该测试中,webkit系浏览器均获取了0,IE8以上版本及Firefox获取了1,只有IE7及以下版本同时计算了width和padding-left,得到了2px的宽度。
这个功能可以用于设置元素的css样式,当需要设置为inline-block时,针对IE7及以下浏览器可以同时设置display: inline;和zoom: 1;来模拟效果,核心代码如下:
if (name == 'display' && value == 'inline-block') { if (support.inlineBlockNeedsLayout) { element.style.display = 'inline'; element.style.zoom = 1; } else { element.style.display = value; } };当然这样直接这样使用肯定是有问题的,当需要获取display样式的时候怎么办呢?同时判断zoom和display吗?并且hasLayout会引起一些其他的问题。
因此,jQuery只将该特性用于动画效果,当需要对width和height进行动画,并且元素是inline时,首先设置为(伪)inline-block状态,动画结束后将相关样式恢复。
这个问题的详细解释可以参考此处,使用以下代码可以检测该特性:
<div id="shrinkWrapBlocks" style="width: 1px; zoom: 1;"> <div style="width: 4px;"> </div> </div> <script type="text/javascript"> var div = document.getElementById('shrinkWrapBlocks'), inner = div.getElementsByTagName('div')[0]; alert(div.offsetWidth); </script>以下为各浏览器中运行结果:
IE64IE71IE81IE9 beta1Firefox 3.61Chrome 71Safari 51测试结果表明,IE6即使显式设定了宽度,在触发了hasLayout的情况下,其大小会受子元素的影响而被撑大。
jQuery将该特性用于动画效果,为了动画过程中改变一个元素的width/height时,其子元素不会溢出,jQuery做了以下几步:
这个问题在上两天工作中遇到,刚好jQuery1.4.3升级了这方面的内容,使用以下代码可以检测该特性:
<table id="reliableHiddenOffsets"> <tbody> <tr> <td style="display: none;"> </td> <td> abcd </td> </tr> </tbody> </table> <script type="text/javascript"> var table = document.getElementById('reliableHiddenOffsets'), td = table.getElementsByTagName('td')[0]; alert(td.offsetHeight); </script>以下为各浏览器中运行结果:
IE60IE70IE821IE9 beta0Firefox 3.60Chrome 70Safari 50只有IE8存在这个问题,那当td元素的display为none时,其高度依旧会受其所在行的高度的影响,而不是0。
这个问题的存在根本上导致了对元素可见性的判定出现差错,原本判断一个元素是否隐藏的代码是这样的:
function isHidden(element) { return element.offsetWidth == 0 || element.offsetHeight == 0; };因为这个BUG的出现,上面的函数对于td元素失去了效果,因此需要改进为:
function isVisible(element) { return (element.offsetWidth == 0 && element.offsetHeight == 0) || (!support.reliableHiddenOffsets && getStyle(element, 'display') == 'none'); };阅读jQuery源码的时候,会发现这一段的判断里多了一句element.style.display,这一句是用来判断元素有display值才去取来看看是不是none的,以免获取运行时样式的开销。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
其中jQuery.browser已经提供了根据UserAgent检测的浏览器信息。而jQuery.support使用特性检测来检查浏览器的功能以及Bug。和文档
便利的设置函数jquery1.4的大部分设置值对方法都可以设置第二个参数为回调函数。比如:.css(),.attr(),.val(),.html(),.text
下面的checkBrowser()函数主要检测了三种浏览器(IE,firefox,chrome),其它的浏览器的检测有兴趣的朋友可以自行添加检测代码!HTML部
前言特性查询赋予了我们使用CSS检测浏览器是否支持某个css特性的能力。我们可以使用该功能在浏览器支持最新的CSS特性时,使用新的语法来编写我们的样式,同时对于
基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,删除已上传文件。要求使用jquery1.4或以上版本,flashpl