最近在做asp.net mvc項目時遇到一個關於超鏈接的問題。很是糾結。
問題描述
有一個公司列表展示頁。在用鼠標中鍵(注意了是滾輪)以下簡稱中鍵,點擊編輯(超鏈接)的時候在該條數據的下面直接加在一個編輯的局部視圖,功能截圖如下:

前端代碼如下:
@model IEnumerable<Models.Company> @{ ViewBag.Title = "Companies"; Layout = null; } <table class="table"> <tr> <th> 公司名稱 </th> <th> 公司地址 </th> <th class="Recruitmenttitle" style="color: green; width: 20%; height: 30px;"> 操作 </th> </tr> @if (Model != null && Model.Count() > 0) { foreach (var item in Model) { <tr> <td> <a href="@Url.Action("RecruitmentDetails", "Recruitment", new { recruitmentid = item.CompanyID })" target="_blank">@item.CompanyName</a> </td> <td> @Html.DisplayFor(modelItem => item.CompanyAddress) </td> <td> <a href="/Test/Edit?companyID=@item.CompanyID" class="btnEdit" data-target="#edit_@item.CompanyID">編輯</a> @Html.ActionLink("刪除", "", new { id = item.CompanyID }) </td> </tr> <tr> <td colspan="3" style="display:none;" id="edit_@item.CompanyID"> </td> </tr> } } </table> <script> $(document).ready(function () { $("table").on("click", ".btnEdit", function (e) { var editDiv = $(this).data("target"); $(editDiv).submit(function () { var $form = $(this).find("form"); var $this = $(this); $.post($form.attr("action"), $form.serialize(), function (data) { if (data.status == "0") { $this.css("display", "none").html(); } else { $this.css("display", "block").html(data); } }); return false; }); $.get($(this).attr("href"), function (data) { $(editDiv).css("display", "block").html(data); }); return false; }); }); </script>
后台很簡單:
public ActionResult Edit(string companyID) { if (companyID == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Company company = Company.Companies.Find(c => c.CompanyID == Guid.Parse(companyID)); if (company == null) { return HttpNotFound(); } if (Request.IsAjaxRequest()) { return PartialView(company); } return View(company); }
老調重彈,無非是根據不同類型的請求返回不同的視圖。這一切似乎都沒有什么問題,但是在ie11下當你試着點擊鼠標中鍵(這里指的是我的滾輪,本人用的是低端鼠標沒有真正意義上的單擊中鍵)的時候,奇跡出現了:它會以導航鏈接的方式重新打開直接打開編輯頁局部視圖:

問題分析
這一看,想都不用想,中鍵點擊的時候肯定發送的不是ajax請求,因為Request.IsAjaxRequest()判斷的實質就是檢查消息頭部的"X-Requested-With"是否是XMLHttpRequest來檢查請求是否為ajax請求。在正常點擊按鈕后,調試即可證明這一點:

中鍵點擊:

當然想要證明這一點不必這么麻煩,用ie捕獲一下請求就知道了:

其實分析了這么久了,這只是表明當點擊中鍵的時候,會導致一個導航請求而非我們想看到的ajax請求。
問題解決
這上面分析了這么多,其實是徒勞的。因為我第一下看到這個問題,會以為這個跟a標簽沒啥關系。其實這個是a標簽在IE11(因為我這邊IE11下其它地方我沒測試過)下,
當用鼠標中鍵點擊a標簽時候都會出現這個問題,也就是說這個問題其實是IE11下無法阻止鼠標中鍵的默認行為。一小段代碼測試以下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>效果測試</title> <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script> <script> $(document).ready(function () { $("a").click(function () { return false; }); }); </script> </head> <body> <div class="normal"> <a href="http://www.baidu.com">Go</a> </div> </body> </html>
測試效果截圖:

看到這兒,有人可能要問了:你可以在mousedown事件里面做些手腳看下?
我們就來試下,加上mousedown事件(當然click也是它的一種):
$(document).ready(function () {
$("a").on("click mousedown", function () {
return false;
});
});
還是game over了。效果和上面的一樣。
但是很奇怪的是:當我在return false之前加行alert("");居然又是可以的了。有點不明覺厲了(注1)。
另一個不是很好的辦法的辦法:

當然實現partview的這個功能,可以不使用a標簽而改用按鈕,到目前為止,我確實沒有找到一個很完美的解決辦法。其實就是要阻止默認行為。當然這只是說的我,Maybe you have?
未完待續
其實問題並沒有真正意義上的解決,博問高分懸賞:http://q.cnblogs.com/q/69623/
眾神提供的意見
在此感謝各位熱情的意見
如EtherDream說言,暫時用唯有采用<a href="javascript:void(0)">Go</a>這樣的辦法。
結貼
根據DiQiSoft.Com的建議,最終解決了此問題。方案如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>效果測試</title>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("a").on("click", function () {
return false;
});
});
</script>
</head>
<body>
<div class="normal">
<a href="http://www.baidu.com"><span>Go</span></a>
</div>
</body>
</html>
就是在a標簽之間加上<span></span>標簽。具體的解釋可以看#22樓linkFly 的回復截圖如下:

正如linkFly 所言,這個是“治標不治本”的,但是也是十分巧妙的辦法。
在此對各位標示感謝!
注1:
之所以在return false之前加上alert("")會看到“默認行為被阻止”的假相,是由於它阻塞了后續代碼的執行,而並非真正意義上阻止了默認行為。
