[小Tip]给元素命名时容易踩的坑

之前说过,给元素的id或者class取一个看上去就是广告的名字,很容易被adblock干掉(当然如果你的网站足够有名,怎么取名都没用,不出三天,立马就有针对你的专属规则)。所以在写html属性值的时候,我们除了要遵守html编码规范,还要看下adblock常用的ChinaList+EasyList过滤列表中的默认规则,不要被匹配到。还要避免踩到陈旧浏览器带来的坑。

上周某同学踩到的坑是:给form里某个input的name属性写了一个名为name的属性值。

<form action="url" method="get" name="form1">
    <input name="name" />
</form>
<script>
var form = document.getElementsByTagName('form')[0];

alert('form.name:' + form.name);
alert('form.getAttribute("name"):' + form.getAttribute('name'));
</script>

在IE6、7下,上面最后两行代码都会取到object,也就是那个input,不会得到form元素的name属性值。其它浏览器,form.name得到的是input元素,form.getAttribute('name')得到的是字符串"form1"。

QWrap有个ajaxForm方法,接受form参数,代码内部获取form的所有数据项以及action和method属性值进行提交。代码使用的是form.action、form.method,如果form里刚好有name等于这两个值的表单元素,就会出错。这里如果改成getAttribute,至少能保证IE6、7之外的浏览器得到正常的结果;对于IE6、7,可以通过getAttributeNode来获取到正确的值。但是由于很多人都习惯用form.xxx来获取表单的属性,给表单元素的name属性值命名还是要尽可能的避开常见的form属性名,如name|method|action等。

另外的坑是IE6给元素指定了id="xx",可以通过window.xx得到这个元素。这在某些场景下会带来问题,例如QWrap所有方法都是定义在QW命名空间下,为了使用方便在最后的retouch文件中,通过mix(window, QW),把方法提到window下。但是这个mix默认不override,如果页面在引用QWrap之前写了一个<div id="W"></div>,QWrap的W就坏掉了。更郁闷的是IE6对name和id的混乱实现,对于支持name属性的a|input等元素,name可以当id来用,写一个<input name="W" />也会在window下定义一个W变量。后来QWrap改成了window.W = QW.W来避免这个问题。

有时候,我们写代码会使用typeof XX !== 'undefined'或者!!window.XX来判断一个页面是否引用了某JS。由于这个bug的存在,IE6中这段代码出现在id|name="XX"的元素之后会得到错误的结果。这种情况,一方面js中需要做更多的检查;另一方面,给html元素的id和name命名时也要格外小心。

本文链接:参与评论 »

--EOF--

提醒:本文最后更新于 1339 天前,文中所描述的信息可能已发生改变,请谨慎使用。

Comments