今天要说一下<a>标签的一个常见写法,它引申出来几个关键的东西,经常让我们犯错。
下面的链接点击不会发生任何跳转,很多朋友喜欢用它来实现按钮,因为在css里可以控制:visited之类的伪类做不同的效果:
1 |
<a href="javascript:void(0)">点我不会发生任何事情</a> |
那这个语法到底是啥意思呢?我就简单的研究了一下,这个事情要从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等事件函数也是支持的,但是却有所不同,这正是我想说的。
1 |
<div onclick="var a = 1; var b = a + 1; alert(b); ">点我执行一段JS代码</div> |
当点击div时会触发click事件,这段js代码将被执行,与<a href>不同的是这里可以是一段js代码而不是js表达式,上述表达等价于:
1 |
divObject.onclick = function() { var a = 1; var b = a + 1; alert(b); } |
或者等价于:
1 |
divObject.addEventListener(“click”, function(event) { var a = 1; var b = a + 1; alert(b); }); |
这样就很清晰了,最后我要说说常见的错误用法,以及怎么正确的使用这些语法。
纠错!
简单的东西很容易被忽视,我们更愿意追逐时髦的东西,却忘记了基础才是不变的,本质的。
下面我要说说常见的错误认识有哪些,你一定见过。
先看这个:
1 |
<a href="http://baidu.com" onclick="return false;">点我不会发生任何事情</a> |
等价于:
1 |
aObj.onclick = function() { return false; } |
也等价于:
1 |
aObj.addEventListener("click", function(event) { event.preventDefault(); }); |
第二种方法和<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来禁止默认行为(跳转),也就是:
1 |
aObj.addEventListener("click", function(event) { event.preventDefault(); }); |
它禁止默认行为,也就是禁止了<a>的点击跳转。
最后的劝戒
一个经常让人迷糊的东西是jquery,通过jquery注册的事件监听函数与Javascript原生做法很相似但却不同,很容易混淆。
首先JQuery使用addEventListener注册监听,如果你在Jquery的事件回调函数里return false,那么Jquery会替你调用下面2个函数:
- event.preventDefault():禁止默认行为。
- event.stopPropagation():禁止继续向上冒泡。
与之前所说的onclick return false的未定义行为是截然不同的。
我们知道,javascript原生事件禁止默认行为的做法有2种:
1 |
aObj.onclick = function(event) { return false; } |
与
1 |
aObj.addEventListener("click", function(event) { event.preventDefault(); }); |
前者是最古老的方法,并且是未定义的做法。因为aObj.onclick=是为DOM对象设置属性,所以最多只能注册一个事件处理函数,另外事件回调只会执行一次。
而后者遵循事件的捕获和冒泡标准流程,在事件经过路径上的节点都可以注册监听,并且可以注册多个监听函数,它们都将被依次回调,是W3C标准定义与建议的做法。
另外,两种做法在回调函数中this的指向有巨大的差异,可以具体在这里了解,劝戒你尽早忘记过时的做法,加入正规军的行列中来。
最近闲来无事,所以随便看看前端基础,后面可能又会换一个方向学习,我貌似是个广度>深度的人,是好还是坏。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~
