【问题标题】:In Angular 9, how do you implement an onblur handler for a page?在 Angular 9 中,如何为页面实现 onblur 处理程序?
【发布时间】:2021-02-01 12:43:40
【问题描述】:

我想在我的 Angular 9 应用程序中设置一个 onblur 事件处理程序,用于当有人离开页面时。我有问题的页面被映射到具有此...的单个组件...

export class HotComponent implements OnInit {
  ...

  onBlur(): void {
    console.log("on blur called !!!");
  }

在模板中,我设置了这个...

<div (blur)="onBlur()">
  <div>
    ...
  </div>
</div>

但是,当我离开加载此页面的浏览器窗口并返回时,我注意到 onblur 处理程序尚未被调用。在 Angular 9 中为页面实现 onblur 事件处理程序的正确方法是什么?

【问题讨论】:

  • 默认情况下 div 甚至没有获得焦点,因此 blur 将毫无用处。请参阅this 了解更多信息。我想你可能正在寻找window.onbeforeunload。有关详细信息,请参阅this。而关于HostListener 最受好评的答案正是您将如何观看此活动。

标签: angular event-handling angular9 onblur


【解决方案1】:

Angular有一个叫HostListener的东西,你需要用它!

 /**
   * Blur
   * @param eventName 'focusout' is the key
   * @param arguments of type '$event'
   */
  @HostListener('focusout', ['$event'])
  onFocusout(event) {
    // your logic goes here
    console.log('on blur called'); // This will get printed on blur
  }

【讨论】:

  • 当我在浏览器中单击不同的选项卡时,这似乎可以工作,但是当我切换到不同的应用程序(在 Mac 上使用 Cmd + 选项卡)时,它不会被调用(至少在 Firefox 上) )。
  • 当您使用 Cmd + tab 时,您需要了解浏览器获取的第一个实例不是您正在工作的选项卡。完成后,您需要编写逻辑,如果浏览器在最前面,则主机监听器将起作用,如果主机本身不在焦点上,它就无法正常工作?
  • 我不太明白。当有人使用(例如)Cmd + tab 导航离开时,我需要在哪里应用您提供的代码或我需要添加哪些其他代码来触发 hte 页面上的 onblur 事件?
【解决方案2】:

我建议您查看onbeforeunload eventonblur 事件并不是真正旨在支持您的用例,因为它针对元素的状态更改。您正在尝试做的是拦截浏览器上的历史更改。

WindowEventHandlers mixin 的 onbeforeunload 属性是用于处理 beforeunload 事件的 EventHandler。这些事件在窗口即将卸载其资源时触发。此时,文档仍然可见,事件仍然可以取消。

如其他回复所述,您可以添加事件监听器via Angular's @HostListener annotation

@HostListener('window:beforeunload')
foo() {
  // Do something here
}

【讨论】:

    【解决方案3】:

    两个问题将解决您的问题。将tabindex="0" 添加到您的DIV 然后处理以下事件

    <!-- language: html -->
    // 1
    <div  (blur)="onBlur()">  // tabindex="0" gets inserted by HostBinding
    // recommend you use an input vs. DIV when user is entering data
    

    第二个问题是因为有two events happening 作为导航的结果,您需要同时处理这两个问题。对于 firefox,请查看 here 的事件名称。一旦你导入HostListener & HostBinding

    <!-- language: typescript -->
    // 2
    import { Component, HostListener, HostBinding } from '@angular/core';
    
    1. 处理 focus event 焦点和 blur 退出
    2. 随意处理blur event

    <!-- language: typescript -->
    // 3              -- you should be good :)
    export class HotComponent { 
    
    focusOutFunction() {
     console.log('focusOutFunction called');
     .. your logic here
     }
    
    focusFunction() {
     console.log('focusFunction called');
     ..
     }
    
    blurFunction()
     {
      console.log('blur called');
      ..
     }
    
       // you dont need to manually add it to HTML if you do this.
       @HostBinding('attr.tabindex') tabindex = '0';
    }
    

    另一个选项2:如果你想处理focusOut

      <!-- language: html -->
      <input tabindex="0" type="text" (focusout)="onFocusOutEvent($event)" />
    

      // in your component explicitly handle the event 
      onFocusOutEvent(event: any){
        console.log(event.target.value);
      }
    

    simple working sample 的事件对我有用,请参阅图片下方的控制台日志...它有效。能否请您禁用所有插件并尝试。

    【讨论】:

    • 关于您的第一个解决方案,我假设其中一个“onFocus”函数应该命名为其他 b/c,您不能有两个具有相同签名的同名函数。无论如何,我将一个更改为“onFocus2”,但是当我 Cmd+tab 离开浏览器并返回时,它们不仅不会被调用,当我单击另一个选项卡并返回原始选项卡时,它们也不会被调用。 (在 Mac 火狐上测试)
    • 没错,我写它是为了让您了解如何捕获区分各种事件。
    • 我为您更新了示例,并在 stackblitz 上添加了一个使用控制台的工作骨架,以向您展示我可以看到事件。请关闭您的插件,然后重试
    【解决方案4】:

    onBluronFocus 不会直接应用于div

    无论如何,要解决您的问题,您只需在 visibilitychange 或任何其他组件的构造函数中添加 EventListener 即可。

    document.addEventListener("visibilitychange", () => {
      if (document.hidden) {
        console.log("Browser tab is on blur")
      } else {
        console.log("Browser tab is on focus")
      }
    });
    

    【讨论】:

    • 我使用的是 Firefox,当我点击不同的 Firefox 选项卡时,这种逻辑似乎有效。但是,当我选择另一个应用程序并将该应用程序带到我桌面的最前端时,逻辑不会被调用。
    猜你喜欢
    • 2017-08-10
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 2020-01-07
    • 2018-03-08
    • 2012-07-03
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多