不要给你的input元素设置“action”或“submit”

大多数的浏览器都有一个严格意义上来说不能算作bug的bug。实际上,浏览器的本意是让你的工作变得更简单,但是如果你(或者其他人)恰好以某种方式(其实是错误的方式)来写HTML代码的话,就会完全触发该问题。特别的,如果你指定input标签的id或者name属性值为“action”或“submit”,你可能就会触发非常隐藏的bug。

关于该“Bug”的介绍

去年我通读了John Resig 和Bear Bibeault著作的Secrets of the JavaScript Ninja一书。顺便说一下,如果你想写高效、优雅的javascript代码,这绝对是一本非常棒的书。不管怎么样,在第11章,某些内容吸引了我的注意力。如果你在form表单里有一个拥有id和/或name属性的input元素,那么你可以直接通过form元素的某些属性获取到该input元素,该特性被作者称为是“贪婪的ID”(greedy IDs)。

<form id="form" action="url">
    <input type="text" id="textboxid" name="textboxname">
</form>

// Grab the form
var form = document.getElementById('form');
 
// Reference the text box directly from the form by its ID or name
form.textboxid;   // -> The input element
form.textboxname; // -> The input element

这真是一个相当酷的想法,但是这并不是很有必要,因为通过元素的id或者name属性来获取元素也是很容易的。而且,要注意一个非常重要的事实:如果form元素的某个属性名和input元素的id/name值一样,那么该属性就会被input元素所覆盖。

如果你的input元素的id/name属性值被设置为了“action”或“submit”,然后你尝试使用javascript控制提交,那么此时就会变得极其悲剧。现在,如果你想知道form表单数据提交 (通过 form.action提交)的URL,或者你只是想通过写js代码的方式来提交(通过form.submit提交),那么你将会分别得到一个错误的值和直接报错。

解决方案

我从来没想过我会遇到这个问题,但是我还是碰到了。也许解决该问题的最简单的方法是改写你的input,但是不幸的是有时你可能拿不到HTML代码,而有时你根本不会去拿。而且其他的代码也可能依赖于id/name来做一些事情。因此,如果你没法去直接修改HTML代码,这里还有其他的解决方案。

这种解决方案只能解决form表单元素的属性值是函数的情形。任意值不是函数的属性都将不起作用,即使你尝试用javascript代码去动态修改input元素的id/name属性也毫无用处。不管怎么样,重写值是函数的属性(比如submit),从元素对象的原型获取函数,并将该函数以你想执行的form表单元素为运行环境来执行就能解决问题。

<form id="form" action="url">
    <input type="text" id="submit">
</form>

// Grab the form
var form = document.getElementById('form');
 
// Try to submit it the normal way
form.submit(); // Nope, that's an error
 
// Try to submit using the prototype
HTMLFormElement.prototype.submit.call(form); // Yay! It worked!

我并没有在老版本的浏览器做测试,但是它应该在对较老HTML4支持较好的浏览器上都能正常运行,因为HTMLFormElement最初是在 DOM Level 1规范中被指定的。

结论

在书中没有给出解决方案我感到有些惊讶。他们只是多少提到了说我们要避免使用这些ids/names(指action、submit等):

“幸运的是,通过避免使用和标准的属性名冲突的较简单的id值,我们在自己的标记中可以避免这个问题,同时我们鼓励其他人也这么做。特别是id和name的值要避免用submit,这是一个导致让人费解的bug并令人沮丧的问题的常见来源。”

虽然这的确是一个合理的建议,正因如此我把它作为了文章的标题,但这种情况并不总是可以避免的,因此有一种简单的能解决一部分问题的方案总是好的。但无论如何,我希望你永远用不到这种解决方案。愿上帝保佑,你能快快乐乐的编程!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值