天天看點

關于僞協定javascript:

前幾天有人問我為什麼點選連結後頁面變成了一個隻有“false”的頁面,我猜想大概是濫用了javascript:僞協定吧。最終因為沒讓我看出事的代碼,真正原因也就不得而知。不過我借此契機理清了此處疑惑,倒也算有所得了。

一般說來,僞協定經常被用到<a>的href屬性上,例如<a href="javascript:alert('hello');" target="_blank" rel="external nofollow" >。這樣,點選此連結的預設行為就是彈出一個框,而不是跳轉至某頁面了。此處需要注意的地方有兩點:

1,傳回值對浏覽器行為的影響。傳回undefined,停留在原頁面,其它跳轉至傳回值。這就是為什麼出現“false”頁面的原因了。舊代碼中能看到javascript:void(...);的寫法,其實也是為了生成一個undefined的傳回值,等同于在最後直接加return;。

2,this指向global變量。這不是說例子中alert裡的this是global變量,而是連href屬性裡的this是global變量。因為此處是預設行為,不是事件,是以裡面的代碼的執行上下文不是觸發元素。

僞協定還可以使用在form元素的action裡,行為和使用在anchor上一樣。至于其它地方可不可以使用,或者有沒有什麼其它細節之類的,我就覺得沒有了解的必要了,畢竟這是一種已經不推薦使用的技術了,即混淆了結構又沒有适當的fallback。

附上測試的代碼,我覺得能運作的代碼往往說明的能力更強。

<!DOCTYPE html>
<html>
<head>
  <title>My Test Page</title>
</head>
<body>
	<div>
		<form id="f" action="javascript:alertThis(this, 'action');" οnsubmit="alertThis(this, 'submit');">
			<div><input type="submit" value="Empty form" /></div>
		</form>
		<a href="javascript:alertThis(this, 'anchor');" target="_blank" rel="external nofollow"  οnclick="alertThis(this, 'click');">empty anchor</a>
	</div>
</body>
<script type="text/javascript">
var logger = typeof(console) === 'object' ? console : {};
if (!logger.log) logger.log = alert;
function alertThis() {
	logger.log("this is " + this + "\nargs[0] is " + arguments[0] + "\nargs[1] is " + arguments[1]);
}
</script>
</html>
           

繼續閱讀