Command-click doesn't open a new tab, but middle-click does

我怕爱的太早我们不能终老 提交于 2019-12-02 23:46:26

Speculating here, but will confirm later from a Mac. This has been confirmed to be working on a Mac.

Win ctrl+click or a Mac command+click gets picked up by a "normal" click listener, just like a click with any other modifier key (alt+click, shift+click etc).

This is particularly confusing since a ctrl+click on a Mac gets interpreted as a right-click on OS level. Command-click, on the other hand, is not interpreted as a middle-click but rather is a browser preference.

Assuming that you do not have in-site functionality that specifically relies on modified clicks, it would be appropriate to exclude such events from click listeners, and instead allow for them to bubble up to be natively handled by the browser. Given the experience of someone in the similar situation, you should be able to add the following to click handlers (likely a delegate on library level as pointed out by Brilliand):

if (e.metaKey || e.ctrlKey) return;

When added at the beginning of the handler with e referring to a current click event, this should circumvent any following e.preventDefault();

Update:

It actually works! In this rather minimalistic fiddle, I am able to recognize when command-clicked or control-clicked, so as to avoid executing the rest of the click handler which includes ajax-fetching the content and e.preventDefault();. This allows for a command-click to be handled "as intended" on a Mac, i.e. opening the link in a new tab.

With this finding in mind, these lines should now read

if (e.isDefaultPrevented() || e.metaKey || e.ctrlKey) {
    return;
}

There is some interesting insight here: https://groups.google.com/forum/#!msg/mozilla.dev.usability/H1qLTur4EFc/gXH007CAPk8J

Apparently the JS you are using can preventDefault() the cmd+click while the middle-click is unaffected. Consult the docs of your JS/Site framework.

Here's the relevant code from sammy.js:

// bind to link clicks that have routes
$('a').live('click.history-' + this.app.eventNamespace(), function(e) {
    if (e.isDefaultPrevented()) {
        return;
    }
    var full_path = lp.fullPath(this);
    if (this.hostname == window.location.hostname && app.lookupRoute('get', full_path)) {
        e.preventDefault();
        proxy.setLocation(full_path);
        return false;
    }
});

Summary: If someone clicks on a link, override the standard link behavior with sammy.js's behavior, which is to change the current page to show the content of the target page with no actual page load. According to dakdad's link, a command-click (unlike a middle-click) is caught by the click event, and can be overridden.

For a workaround, you could remove sammy.js's event handler (using $('a').die('click.history-' + _sammy_event_namespace_);) and replace it with a modified version that checks for command-clicks and avoids overriding them.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!