Javascript 如何检测用户是否试图在新选项卡中打开链接?

Javascript 如何检测用户是否试图在新选项卡中打开链接?,javascript,Javascript,我正在编写一个网站,其中所有内容都存储在JavaScript环境中,因此应该可以在“页面”之间导航,而无需额外的HTTP请求 不过,我想保留用户关于如何打开链接的意图。例如,如果Mac用户apple+单击某个链接,则应在新选项卡中打开该链接。但是,如果用户希望在当前窗口中打开链接,我希望避免发出新的HTTP请求,而只使用DOM操作来显示新内容 以下是我尝试过的(): 它的行为与正常左键单击和上下文菜单操作所需的行为相同,但不适用于使用修改器键的单击。我可以检查是否持有某些修改键,但这似乎很脆弱

我正在编写一个网站,其中所有内容都存储在JavaScript环境中,因此应该可以在“页面”之间导航,而无需额外的HTTP请求

不过,我想保留用户关于如何打开链接的意图。例如,如果Mac用户apple+单击某个链接,则应在新选项卡中打开该链接。但是,如果用户希望在当前窗口中打开链接,我希望避免发出新的HTTP请求,而只使用DOM操作来显示新内容

以下是我尝试过的():

它的行为与正常左键单击和上下文菜单操作所需的行为相同,但不适用于使用修改器键的单击。我可以检查是否持有某些修改键,但这似乎很脆弱

Twitter网站的行为与我所希望的类似——当你点击用户名时,通常是AJAX请求,但如果你在按住meta键的情况下点击,你会得到一个新的标签

我更喜欢没有库的简单JavaScript解决方案,除非这需要一堆特定于平台的逻辑

更新 我看了一下GitHub的代码,它也有我想要的行为,它确实检查了某些密钥是否被持有。所以我接受克里斯的答案,因为似乎没有更好的选择

$(document).on("click", ".js-directory-link", function (t) {
    return 2 === t.which || t.metaKey || t.ctrlKey ? void 0 : ($(this).closest("tr").addClass("is-loading"), $(document.body).addClass("disables-context-loader"))
}

您可以检查事件对象的
ctrlKey
shiftKey
metaKey
属性。如果其中一个为真,则按住键control、shift或meta(苹果的命令)键,您应该允许默认链接操作继续。否则,您将使用
preventDefault
停止链接操作,并使用javascript处理它

target=“\u blank”
添加到锚定标记,因此默认链接行为是打开一个新选项卡。否则,它将在当前页面的顶部打开(这可能是需要的)

以下是javascript,无论哪种方式:

document.getElementById("mylink").onclick = function(evnt) {
    if (
        evnt.ctrlKey || 
        evnt.shiftKey || 
        evnt.metaKey || // apple
        (evnt.button && evnt.button == 1) // middle click, >IE9 + everyone else
    ){
        return;
    }
    evnt.preventDefault();

    alert("clicked");
    return false;
}
小提琴:

文档

  • MDN事件-
  • Event.ctrlKey
    -
  • Event.shiftKey
    -
  • Event.metaKey
    -
  • a
    tag-

您也可以使用onblur检测到

<html>
<head>
<script>
function newTabaction() {
  document.getElementById("demo").innerHTML = "New tab opened!<br><br>refesh this page to recheck ";
}
window.onblur = newTabaction;
</script>
</head>
<body>
<div id="demo">
Open a new tab and then check this page
</div>
</body>
</html>

函数newTabaction(){
document.getElementById(“demo”).innerHTML=“新选项卡已打开!

请参照此页面重新检查”; } window.onblur=newTabaction; 打开一个新选项卡,然后检查此页面
您在哪个浏览器和平台上测试?当我在Windows中尝试摆弄Firefox时,无论我是否按住控制键,都会触发该事件。您可以检查
event.ctrlKey
来检查控制键的状态。我正在OSX 10.8.5上使用Chrome v31。但我认为我们看到了同样的行为。我想要的是,只在正常的左键单击下看到警报,如果按住control/meta或使用上下文菜单,则打开新选项卡。如果您的链接是链接,用户可以自行决定在何处打开它们-同一窗口、新窗口或新选项卡。为什么需要检测任何东西?你想解决什么问题?可能重复的问题我不同意重复标记,而且答案肯定适用于这里。如果你需要在没有不确定的条件下,在没有失败可能性的情况下,检测一个新的标签(比如扩展),那么当然,跳转。对于一个网站,我认为这个问题可以用我在回答中概述的方式来处理。没有必要过于复杂——处理主要用例,避免边缘用例,因为它更可能过时,或者产生一些让用户恼火的意外效果。但是关键点是操作系统和浏览器特定的。我可以根据
window.navigator
,尝试确定哪些修改键会导致新选项卡/窗口,我只是想知道是否有更好的方法。在没有任何单击事件的情况下,在新选项卡或窗口中打开链接的位置如何@Daniel浏览器嗅探是一个糟糕的解决方案,除非有人付钱让你在新平台出现时代码崩溃时维护代码。@Daniel我能想到的唯一操作系统专用键是Apple命令键。我已经修改了代码,将其也包括在内。至于边缘案例,我认为你不需要涵盖它们。如果用户在单击链接时除了按住control、shift或command之外,还执行其他操作,那么代码的行为就像他们正常单击它一样。浏览器嗅探是对解决方案的过度设计。@chris用两个手指轻按,或拖动或多次单击进行选择,然后使用键盘或关联菜单进行复制。上下文菜单上还有右键单击+打开,在当前窗口中打开链接,不发送单击事件,以及各种插件和加速器。我认为关键的一点是,任何方法都是不可靠的,并且只能在某些时候起作用(用户可能不知道什么时候使用哪种方法)。此外,让服务器页面的结果与本地页面保持一致似乎给站点维护人员带来了不必要的不便(但这就是OPs问题)。@ChrisBaker Cool:)中键点击解决方案不适用于Linux上的Firefox 35,但适用于Chromium 39。另外,不允许右键单击也是一个不错的选择,因为仍然可以访问“在新选项卡中打开”选项卡。捕获“新选项卡”单击的目的是在打开新选项卡之前处理它们
document.getElementById("mylink").onclick = function(evnt) {
    if (
        evnt.ctrlKey || 
        evnt.shiftKey || 
        evnt.metaKey || // apple
        (evnt.button && evnt.button == 1) // middle click, >IE9 + everyone else
    ){
        return;
    }
    evnt.preventDefault();

    alert("clicked");
    return false;
}
<html>
<head>
<script>
function newTabaction() {
  document.getElementById("demo").innerHTML = "New tab opened!<br><br>refesh this page to recheck ";
}
window.onblur = newTabaction;
</script>
</head>
<body>
<div id="demo">
Open a new tab and then check this page
</div>
</body>
</html>