javascript:void(0)的相关问题记录

今天要说一下<a>标签的一个常见写法,它引申出来几个关键的东西,经常让我们犯错。

下面的链接点击不会发生任何跳转,很多朋友喜欢用它来实现按钮,因为在css里可以控制:visited之类的伪类做不同的效果:

那这个语法到底是啥意思呢?我就简单的研究了一下,这个事情要从2方面说起。

<a>的href属性

首先要说href=”xxxxxx”,这里xxxxx可以写什么东西呢?其实标准早已定义,<a>标签的href属性支持多种值:

  • An absolute URL – points to another web site (like href=”http://www.example.com/default.htm”)
  • A relative URL – points to a file within a web site (like href=”default.htm”)
  • Link to an element with a specified id within the page (like href=”#top”)
  • Other protocols (like https://, ftp://, mailto:, file:, etc..)
  • A script (like href=”javascript:alert(‘Hello’);”)

这里显然是在应用最后一个规则,也就是执行一段js代码。在javascript:后的就是js代码了,但是这里要求它必须是一个表达式,比如上面的alert(“hello”),同时表达式的返回值将当做href的最终值。

表达式void()

那么void(0)是什么呢?当然是一个表达式了!这个表达式接受一个参数,返回值是undefined,而如果href的值是undefined,那么最终这个<a>链接被点击时将什么也不会发生,即不做任何跳转。

注意;

一定要注意,既然是javascript代码,最好记得在末尾写一个分号;,这是一个良好的习惯。

延伸思考

除了<a>的href支持执行js外,其实我们常用的onclick等事件函数也是支持的,但是却有所不同,这正是我想说的。

当点击div时会触发click事件,这段js代码将被执行,与<a href>不同的是这里可以是一段js代码而不是js表达式,上述表达等价于:

或者等价于:

这样就很清晰了,最后我要说说常见的错误用法,以及怎么正确的使用这些语法。

纠错!

简单的东西很容易被忽视,我们更愿意追逐时髦的东西,却忘记了基础才是不变的,本质的。

下面我要说说常见的错误认识有哪些,你一定见过。

先看这个:

等价于:

也等价于:

第二种方法和<a href=”http://baidu.com” onclick=”false;”>相比多了一个return,但是后者总是可以跳转,而前者则不会发生跳转,为什么呢?

return boolean是”网间流传”的野路子:事件函数return 一个boolean可以控制是否执行浏览器的默认行为,return false则可以禁止浏览器的默认行为,对于a标签来说就是不发生跳转,效果等同于javascript:void(0)。

可惜,对于禁止默认行为来说,return boolean的做法是不靠谱的,因为这个特性不是W3C标准制定的,可以参考这里

那么,之前所说的<a href=”javascript:void(0)”>禁止<a>标签跳转的做法就是对的吗(也就是只看中<a>标签的:visited等伪类的便捷性而选择了<a>标签)?从W3C标准上来说,它是合法的并且兼容性很高的,但是官方仍旧建议不要使用这种方案,更不要在void()表达式内部做任何业务逻辑,因为html和js混合编写是很难被察觉的。

正确的做法:通过addEventListener监听事件,并通过API来禁止默认行为(跳转),也就是:

它禁止默认行为,也就是禁止了<a>的点击跳转。

最后的劝戒

一个经常让人迷糊的东西是jquery,通过jquery注册的事件监听函数与Javascript原生做法很相似但却不同,很容易混淆。

首先JQuery使用addEventListener注册监听,如果你在Jquery的事件回调函数里return false,那么Jquery会替你调用下面2个函数:

  • event.preventDefault():禁止默认行为。
  • event.stopPropagation():禁止继续向上冒泡。

与之前所说的onclick return false的未定义行为是截然不同的。

我们知道,javascript原生事件禁止默认行为的做法有2种:

前者是最古老的方法,并且是未定义的做法。因为aObj.onclick=是为DOM对象设置属性,所以最多只能注册一个事件处理函数,另外事件回调只会执行一次。

而后者遵循事件的捕获和冒泡标准流程,在事件经过路径上的节点都可以注册监听,并且可以注册多个监听函数,它们都将被依次回调,是W3C标准定义与建议的做法。

另外,两种做法在回调函数中this的指向有巨大的差异,可以具体在这里了解,劝戒你尽早忘记过时的做法,加入正规军的行列中来。

最近闲来无事,所以随便看看前端基础,后面可能又会换一个方向学习,我貌似是个广度>深度的人,是好还是坏。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~