web-dev-qa-db-fra.com

Renvoie une valeur de window.open

Nous avons récemment découvert que Chrome ne prend plus en charge window.showModalDialog, ce qui pose problème car notre application d'entreprise utilise cette méthode.

Il existe apparemment une solution de contournement à court terme qui vous permet de restaurer showModalDialog, mais cela implique de modifier le registre, ce qui est trop compliqué (et risqué) pour notre utilisateur moyen. Par conséquent, je ne suis pas un grand fan de cette solution de contournement.

La solution à long terme est évidemment de supprimer tous les appels à cette méthode obsolète et de les remplacer par un plugin jQuery pratique (tel que VistaPrint plugin Skinny Modal Dialog , par exemple. D'autres suggestions sont les bienvenues d'ailleurs).

Le scénario typique que nous utilisons la boîte de dialogue modale est de demander à l'utilisateur une confirmation Oui/Non avant d'exécuter une action qui ne peut pas être annulée, de demander à l'utilisateur d'accepter les termes et conditions avant de continuer, etc. En général, l'événement onclick sur le "Oui" ou le bouton "Ok" dans la boîte de dialogue modale ressemble à ceci:

window.returnValue = true;
window.close();

De même, le bouton "Annuler" ou "Non" ressemble à ceci:

window.returnValue = false;
window.close();

Le fait que nous puissions renvoyer une valeur à partir de la boîte de dialogue est très pratique car il permet à la fenêtre "parent" d'être notifiée si l'utilisateur a cliqué sur le bouton "Ok" ou "Annuler" comme ceci:

var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
if (termsOfServiceAccepted) {
    ... proceed ...
}

La dernière chose que je vais mentionner à propos du showModalDialog est qu'il fonctionne très bien même lorsque le document affiché dans la boîte de dialogue provient d'un domaine différent. Il est très courant que notre javascript soit exécuté à partir de http://the-client.com mais la page Web "Conditions d'utilisation" provient de http: // the-enterprise- vendor.com

J'ai besoin d'une solution temporaire que je peux déployer dès que possible pendant que nous travaillons sur la solution à long terme. Voici mes critères:

  • modification minimale du code dans JavaScript existant
  • la fenêtre contextuelle doit pouvoir renvoyer une valeur au "parent". En règle générale, cette valeur est un booléen, mais il peut s'agir de n'importe quel type simple (par exemple: chaîne, entier, etc.)
  • la solution doit fonctionner même si l'URL du contenu provient d'un domaine différent

Voici ce que j'ai jusqu'à présent:

1) Ajoutez la méthode suivante dans mon JavaScript:

function OpenDialog(url, width, height, callback)
{
    var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
    var timer = setInterval(function ()
    {
        if (win.closed)
        {
            clearInterval(timer);
            var returnValue = win.returnValue;
            callback(returnValue);
        }
    }, 500);
}

Comme vous pouvez le voir dans cette méthode, j'essaie de faire en sorte que la fenêtre contextuelle ressemble autant à une boîte de dialogue que possible en masquant le menu et la barre d'outils, je configure une heure toutes les 500 millisecondes pour vérifier si la fenêtre a été fermée par l'utilisateur et si c'est le cas, obtenez la 'returnValue' et appelez un rappel.

2) remplacez tous les appels à showModalDialog par ce qui suit:

OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
{
    if (termsOfServiceAccepted)
    {
        ... proceed ....
    }
});

Le quatrième paramètre de la méthode est le rappel où je vérifie si l'utilisateur a cliqué sur le bouton "Ok" avant de lui permettre de continuer.

Je sais que c'est une longue question, mais en gros, cela se résume à:

  1. Que pensez-vous de la solution que je propose?
  2. En particulier, pensez-vous que je serai en mesure d'obtenir une valeur de retour à partir d'une fenêtre qui a été ouverte avec window.open?
  3. Une autre alternative que vous pouvez suggérer?
15
desautelsj

J'ai deux idées qui pourraient vous aider, mais la première est liée à CORS, vous ne pourrez donc pas l'utiliser à partir de différents domaines, au moins vous pourrez accéder aux deux services et les configurer.

PREMIÈRE IDÉE:

Le premier est lié à cela API native . Vous pouvez créer sur la fenêtre parent une fonction globale comme celle-ci:

window.callback = function (result) {
    //Code
}

Comme vous pouvez le voir, il reçoit un argument result qui peut contenir la valeur booléenne dont vous avez besoin. Vous pouvez ouvrir le popup en utilisant la même ancienne fonction window.open (url). Le gestionnaire d'événements onlick du popup pourrait ressembler à ceci:

function() {
    //Do whatever you want.
    window.opener.callback(true); //or false
}

DEUXIÈME IDÉE: Résout le problème

L'autre idée que j'ai eue est d'utiliser cet autre API native pour déclencher un événement sur la fenêtre parente lorsque la fenêtre contextuelle se résout (mieux connue sous le nom de messagerie croisée). Vous pouvez donc le faire à partir de la fenêtre parent:

window.onmessage = function (e) {
    if (e.data) {
        //Code for true
    } else {
        //Code for false
    }
};

De cette façon, vous écoutez tout message publié dans cette fenêtre et vérifiez si les données jointes au message sont vrai (l'utilisateur clique sur ok dans la fenêtre contextuelle) ou faux (l'utilisateur clique sur annuler dans la fenêtre contextuelle).

Dans la fenêtre contextuelle, vous devez publier un message dans la fenêtre parent en joignant une valeur true ou false lorsque cela correspond:

window.opener.postMessage(true, '*'); //or false

Je pense que cette solution correspond parfaitement à vos besoins.

[~ # ~] edit [~ # ~] J'ai écrit que la deuxième solution était également liée à CORS mais en creusant plus profondément, j'ai réalisé que le cross-document la messagerie n'est pas liée à CORS

17