细说浏览器特性检测(1)(2)

这个特性用来获取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; } checkClone

使用以下代码可以检测该特性:

<div> <input type="radio" 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函数。

以下为各浏览器中运行结果:

IE6   true  
IE7   true  
IE8   true  
IE9 beta   true  
Firefox 3.6   true  
Chrome 7   true  
Safari 5   true  
Safari 4   false  

由结果可以看出,该问题出现在Safari 4中,并且已经在Safari 5得到修复,介于Safari在市场中的占有率以及版本较老的原因,这个问题确实不需要太多的重视。

这个特性的使用场合极少,在开发中几乎不会有如此严格的环境(对DocumentFragment连续调用2次cloneNode),在jQuery中,该特性用做buildFragment这个内部函数中的缓存功能,jQuery会对比较简单的创建DOM元素的字符串的创建结果缓存到DocumentFragment中,但当遇到创建radio时,如果cloneNode为false,则强制不进行缓存。

inlineBlockNeedsLayout

这是一个历史久远的问题,IE7以下版本并不支持display: inline-block;样式,而是使用display: inline;并通过其他样式触发其hasLayout形成一种伪inline-block的状态(具体请点击这里)。

inline-block与inline的一个重要区别在于,inline-block的元素可以显式地设置宽和高,因此可以用以下代码检测该特性:

<div> </div> <script type="text/javascript"> var div = document.getElementById('inlineBlockNeedsLayout'); alert(div.offsetWidth); </script>

以下为各浏览器中运行结果:

IE6   2  
IE7   2  
IE8   1  
IE9 beta   1  
Firefox 3.6   1  
Chrome 7   0  
Safari 5   0  

对于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状态,动画结束后将相关样式恢复。

shrinkWrapBlocks

这个问题的详细解释可以参考此处,使用以下代码可以检测该特性:

<div> <div> </div> </div> <script type="text/javascript"> var div = document.getElementById('shrinkWrapBlocks'), inner = div.getElementsByTagName('div')[0]; alert(div.offsetWidth); </script>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdxyjp.html