web-dev-qa-db-fra.com

Comment ouvrir les liens mailto dans un nouvel onglet pour les utilisateurs qui ont gmail comme gestionnaire de messagerie par défaut?

Sur une page Web, les liens mailto ouvrent le client de messagerie par défaut. Maintenant que Chrome offre la possibilité de définir Gmail comme client de messagerie par défaut, certains utilisateurs ont les liens ouverts dans la même fenêtre, les éloignant ainsi de la page sur laquelle ils ont cliqué sur le lien (qu'ils ne pas aimer)

J'ai essayé d'ajouter _blank cible aux liens, ce qui fonctionne très bien pour les utilisateurs de gmail, mais rendra les utilisateurs Outlook fous, car un nouvel onglet vide s'ouvrira chaque fois qu'ils cliquent sur un lien mailto.

Existe-t-il un moyen de détecter le gestionnaire d'e-mails par défaut et d'offrir une bonne expérience aux deux types d'utilisateurs?

34
Martin Henk

D'accord, j'ai donc pu faire fonctionner cela en Chrome sur Mac. Votre kilométrage peut varier. En outre, c'est assez IMO hacky, donc cela peut ne pas en valoir la peine. Honnêtement, cela devrait exister comme un paramètre dans Chrome, et le comportement doit être délégué au site Web. Par exemple Chrome devrait avoir une option: "[x] Toujours ouvrir les liens mailto dans un onglet séparé"

Cela étant dit, voici comment procéder.

Construisez d'abord vos liens comme ceci:

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

Définissez ensuite un gestionnaire de clics pour ceux-ci.

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

Il existe un argument options facultatif pour window.open que vous pouvez Tweak. En fait, je le recommanderais presque, pour voir si vous pouvez obtenir que la fenêtre générée soit aussi imperceptible que possible. https://developer.mozilla.org/en/DOM/window.open

http://www.w3schools.com/jsref/met_win_open.asp (le doc MDN est exhaustif, tandis que le doc w3schools est presque plus facile à lire)

Ensuite, nous devons créer la page mailto.html. Maintenant, vous devrez peut-être jouer avec le délai d'attente que vous voyez ci-dessous. Vous pourriez probablement même régler cela sur quelque chose de très court comme 500 ms.

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

Résultats

Mail.app défini comme lecteur de messagerie par défaut:

Lorsque je clique sur le lien, il ouvre une fenêtre pendant une fraction de seconde, puis compose un message vierge. Dans le navigateur, il revient à la page d'origine.

Gmail défini comme lecteur de messagerie sous Paramètres> Avancé> Confidentialité> Gestionnaires:

Lorsque je clique sur le lien, il ouvre un nouvel onglet vers Gmail, avec la page précédente en toute sécurité dans son propre onglet.

Remarque: Une fois que vous avez défini Gmail comme gestionnaire de messagerie, du côté du système d'exploitation (au moins sur mac), Chrome est défini comme gestionnaire de messagerie du système. Donc, même si vous désactivez Gmail comme messagerie dans Chrome, il est toujours défini au niveau du système d'exploitation. Donc, pour réinitialiser cela, je suis allé à Mail> Prefs> General. Et je remets le lecteur de messagerie par défaut à Mail.

17
Jon Jaques

J'ai reçu une demande d'implémentation de cela dans les contacts ownCloud et bien que je pense aussi que c'est un peu hackish, il ne semble pas y avoir d'autre moyen de détecter si le gestionnaire mailto est défini sur une adresse de messagerie Web.

Cet exemple est implémenté sans avoir besoin de fichiers externes.

REMARQUE: jQuery est nécessaire pour cet exemple, mais il peut probablement être réécrit en javascript strict.

Pour éviter d'avoir à utiliser data-mailto Ou d'autres astuces, vous pouvez plutôt intercepter le gestionnaire:

$(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();
});

Maintenant, pour la fonction 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);

}

J'ai réduit le délai d'attente à 500. Works For Me, permet de voir ce que les utilisateurs disent quand il est poussé;)

Si vous voulez éviter d'ouvrir un nouvel onglet/fenêtre, vous pouvez utiliser un iframe. Cela nécessitera une demande supplémentaire, mais est moins ennuyeux si vous n'utilisez pas vous-même le webmail. Cela n'était pas possible pour ownCloud car par défaut, la politique de sécurité du contenu est très stricte, et l'injection d'URL "étrangères" dans un iframe n'est pas autorisée (pas beaucoup testée):

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

}
2
tanghus