Javascript 如何为将 gmail 作为默认邮件处理程序的用户在新选项卡中打开 mailto 链接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11576255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:22:57  来源:igfitidea点击:

How to open mailto links in new tab for users that have gmail as the default mail handler?

javascriptgoogle-chromegmailhandlermailto

提问by Martin Henk

On a web page mailto links open the default e-mail client. Now that Chrome offers the ability to set Gmail as the default e-mail client, some users have the links open in the same window thus taking them away from the page they clicked the link (which they do not like)

在网页上的 mailto 链接打开默认的电子邮件客户端。现在 Chrome 提供了将 Gmail 设置为默认电子邮件客户端的功能,一些用户在同一窗口中打开链接,从而使他们离开他们单击链接的页面(他们不喜欢)

I have tried adding target _blank to the links, which works great for gmail users, but will drive Outlook users mad, because a new blank tab will open every time they click a mailto link.

我曾尝试将 target _blank 添加到链接中,这对 gmail 用户很有用,但会使 Outlook 用户发疯,因为每次单击 mailto 链接时都会打开一个新的空白选项卡。

I there a way to detect the default e-mail handler and offer a good experience for both types of users?

我有没有办法检测默认的电子邮件处理程序并为这两种类型的用户提供良好的体验?

回答by Jon Jaques

Okay, so I was able to get this working in Chrome on Mac. Your mileage may vary. Also, this is pretty hacky IMO, so it may not be worth it. Honestly this should exist as a setting within Chrome, and the behavior should be delegated to the website. E.g. Chrome should have an option: "[x] Always open mailto links in separate tab"

好的,所以我能够在 Mac 上的 Chrome 中使用它。你的旅费可能会改变。此外,这是非常 hacky IMO,所以它可能不值得。老实说,这应该作为 Chrome 中的一个设置存在,并且该行为应该委托给网站。例如 Chrome 应该有一个选项:“[x] 总是在单独的标签中打开 mailto 链接”

That being said, here's how you do it.

话虽如此,这就是你如何做到的。

First construct your links like so:

首先像这样构建你的链接:

<a href="#" data-mailto="[email protected]">Mail Somebody</a>

Then set a click handler for those.

然后为这些设置一个点击处理程序。

$('a[data-mailto]').click(function(){
  var link = 'mailto.html#mailto:' + $(this).data('mailto');
  window.open(link, 'Mailer');
  return false;
});

There is an optional optionsargument to window.openthat you can tweak. In fact I would almost recommend it, to see if you can get the generated window to be as unnoticable as possible. https://developer.mozilla.org/en/DOM/window.open

您可以调整一个可选options参数window.open。事实上,我几乎会推荐它,看看你是否能让生成的窗口尽可能不引人注意。 https://developer.mozilla.org/en/DOM/window.open

http://www.w3schools.com/jsref/met_win_open.asp(the MDN doc is exhaustive, while the w3schools doc is almost easier to read)

http://www.w3schools.com/jsref/met_win_open.asp(MDN文档详尽,而 w3schools 文档几乎更容易阅读)

Next we need to create the mailto.html page. Now you may need to play around with the timeout you see below. You could probably even set this to something really short like 500ms.

接下来我们需要创建mailto.html 页面。现在您可能需要调整您在下面看到的超时时间。您甚至可以将其设置为非常短的时间,例如 500 毫秒。

<html>
<script>
function checkMailto(hash){
    hash = hash.split('mailto:');
    if(hash.length > 1){
        return hash[1];
    } else {
        return false;
    }
}

var mailto = checkMailto(location.hash);

if(mailto){
    location.href = 'mailto:'+mailto;
    setTimeout(function(){
      window.close();
    }, 1000);
}
</script>
</html>

Results

结果

Mail.app set as my default email reader:

Mail.app 设置为我的默认电子邮件阅读器:

When I click the link, it opens a window for a split second, then composes a blank message. In the browser it goes back to the original page.

当我单击该链接时,它会在瞬间打开一个窗口,然后撰写一条空白消息。在浏览器中,它返回到原始页面。

Gmail set as mail reader under Settings > Advanced > Privacy > Handlers:

Gmail 在设置 > 高级 > 隐私 > 处理程序下设置为邮件阅读器:

When I click the link, it opens a new tab to Gmail, with the previous page safely in it's own tab.

当我单击该链接时,它会打开一个新的 Gmail 标签,上一页安全地位于它自己的标签中。

Note: Once you set Gmail as your email handler, on the OS side (at least on mac), Chrome is set as the system's email handler. So even if you turn off Gmail as the email handler inside Chrome, it is still set on the OS level. So to reset that, I went to Mail > Prefs > General. And set default mail reader back to Mail.

注意:一旦您将 Gmail 设置为您的电子邮件处理程序,在操作系统端(至少在 Mac 上),Chrome 将被设置为系统的电子邮件处理程序。因此,即使您在 Chrome 中关闭 Gmail 作为电子邮件处理程序,它仍然是在操作系统级别设置的。所以要重置它,我去邮件>首选项>常规。并将默认邮件阅读器设置回邮件。

回答by tanghus

I received a request for implementing this in ownCloud Contactsand though I also think it's a bit hackish, there doesn't seem to be another way of detecting if the mailto handler is set to a webmail address.

我收到了在 ownCloud Contacts 中实现此功能请求,虽然我也认为这有点骇人听闻,但似乎没有其他方法可以检测 mailto 处理程序是否设置为网络邮件地址。

This example is implemented without the need for external files.

这个例子是在不需要外部文件的情况下实现的。

NOTE: jQuery is needed for this example, but it can probably be rewritten to strict javascript.

注意:此示例需要 jQuery,但它可能可以重写为严格的 javascript。

To avoid having to use data-mailtoor other tricks, you can instead intercept the handler:

为了避免使用data-mailto或其他技巧,您可以改为拦截处理程序:

$(window).on('click', function(event) {
    if(!$(event.target).is('a[href^="mailto"]')) {
        return;
    }

    // I strip the 'mailto' because I use the same function in other places
    mailTo($(event.target).attr('href').substr(7));
    // Both are needed to avoid triggering other event handlers
    event.stopPropagation();
    event.preventDefault();
});

Now for the mailTo()function:

现在的mailTo()功能:

var mailTo = function(url) {
    var url = 'mailto:' + data.url;
    // I have often experienced Firefox errors with protocol handlers
    // so better be on the safe side.
    try {
        var mailer = window.open(url, 'Mailer');
    } catch(e) {
        console.log('There was an error opening a mail composer.', e);
    }
    setTimeout(function() {
        // This needs to be in a try/catch block because a Security 
        // error is thrown if the protocols doesn't match
        try {
            // At least in Firefox the locationis changed to about:blank
            if(mailer.location.href === url 
                    || mailer.location.href.substr(0, 6) === 'about:'
            ) {
                mailer.close();
            }
        } catch(e) {
            console.log('There was an error opening a mail composer.', e);
        }
    }, 500);

}

I decreased the timeout to 500. Works For Me, lets see what the users say when it's pushed ;)

我将超时减少到 500。对我有用,让我们看看用户在推送时怎么说;)

If you want to avoid opening a new tab/window you can use an iframe. It will require an extra request, but is less annoying if you don'tuse webmail yourself. This wasn't feasible for ownCloud because per default the Content-Security-Policy is very strict, and injecting "foreign" URLs into an iframe isn't allowed (not tested much):

如果您想避免打开新标签/窗口,您可以使用 iframe。这将需要额外的请求,但如果您自己不使用网络邮件,则不会那么烦人。这对 ownCloud 来说是不可行的,因为默认情况下 Content-Security-Policy 非常严格,并且不允许将“外国”URL 注入 iframe(没有经过太多测试):

var mailTo = function(url) {
    var url = 'mailto:' + data.url, $if;
    try {
        $if = $('<iframe />')
            .css({width: 0, height: 0, display: 'none'})
            .appendTo($('body'))
            .attr('src', url);
    } catch(e) {
        console.log('There was an error opening a mail composer.', e);
    }
    setTimeout(function() {
        try {

            if($if.attr('src') !== url 
                    && $if.attr('src').substr(0, 6) !== 'about:'
            ) {
                window.open($if.attr('src'), 'Mailer');
            }
        } catch(e) {
            console.log('There was an error opening a mail composer.', e);
        }
        $if.remove();
    }, 500);

}

回答by user2795020

I just wanted to say that for Firefox there is a simple solution.

我只想说,对于 Firefox,有一个简单的解决方案。

Construct your links like so:

像这样构建你的链接:

<a href="#" data-mailto="[email protected]">Mail Somebody</a>

Set a click handler for those.

为这些设置一个点击处理程序。

$('a[data-mailto]').click(function(){
  window.open($(this).data('mailto'));
});

Would be great if Chrome accepted it as well.

如果 Chrome 也接受它,那就太好了。