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

3

35

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)

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.

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

Okechuku answered 20/7, 2012 at 9:6 Comment(6)
Well, I'm not sure if I should call it a bug, but they certainly could opt for open in new window in this case. Or at least offer a setting for the user to do so.Okechuku
Unfortunately there is no API to detect the email handler. However, educated Chrome users know to hold Cmd (Mac), or Ctrl (Win) to open a link in a new tab. Perhaps you can educate them?Hydraulic
This was an idea I had. jsfiddle.net/jaquers/UCHKg I was thinking you could instead link them to a 'mailto' page, with the url set like this. foo.com/mailto.html#mailto:[email protected] How I wanted it to work, would be that if the email handler was gmail, the location.href call would negate the window.close() call. And if the email handler was on the OS, the window would close itself after a delay. Turns out window.close() doesn't actually work in Chrome. Didn't bother testing elsewhere.Hydraulic
I found out the window.close only works if you create the window via window.open(). Otherwise turns out I was on track with my initial thinking. :)Hydraulic
@MartinHenk Wondering if my solution worked for you? If so, could you accept the answer (checkmark icon next to my post)?Hydraulic
Maybe it fits? Look there 4 options https://mcmap.net/q/378029/-open-the-href-mailto-link-in-new-tab-windowGazebo
H
17

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"

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 options argument to window.open that 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

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

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.

<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:

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:

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

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.

Hydraulic answered 21/7, 2012 at 19:34 Comment(5)
Note, as far as the click handler goes. I think the data-mailto attr is nicer because it's more declarative, but you could alter it to check every link and only fire if it was a mailto.Hydraulic
Do you need the timeout at all? Shouldn't the locationchange prevent every following code to execute?Roadster
AFAIK, location change doesn't happen in the case of non-Gmail handler. Instead, it bubbles up to the OS in the form of an external protocol request - therefore, the setTimout still executes. But to answer your question, no it shouldn't be required. I put it in to give the browser time to execute the ext. protocol request. I would encourage you to test your theory though :)Hydraulic
@jipiboily It would be helpful if you said which browser it didn't work in that you tested, or explain the general reason why it won't work.Butte
@TylerCollier: I agree. I honestly don't remember though, 2 years later. :/Ray
M
2

I received a request for implementing this in ownCloud Contacts and 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.

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.

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

$(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:

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 ;)

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't use 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):

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);

}
Mixedup answered 11/3, 2014 at 14:41 Comment(1)
Works great on computers, but fails on iOS 9 in Safari when you want to use the default mail client. Opens and closes a blank page even when I set the timeout to 10000 just to let their bloated animations run.Klondike
R
-3

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

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.

Royston answered 25/10, 2013 at 14:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.