xiaooooooo 发表于 2023-12-23 00:08:54

关于iframe问题的求助

求助各位大佬,我遇到的需求场景是:我通过油猴脚本在当前页面注入了一个iframe元素,顺利打开了src的链接,然后——
**我需要在判断这个iframe元素完全加载之后,自动把这个iframe元素删掉,再加载下一个我设定的iframe元素**
请问是否可以实现?

李恒道 发表于 2023-12-23 05:27:18

可以主页面监听事件
iframe触发某些特定事件互相沟通

xiaooooooo 发表于 2024-1-7 00:42:16

李恒道 发表于 2023-12-23 05:27
可以主页面监听事件
iframe触发某些特定事件互相沟通

哥哥我要付费求教学{:4_89:}太难了这个

cxxjackie 发表于 2024-1-8 22:24:07

function waitAndRemove(iframe) {
    return new Promise(resolve => {
      iframe.addEventListener('load', e => {
            iframe.remove();
            resolve();
      });
    });
}

(async function() {
    const iframe1 = createIframe();
    await waitAndRemove(iframe1);
    const iframe2 = createIframe();
    await waitAndRemove(iframe2);
})();

xiaooooooo 发表于 2024-1-9 12:46:31

cxxjackie 发表于 2024-1-8 22:24


谢谢 cxxjackie 大佬指点!

xiaooooooo 发表于 2024-1-23 00:02:03

本帖最后由 xiaooooooo 于 2024-1-23 00:04 编辑

感谢大佬指点。我在您的代码结合我的需求做了一点改动,原因在于如果以'load'事件来作为关闭iframe的时机的话,会导致我在iframe页面上注入的代码还没有来得及执行完毕,这个iframe就被关闭了。

因此我试着参照李恒道大佬的postMessage方法进行改造,[参考链接](https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=2267)

在主页面增加以下代码:
```
function waitAndRemove(iframe) {
    return new Promise(resolve => {

      const ListenMessage= (e)=> {
            if(e.data==='close_window'){
                iframe.removeEventListener('message', ListenMessage)
                //关闭窗口代码
                iframe.remove();
                resolve()
            }
      };
      iframe.addEventListener('message', ListenMessage);

    });
}

。。。。。。
(async function() {
            await waitAndRemove(iframe);
      })();
。。。。。。
```
在子页面(iframe)打开的页面注入如下代码:
```
function EmitParentClose(){
    let parentif = window.top;
    parentif.postMessage('close_window')
}

。。。。。。

      // 发送关闭信号
      EmitParentClose();
。。。。。。
```


但是并未奏效,不知原因何在。另外我也想请教一下,这个postMessage发送回来的这个消息,是应当打印在dev tools的console里面吗?

cxxjackie 发表于 2024-1-23 22:12:50

xiaooooooo 发表于 2024-1-23 00:02
感谢大佬指点。我在您的代码结合我的需求做了一点改动,原因在于如果以'load'事件来作为关闭iframe的时 ...

在iframe内window.top指的是主页面,因此你的消息是直接发送到主页面的,在主页面中应对window做监听而非iframe,参考:https://bbs.tampermonkey.net.cn/thread-2895-1-1.html

xiaooooooo 发表于 2024-1-24 00:42:46

cxxjackie 发表于 2024-1-23 22:12
在iframe内window.top指的是主页面,因此你的消息是直接发送到主页面的,在主页面中应对window做监听而非 ...

感谢大佬指点。现在我在代码上做了如下修改

在主页面油猴脚本代码:
```
function waitAndRemove(iframe) {
    return new Promise(resolve => {

      const ListenMessage= (e)=> {
            if(e.data==='close_window'){
                window.removeEventListener('message', ListenMessage)
                //关闭窗口代码
                iframe.remove();
                resolve()
            }
      };
      window.addEventListener('message', ListenMessage);

    });
}

。。。。。。
(async function() {
            await waitAndRemove(iframe);
      })();
。。。。。。
```
在子页面(iframe)打开的页面注入如下代码:
```
function EmitParentClose(){
    let parentif = window.top;
    parentif.postMessage('close_window','*')
}

。。。。。。

      // 发送关闭信号
      EmitParentClose();
。。。。。。
```


主页面成功接收到了'close_window'信号并删除了iframe元素。但有一个新的问题,我在主页面创建了20个iframe,但是只收到了6个iframe页面的内容。也就是说,我猜想由于我的iframe元素不能编号区分,导致在remove的时候,同时关闭了所有iframe,造成信息丢失。请问我该如何实现【依次关闭】?

李恒道 发表于 2024-1-24 07:18:17

xiaooooooo 发表于 2024-1-24 00:42
感谢大佬指点。现在我在代码上做了如下修改

在主页面油猴脚本代码:


这要看你具体实现了
比如你可以主页面给子页面一个唯一uuid并且标识iframe
子页面发送关闭主页面控制关闭

xiaooooooo 发表于 2024-1-24 10:58:12

李恒道 发表于 2024-1-24 07:18
这要看你具体实现了
比如你可以主页面给子页面一个唯一uuid并且标识iframe
子页面发送关闭主页面控制关闭 ...

有点设计不出来这个机制。比如我在生成iframe的时候带上一个id属性,但是有个问题在关闭窗口代码当中, iframe.remove()怎么加这个判断id的语句呢?
页: [1] 2
查看完整版本: 关于iframe问题的求助