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

Angular 4在IE11中出现TypeError:无法获取apply属性问题排查

问题根源分析与解决方案

首先,这个错误的核心原因很明确:IE11并不支持scrollIntoViewIfNeeded()这个DOM方法,而你的focused指令里直接调用了它,导致Angular的Renderer.invokeElementMethod尝试调用一个不存在的方法的apply时抛出了错误(因为方法本身是undefined,自然没有apply属性)。

为什么移除[focused]="i === activeIndex"就正常?

因为这个绑定一移除,指令里的focused setter就不会被触发,也就不会执行那行调用scrollIntoViewIfNeeded()的代码,自然避开了IE11不支持的API。而移除API调用组件后正常,大概率是那个组件也用到了类似IE11不兼容的DOM方法,但从你给出的信息看,最直接的问题点就是focused指令里的这行代码。

验证这个结论

你可以直接在IE11的开发者工具控制台里,随便选一个DOM元素,执行element.scrollIntoViewIfNeeded(),会发现控制台直接提示这个方法不存在,这就是问题的源头。

修复方案

把scrollIntoViewIfNeeded()替换成IE11支持的scrollIntoView(),并且可以通过参数来实现类似的效果:

修改你的focused指令代码:

import {Directive, Input, Renderer, ElementRef} from '@angular/core'

@Directive({ selector: '[focused]' })
export class FocusedDirective {
  @Input() set focused(value: boolean){
    if(value){
      // 替换为IE11支持的scrollIntoView,加上参数实现类似scrollIntoViewIfNeeded的行为
      this.renderer.invokeElementMethod(
        this.elementRef.nativeElement, 
        'scrollIntoView',
        [{ behavior: 'auto', block: 'nearest' }] // 这个参数会让元素在可视区域时不滚动,和scrollIntoViewIfNeeded效果接近
      );
    }
  }
  constructor(private elementRef: ElementRef, private renderer: Renderer){}
}

另外补充一点:你当前的polyfills都是针对ES6/ES7语法的(比如core-js的那些导入),但这类DOM方法的缺失是浏览器API支持问题,语法polyfill解决不了,所以就算你加了再多语法polyfill,也解决不了这个问题,必须针对性地替换兼容的API。

额外严谨兼容方案

如果需要同时兼容现代浏览器和IE11,可以先检查元素是否存在目标方法,再决定调用哪个:

@Input() set focused(value: boolean){
  if(value){
    const el = this.elementRef.nativeElement;
    if (el.scrollIntoViewIfNeeded) {
      this.renderer.invokeElementMethod(el, 'scrollIntoViewIfNeeded');
    } else {
      this.renderer.invokeElementMethod(el, 'scrollIntoView', [{ behavior: 'auto', block: 'nearest' }]);
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:26