如何在Vue.js中正确为子窗口添加事件侦听器?

huangapple go评论87阅读模式
英文:

How to properly add an event listener to a child window in vuejs?

问题

从Vue 3组件中,我需要一个新窗口,就像一个弹出窗口,使用 window.open(url, name, config)。并且当子窗口关闭时,我需要触发一个函数。

(请注意,这与子父组件或相反的事件无关,而是涉及到窗口对象及其父窗口)

我尝试在弹出窗口上添加事件监听器,但这些事件在子窗口重定向时被销毁。

在组件的 script 标签中,我添加了一个方法,用于在按钮点击时打开新窗口并进行其他处理,如下所示:

<template>
    ....
    <button @click="onPositive"></button>
</template>

<script lang="ts">
export default defineComponent({
    methods: {
        onPositive() {
           const popup = window.open(url, name, config) as Window
           popup.focus()

           // 方法 1:
           popup.addEventListener('beforeunload', () => {
               console.log("事件触发")
               this.onPopupClosed
           })

           // 方法 2:
           popup.onbeforeunload = () => {
               console.log("事件触发")
               this.onPopupClosed
           }
       },

       onPopupClosed() {
            // .....
       }
    }
})
</script>

我尝试添加各种事件监听器,像上面提到的2种方法,但仍然没有触发。

一些见解:

  1. url 来自不同的源。
  2. 在url被重定向之前,当我关闭子窗口时,它会触发。
  3. 使用Vue.js 3和Typescript 5。
英文:

From a component in vue 3, i needed a new window, like a popup, using window.open(url, name, config). And i need to trigger a function when the child window is closed.

(Please note that this is not regarding events on child-parent component, or vice-versa, rather on a window object and its parent)

I tried adding event listeners on the popup window, but those are getting destroyed when the url is redirected on the child window.

Inside the script tab on a component, added a method to open new window and do other processing, on a button click, like below:

<template>
    ....
    <button @click="onPositive"></button>
</template>

<script lang="ts">
export default defineComponent({
    methods: {
        onPositive() {
           const popup = window.open(url, name, config) as Window
           popup.focus()

           // method 1:
           popup.addEventListener('beforeunload' () => {
               console.log("event triggered)
               this.onPopupClosed
           })

           // method 2:
           popup.onbeforeunload = () => {
               console.log("event triggered)
               this.onPopupClosed
           }
       },

       onPopupClosed() {
            // .....
       }
    }
})
</script>

I tried adding various event listeners like the 2 methods mentioned above, but still its not getting triggered.

Some insights:

  1. url is of different origin.
  2. Before the url is getting redirected, when i close the child window, its getting triggered.
  3. Using Vue.js 3 & typescript 5.

答案1

得分: 0

如果弹出窗口在您的控制下,您可以像这样做。

在最后一个地方,当所有导航都完成时

<script>
window.addEventListener('beforeunload', () => {
  window.opener.postMessage('popup-closed', '*');
});
</script>

window.opener.postMessage() 是一种允许当前窗口(子窗口)与打开它的窗口(父窗口)进行通信的方法。它提供了一种在这两个窗口之间发送消息的方式,即使它们来自不同的源(即不同的域、协议或端口)也可以。

在您的父Vue组件中

...

// 监听来自子窗口的消息
window.addEventListener('message', (event) => {
  if (event.data === 'popup-closed') {
    onPopupClosed();
  }
});

const onPopupClosed = () => {
  // 处理子窗口关闭时的事件
  console.log('弹出窗口已关闭');
};

window.addEventListener('message', ...) 是JavaScript中的事件监听器,允许您监听来自网页中其他窗口或iframe发送的消息。它使不同窗口或iframe之间的跨源通信成为可能,无论它们在同一页面上还是跨不同的域、协议或端口。

还有一点是,window.opener 属性始终指向打开子窗口的父窗口,无论在最终目标之前是否经过了其他URL的中间导航。一旦使用 window.open() 从父窗口打开子窗口,父窗口的引用将在子窗口的生命周期内保持不变,即使子窗口在最终目标之前导航到其他URL。

英文:

If the popup is under your control, you can do something like this.

In the final place, when all the navigation is done

&lt;script&gt;
window.addEventListener(&#39;beforeunload&#39;, () =&gt; {
  window.opener.postMessage(&#39;popup-closed&#39;, &#39;*&#39;);
});
&lt;/script&gt;

window.opener.postMessage() is a method that allows communication between the current window (child window) and the window that opened it (parent window). It provides a way to send messages between the two windows, even if they are from different origins (i.e., different domains, protocols, or ports).

In your parent vue component

... 

// Listen for messages from the child window
window.addEventListener(&#39;message&#39;, (event) =&gt; {
  if (event.data === &#39;popup-closed&#39;) {
    onPopupClosed();
  }
});

const onPopupClosed = () =&gt; {
  // Handle the event when the child window is closed
  console.log(&#39;Popup closed&#39;);
};

window.addEventListener(&#39;message&#39;, ...) is an event listener in JavaScript that allows you to listen for messages sent from other windows or iframes in a web page. It enables cross-origin communication between different windows or iframes on the same page or across different domains, protocols, or ports.

One more thing is the window.opener property always refers to the parent window that opened the child window, regardless of any intermediate navigation to other URLs. Once a child window is opened using window.open() from the parent window, the reference to the parent window remains the same throughout the child window's lifetime, even if the child window navigates to other URLs before go through final destination.

huangapple
  • 本文由 发表于 2023年7月20日 14:11:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727113.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定