Salut les amis de l'internet, scénario rapide: j'ai une application qui utilise des sous-fenêtres pour l'outillage, ouverte avec window.open('/tools', '_blank'). Il renvoie un objet window auquel je peux attacher des écouteurs d'événements, mais lorsque l'utilisateur clique sur le bouton d'actualisation, ou que la fenêtre effectue une redirection (ce que fait le mien, car il a une fonction de recherche), le {{X2} } l'objet est détruit, ou du moins je ne peux pas l'utiliser pour obtenir la fenêtre courante. Mon application pense donc que la fenêtre est fermée, même si ce n'est pas le cas.

Cela devient un problème lorsque je dois utiliser les objets window pour échanger des messages entre l'application principale et la fenêtre. Si l'utilisateur a changé l'objet window, cela ne fonctionnera plus. Je me demande simplement s'il existe une meilleure façon de procéder.

Évidemment, je pourrais avoir des invites intégrées à l'application avec HTML, mais j'essaie d'éviter cela pour des raisons de propreté, et ainsi l'utilisateur peut utiliser le système de fenêtrage de son système d'exploitation pour faciliter l'utilisation de l'application.

En termes d'exemples de code, il n'y a pas grand chose à montrer, j'ai deux scripts, un sur le principal et un sur la fenêtre de l'outil,

Principale

$("#btn").on('change', function() {
  const windowRef: Window | null = window.open('/tools', '_blank');
  if (windowRef)
    $(windowRef).on('load', function() {
      windowRef.connect = function() {
        // Initialise tools and functions here
      };
      $(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
    });
});

Fenêtre d'outil

...
<body>
  <script defer>
    new Promise((ok, err) => 'connect' in window ? ok(window.connect()) : err());
  </script>
</body>
2
Jacob Schneider 15 mars 2021 à 09:49

1 réponse

Meilleure réponse

Le problème n'est pas que la connexion à la sous-fenêtre soit détruite, car cela ne se produit pas lors d'une actualisation ou d'une redirection. Vous pouvez vérifier cela via windowRef.closed. Je suppose que votre fonction d'initialisation contient une logique qui doit être réappliquée après une actualisation / une redirection. Avec le code suivant:

windowRef.connect = function() {
   // Initialise tools and functions here
};

Vous avez défini une fonction globale pour la fenêtre nouvellement ouverte, qui est ensuite appelée dans la nouvelle fenêtre. Lorsqu'une page est actualisée / redirigée, toutes les modifications temporaires effectuées par javascript sont perdues. Ceci est vrai pour windowRef.connect, mais aussi pour $(windowRef).on('load'; ...):

$("#btn").on('change', function() {
  const windowRef: Window | null = window.open('/tools', '_blank');
  if (windowRef)
    // The registration of this listener is lost when the subwindow is refreshed
    $(windowRef).on('load', function() {
      windowRef.connect = function() {
        // Initialise tools and functions here
      };
      $(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
    });
});

Cela signifie que lorsque la sous-fenêtre est actualisée, le script suivant de la sous-fenêtre:

...
<body>
  <script defer>
    new Promise((ok, err) => 'connect' in window ? ok(window.connect()) : err());
  </script>
</body>

N'aura jamais de fonction window.connect, puisque l'auditeur n'est plus appelé. Vous pouvez résoudre ce problème d'initialisation avec window.opener :

Fenêtre principale:

let windowRef: Window | null;
$("#btn").on('change', function() {
  windowRef = window.open('/tools', '_blank');
});
// has to be a global function accessible via window.initialize
function initialize() {
  // Initialise tools and functions here
  $(windowRef).on('beforeunload', () => $("#btn").prop('checked', false));
}

Fenêtre de l'outil:

// on load in the tool window will be called after redirect/refresh
$(window).on("load", () => {
  if(window.opener) {
    // Get main window, which opened the sub window and call initialize.
    window.opener.initialize();
  }
})
1
Mirco S. 15 mars 2021 à 11:52