"javascript:void(0);"是个好选择吗?

上一篇文章中,提到了因为onbeforeunload事件造成浏览器进行中的请求被挂断的问题,这篇算是一个扩展。

在网页中我们常用<a href="javascript:void(0);"> ... </a>(包括其变种如javascript:等)来做一个“不会跳转”的超链接,而这个a标签通常会长得像一个按钮,或者充当了按钮的功能。

先抛开BUG不说,从语义上讲,a标签来做按钮是不合适的。但这么做其实是处于历史原因:在IE6或更古董的浏览器中,:hover等广泛应用的伪类只对a标签生效。悬浮态、点击态对于按钮来说是非常重要的,但如果用JS来实现这事就有点蛋B,杀鸡用牛刀了,于是为了图便宜,大家都采用a加上各种样式来充当按钮功能。

时间一长,按钮的点击很多不会是页面跳转了,而是页面内交互。这时候问题来了:a标签一点击,页面跳走了,没得玩儿了。于是强需求“不会跳转的a标签”,使用事件机制阻止浏览器默认行为当然是很好的,但是毕竟要手工操作,容易漏,再加上前端捉襟见肘的代码量,似乎这种正经方法不怎么遭人待见。

结果容易的方法当然还是被人找出来了,起先是onclick="return false;",没啥问题,可咱不是不提倡写内联事件绑定么?于是有了href="#",时间一长,发现hash是很有用的,比如可以用来做历史记录,当然还有它本来的页面定位的作用,而且这容易造成页面跳到最顶上去,于是这样的a标签虽然不会跳转页面,但其实是有破坏性的。后来不知道是谁发明了本文的猪脚:javascript:void(0);可谓惊为天人,后续为了省几个字符所扩展的都算不上啥,由于其较小的破坏性和非常便捷的用法,一度成为比较公认的最佳实践。

基本上来说这没太大问题,缺点就是因为javascript:这个protocol是会触发onbeforeunload事件,从而引发一连串不必要的麻烦。

那么,哪里才能买得到呢怎么才是真正的最佳实践呢?

我觉得有三种选择:

  1. 只要是不跳走的,就坚决不用a标签做按钮,然后让IE6玩儿蛋去。
  2. 保证对每个按钮性质的a标签都阻止浏览器默认事件行为。
  3. 用事件代理,在body上捕获所有a标签的点击事件,判断其href并阻止浏览器默认行为。

2麻烦
3可能受阻止冒泡的影响
教练,我想选1

LoL