【问题标题】:Detect click outside of Angular application which runs in an iframe检测在 iframe 中运行的 Angular 应用程序外部的点击
【发布时间】:2021-01-29 20:51:45
【问题描述】:

我正在开发一个嵌入在 Wordpress 页面中的 Angular 应用程序。我正在使用 iframe 将 Angular 应用程序嵌入到 Worpress 页面中。现在我的 Angular 应用程序中有模态对话框,在对话框外部单击时应该关闭。当单击发生在对话框之外和 Angular 应用程序内部时,这可以正常工作。但是当点击甚至在 iframe 之外,在 wordpress 页面的其他地方,什么都没有发生。 Angular 事件处理程序似乎无法识别 iframe 之外的所有点击。
我找到了一些 Javascript 解决方案,其中 iframe 之外的页面是通过 document.parentElement 引用的。就我而言,这似乎不起作用,我的文档的 parentElement 是undefined
我希望你明白我的问题是什么,建立一个运行的例子会很费劲。

提前致谢!

【问题讨论】:

  • 我的意思是......你会期待这样的工作吗? iFrame 就像浏览器中的浏览器,并且相当孤立。如果 iframe 与父域是不同的域,则您也不能使用直接形式的通信。解决此问题的唯一方法是在父级中设置一个侦听器 - 并使用 postMessage 等机制将其传递给 iFrame。这就是 iFrame 真的很烂的原因 ;-)
  • 也许现在我想到了一种更简单的方法......但这并不理想。您可以尝试在 Angular 应用程序中检测窗口模糊,然后关闭模态框。但副作用可能是它“太容易”关闭了..
  • 您可以为此使用角度区域 this.ngZone.runOutsideAngular(() => { this.document.addEventListener( 'click', this.onDocumentClick.bind(this) ); });
  • @MikeOne:就我而言,两者都在同一个域上运行。我可以构建某种后端来实现两者之间的通信,但我希望有一个更简单/轻量级的解决方案。尝试检测窗口模糊是什么意思?您的意思是 wordpress 页面尝试在 Angular 应用程序中检测窗口模糊?
  • @MskSatheesh 我尝试了您的解决方案,但不起作用。仅当单击在我的 Angular 应用程序内时才会触发“onDocumentClick”方法。外部的点击仍然无法识别。

标签: angular iframe click


【解决方案1】:

感谢@Msk Satheesh 和@MikeOne,在你们俩的提示下,我运行起来了!
问题是我可以通过window.parent 真正解决(外部)wordpress 页面。但这仅有效,因为两者都在同一个域中运行。结合 Msk Satheesh 在他的第一条评论中发布的代码,它可以工作。而且我什至不需要在 Angular 之外运行任何东西。在 Angular 的模态对话框组件中,我输入了以下代码:

  constructor(public dialogRef: MatDialogRef<ResultsDialogComponent>, private eRef: ElementRef) {}
  
  ngOnInit(): void {
    if(!this.onDocumentClickFunction){
      this.onDocumentClickFunction = this.onDocumentClick.bind(this);
    }
    window.parent.addEventListener( 'click', this.onDocumentClickFunction ); 
  }

  onDocumentClick() {    
    this.dialogRef.close();
    this.eRef.nativeElement.click();
  }

  ngOnDestroy() {
    window.parent.removeEventListener( 'click', this.onDocumentClickFunction ); 
  }

就是这样。优雅的是onDocumentClick() 仅在点击在 iFrame 之外时才会触发。这意味着我不需要额外的逻辑来确定点击是在 iFrame 内部还是外部。 this.eRef.nativeElement.click(); 行对于将焦点带回 iFrame 是必需的。如果没有这条线,只有当用户自己点击 iFrame 时,模式才会消失。

【讨论】:

    【解决方案2】:

    尝试使用:

    角度组件

       constructor(private zone:NgZone) {
           window['clickEvent'] = (event) => {
               zone.run(() => {
                   console.log(event);
               });
           };
       }
    

    外部 Js:

    onClickEvent(event){
         window.parent.frames[#frameId].clickEvent(event);
    }
    

    【讨论】:

    • 对不起,我看错了,我以为你只是把你之前的评论变成了答案。
    • 这个我没去上班。 'line window['clickEvent'] = (event) => ...' 被 VS Code 标记为错误。但是您对我原帖的评论帮助很大,谢谢!
    猜你喜欢
    • 2023-03-27
    • 2017-02-27
    • 2016-06-19
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 2020-07-21
    相关资源
    最近更新 更多