You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Safari中Angular Material报addEventListener不存在如何修复

问题核心成因
  • 旧版本Safari(含iOS 12及更早的移动端Safari、macOS 11.0之前的桌面端Safari)的MediaQueryList对象未实现W3C标准的addEventListener、removeEventListener监听接口
  • 这类老旧浏览器仅支持已被标记为废弃的addListener、removeListener旧API,直接调用不存在的标准方法时,就会抛出this.mobileQuery.addEventListener is not a function的运行时错误,removeEventListener的调用也会触发同类型问题
  • 参考的官方实现未做旧版浏览器的兼容兜底,仅在全量支持标准MediaQueryList接口的现代浏览器上可正常运行
兼容修复方案
  • 对绑定监听、移除监听的逻辑做API能力判断,优先调用标准方法,在旧版Safari场景下自动降级到可用的旧API,无需引入额外的polyfill依赖
  • 新旧API的触发时机、回调入参完全一致,不需要修改原有断点判断的业务逻辑
  • 修复后的核心实现代码:
public mobileQuery: MediaQueryList;
private _mobileQueryListener: () => void;

constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) {
  this.mobileQuery = media.matchMedia('(max-width: 992px)');
  this._mobileQueryListener = () => changeDetectorRef.detectChanges();

  // 绑定监听前判断API能力
  if (this.mobileQuery.addEventListener) {
    this.mobileQuery.addEventListener('change', this._mobileQueryListener);
  } else {
    // 旧版Safari降级逻辑
    this.mobileQuery.addListener(this._mobileQueryListener);
  }
}

ngOnDestroy(): void {
  // 移除监听前判断API能力
  if (this.mobileQuery.removeEventListener) {
    this.mobileQuery.removeEventListener('change', this._mobileQueryListener);
  } else {
    // 旧版Safari降级逻辑
    this.mobileQuery.removeListener(this._mobileQueryListener);
  }
}
落地注意事项
  • 不需要强行给MediaQueryList手动补充不存在的方法,能力判断的兼容方式无额外副作用,不会增加项目包体积
  • 兼容逻辑同时覆盖现代浏览器、旧版Safari的运行场景,不会出现重复绑定监听导致的内存泄漏、频繁触发变更检测的性能问题
  • 原有992px的断点判断逻辑完全不受兼容代码影响,sidenav的折叠、展开行为不会出现偏差

内容的提问来源于stack exchange,提问作者Devla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 11:06:04