在 IE11 中,当单击其子元素之一时,焦点事件未在具有显示 flex 的可聚焦父 HTML 元素上触发

Posted

技术标签:

【中文标题】在 IE11 中,当单击其子元素之一时,焦点事件未在具有显示 flex 的可聚焦父 HTML 元素上触发【英文标题】:Focus event not fired on focusable parent HTML element with display flex, in IE11, when one of its children is clicked 【发布时间】:2018-12-26 12:53:16 【问题描述】:

Here 更新了 IE11 中的问题(更孤立的示例)。当父元素(tabindex=0,显示为flex)有子元素<div><span>时,在IE11中点击里面的文字不会触发焦点事件。这在其他浏览器中运行良好,也适用于 IE11 和 <p><section> 的子级。感谢@ConnorsFan,其中一种解决方案是在父级上使用display: block 而不是display: flex。然而,这似乎是 IE11 中的一个错误。

原帖:

Here 是一个简单的自定义 html 组件,使用 Angular 创建,它有一个 HTML DIV 子元素,其中包含文本。该组件是可聚焦的(它的 tabindex=0),但是单击文本不会触发 Internet Explorer 11 中的焦点事件。这在所有其他浏览器中都可以正常工作,这让我认为这是 IE11 中的错误。在 IE11 中似乎有些东西阻止了焦点在父可聚焦元素上触发,同时单击子元素,这是不可聚焦的。

用focusin 替换focus 并使用stopPropagation() 可能是一种选择,但它也不起作用并且事件被传播(取消注释hostListener 中的焦点)。我只需要在自定义组件上触发焦点。

【问题讨论】:

你绝对需要 flexbox 吗?当使用:host.div-class display: block; border: 1px solid black; 将显示设置为blockinline-block 时,它似乎可以工作。 谢谢你,@ConnorsFan!有用。我仍然想知道为什么 :host (正确应用样式不需要)和 display:block 的组合会导致焦点事件触发?当显示被阻止时,子 div 将采用父维度,在 IE11 中这似乎对焦点事件没问题?但是为什么在这种情况下还需要 :host 呢? 好的,IE11 和 display:flex 的问题在纯 HTML div 和外部 Angular 项目中可用,这里是隔离的 (codepen.io/lipata/pen/GBjYPK)。我已经更新了上面的原始帖子。 :host 是必需的,因为我已将父主机的样式放在 div.component.css 中,这是不正确的,现在我将它移到 app.component.css 中,它应该在的位置。因此,由于示例中存在问题,因此需要 :host,我已对其进行了更正。 @ConnorsFan 如果你愿意,你可以发布一个答案,我会验证它(没有 :host)。谢谢! 【参考方案1】:
   import   Component, OnInit, HostListener, HostBinding from '@angular/core';

@Component(
  selector: 'my-div',
  template: `<div (focus)="onFocus($emit)">Click to see some magic happen :)</div>`,
  styles: [`.div-class  display: flex; border: 1px solid black; `]
)
export class DivComponent  
    @HostBinding('attr.tabindex')
    public tabindex = 0;

    @HostBinding('attr.class')
      get hostClass(): string 
        return 'div-class';
      

    @HostListener('focus', ['$event'])
    //@HostListener('focusin', ['$event'])
    public onFocus(event) 
      console.log("focus my-div", document.activeElement);
      // event.stopPropagation();
    

    @HostListener('click', ['$event'])
    public onClick(event) 
      // console.log("click HostListener");
    

我已经修复了您的 div.component.ts 文件,您必须从 div 调用 onFocus() 将其绑定为单向方法并发出事件 查看 stackbiltz 示例https://stackblitz.com/edit/angular-gm4hyf

【讨论】:

谢谢!我已经这样做了,但这也不是一个选择。问题是我需要在自定义元素上使用事件处理程序,因为它是模板化的,并且有人可以替换 ,因此它不起作用。首先,我想了解的是,这是否是 IE11 中的错误。无论如何,谢谢! 【参考方案2】:

根据我在IE11上使用this stackblitz的测试,当子组件的display样式属性设置为blockinline-block,而不是flex时,会触发焦点事件:

.div-class 
    display: block; 
    border: 1px solid black;

【讨论】:

以上是关于在 IE11 中,当单击其子元素之一时,焦点事件未在具有显示 flex 的可聚焦父 HTML 元素上触发的主要内容,如果未能解决你的问题,请参考以下文章

IE 10, 11. 如何防止使用占位符的文本输入触发焦点输入事件?

jQuery之事件even

TailwindCSS 组内的链接:焦点元素失败,因为单击事件被阻止

JS之event flow

JS基础语法之DOM02(事件)

JavaScript+html显示隐藏文本框的内容