<a>标签 return false了,竟还能跳转

背景

前些天在 IE 浏览器测试功能的时候,点击某处功能触发函数时,alert 了一个错误提示,接着点击 alert 的确定按钮,页面发生了跳转,并仅展示了 false,结果就如下图。
在这里插入图片描述

一开始没留意到是 a 标签,增加了不少排查时间。如今问题处理完了,然后做个了一些对比测试,所以梳理并记录一下。

正文

先贴个测试代码

<html>

<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>

<a href="javascript:test1();">测试按钮1.1</a>
<a href="javascript:test2();">测试按钮1.2</a>
<a href="javascript:test4();">测试按钮1.3</a>
<br/>
<a href="javascript:test1();test3();">测试按钮1.1.1</a>
<a href="javascript:test2();test3();">测试按钮1.2.1</a>
<br/>
<br/>
<br/>
<a href="https://www.baidu.com/" onclick="test1();">测试按钮2.1</a>
<a href="https://www.baidu.com/" onclick="test2();">测试按钮2.2</a>
<a href="https://www.baidu.com/" onclick="return test2();">测试按钮2.3</a>
<br/>
<a href="https://www.baidu.com/" onclick="test1();test3();">测试按钮2.1.1</a>
<a href="https://www.baidu.com/" onclick="return test2();test3()">测试按钮2.3.1</a>
<br/>
<br/>
<br/>
<a href="https://www.baidu.com/" onclick="test5();">测试按钮3.1</a>

<script>
	function test1(){debugger;
		console.log("11111");
		return;
	}
	
	function test2(){debugger;
		console.log("22222");
		return false;
	}
	
	function test3(){debugger;
		console.log("33333")
	}
	
	function test4(){debugger;
		if(true){return false;}
		
		console.log("4444");
	}
	
	function test5(){debugger;
		console.log("55555");
		if(true){
			window.event.returnValue = false;
			//return;
		}
		
		console.log("test5 end");
	}

</script>

</body>
</html>
测试1

我们遇到的问题就是 1.2,a 标签的 href 直接调用函数,然后函数有 return false,结果就是发生了页面跳转,并且仅展示了 false。

如果在谷歌点击 1.2 按钮,是不会发生页面跳转的。

我们当时的解决办法是将函数里面的 return false,修改成为 return,就是说去掉 false,问题就解决了。IE 和 google 浏览器都正常。

思考
点击 a 标签除了触发函数以外,还要触发一个默认事件,这个默认事件就是执行页面跳转。

return 和 return false 的作用都是用来取消默认事件这个动作。但它两的区别是后者带有返回值,返回值就是 false。

那为什么 1.1 不会跳转,而 1.2 发生了跳转呢?

如果在 href 里面增加 test3() 函数,并都打上断点,你会发现点击任何一个按钮,都会触发两个函数

<a href="javascript:test1();test3();">测试按钮1.1.1</a>
<a href="javascript:test2();test3();">测试按钮1.2.1</a>

所以,1.1 看似解决了问题,但实际上是因为 test1() 的 return 没有返回值。

我们正常逻辑是当 test1() return false 之后,后面的所有逻辑不再执行,但是现在实际上是执行了 test3() 的逻辑。

然后我们会发现 1.2.1,原本 test2() return false 是发生跳转的,但结果接着执行完 test3() 后,没有发生跳转。

到这里我有一个猜想,href=“javascript:test2();test3();” 类似一个方法块,方法块里有两个子方法。有点像 JAVA 里面的 main 方法,然后 main 方法分别调用不同的 static 方法。

后来补了测试 1.3,结论是:return false 在当前方法(test4())内有效,不会继续执行本方法下面的逻辑。

测试2

测试 2 的写法是我们比较常见的,有一个 onclick 事件。

事实上 2.1,2.2 IE 和谷歌都发生了跳转,这是无容置疑的。但是 2.3 阻止了页面跳转。

所以 2.3 的原因有可能跟上面的猜想有关,把 onclick 看作一个 main 方法,test2() 返回 false,到 main 方法的时候接收到了这个返回值,所以实际上 main 方法也是 return false。

根据上面想法,写了测试 2.1.1,2.3.1,而且得到了证实。如果上面想法不好理解的话,写个JAVA代码。

public static void main(String[] args) {
	Boolean b = test2();
	if(!b) return;

	test3();
}

public static boolean test2() {
	System.out.println("22222");
	return false;
}

public static void test3() {
	System.out.println("33333");
}

当 test2 return false 后,main 方法也得到了 return false,而 return 对当前方法有效,所以阻断了后面的执行逻辑,即 test3 不再执行。

所以测试 2 的结论就是 onclick 加上 return 可以有效阻止页面跳转

最后

网上说 window.event.returnValue = false 也可以阻止页面跳转,但是我没有尝试成功。

也看见有人说 onclick 加上 return 等同于 window.event.returnValue = false。

我还看到一种写法 onclick = “test3();return false;”,这种写法是一律阻止页面跳转。所以比较好的实现方式是 2.3 或者 2.3.1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值