众所周知,IE 的 HTMLElement 对象不支持 hasAttribute 方法,于是有了如下实现: 它针对不支持 hasAttribute 方法的浏览器,检查 getAttribute 得到的是否等于 null, 如果是 null 则表明这个 HTMLElement 不存在指定的 Attribute。很聪明的一个方法。
最近写了个原理简单的基于 Select+Input 的可编辑 Combox 控件,用到了这个方法来检查目标 select 对象是否存在如 multiple, editable 这样的属性,来实现不同的 Combox 版本。其他 浏览器上跑的很好,但是在 IE6 上却总是被初始化为 multiple 的实例,很明显,这个 hasAttribute 的实现出问题了。
原来针对 IE6,还有稍多一点的特殊性:
input.getAttribute("checked")
返回 Boolean 值,true/false;input[type=checkbox|radio].getAttribute("checked")
根据他的 checked 状态相关;input[type=others...].getAttribute("checked")
始终返回 false;
select.getAttribute("multiple")
返回 Boolean 值;select>option.getAttribute("selected")
返回 Boolean 值。
虽然可以通过 getAttribute("checked") 判断 checkbox/radio 的属性状况,但对于 其他类型的 input 元素,是无法准确获得 checked 属性的。
TODO: checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected
下面是比较完整一点的实现:
function hasAttr(elem, attr){ var tag = elem.tagName.toLowerCase(); attr = attr.toLowerCase(); if(elem.hasAttribute){ return elem.hasAttribute(attr); } if(navigator.userAgent.indexOf("MSIE 6")>0 && (("input"==tag && "checked"==attr) || ("option"==tag && "selected"==attr) || ("select"==tag && "multiple"==attr))){ return elem.getAttribute(attr); } return null!=elem.getAttribute(attr); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-- Update 2011/07/26 --
继续发现新坑:IE 中下面的代码
输出:
所以上面的 hasAttr
函数是无法正确返回这种在脚本中设置 onclick
值的。
对策:
var hasAttr = function(elem, attr){ if(!elem || 1!=elem.nodeType){return false;} if(elem.hasAttribute){return elem.hasAttribute(attr);} // for IE, not perfect. // @see http://www.patmullin.com/weblog/2006/04/06/getattributestyle-setattributestyle-ie-dont-mix/ attr = attr.toLowerCase(); if("style" == attr){return "" !== elem.style.cssText;} if(navigator.userAgent.indexOf("MSIE 6")>0 && (("input"==tag && "checked"==attr) || ("option"==tag && "selected"==attr) || ("select"==tag && "multiple"==attr))){ return elem.getAttribute(attr); } var val = elem.getAttribute(attr); if(null == val){return false;} else if("function" == typeof(val)){ return val.toString().indexOf("function "+attr+"()") == 0; }else{return true;} };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
----- Update 2011/10/26 ------
继续新坑,IE5,6,7 的 script.getAttribute("src") === ""
,正常的 DOM 方法已经
阻止不了 IE 了,hack 方案可以解析 wrapHTML(node){return outerHTML.startTag;},
判断是否有 src 属性。
如果在这里你真的可以忽略 IE,最佳方案还是屏蔽 IE 吧。