使用Brace(ACE Editor兼容版)滚动时触发preventDefault错误的解决方法
解决ACE Editor(Brace版本)滚动时的
Unable to preventDefault错误 问题背景
使用Brace(ACE Editor的Browserify兼容版本)实现自定义模式后,滚动编辑器窗口时控制台会抛出Unable to preventDefault inside passive event listener invocation错误,错误指向brace源码index.js中的e.preventDefault()行。当前Angular模板里的编辑器实例化代码如下:
<div ace-editor *ngIf="formDefinitionPanel.expanded" [text]="formDefinitionJSON$ | async" [options]="aceEditorOptions" [readOnly]="true" [autoUpdateContent]="true" (textChanged)="updateFormFromEditor($event)" class="ace-editor-container" ></div>
可行解决方法
不需要修改node_modules源码,直接在TypeScript代码中调整编辑器的事件监听配置即可解决:
1. 先获取编辑器实例
在组件类中通过ViewChild获取ace-editor的实例,需要先给模板中的编辑器元素添加标记:
<div #aceEditor ace-editor *ngIf="formDefinitionPanel.expanded" [text]="formDefinitionJSON$ | async" [options]="aceEditorOptions" [readOnly]="true" [autoUpdateContent]="true" (textChanged)="updateFormFromEditor($event)" class="ace-editor-container" ></div>
然后在组件代码中获取实例:
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import * as ace from 'brace'; @Component({ // 你的组件元数据 }) export class YourComponent implements AfterViewInit { @ViewChild('aceEditor') aceEditor: any; aceEditorOptions = { // 你的编辑器配置,比如mode: 'json'等 }; ngAfterViewInit() { const editor = this.aceEditor.editor; // 后续处理逻辑写在这里 } }
2. 重新绑定滚动事件
ACE的滚动事件监听默认可能被设置为被动模式,但又调用了preventDefault,导致报错。我们可以移除原有监听,再重新绑定并指定passive: false:
ngAfterViewInit() { const editor = this.aceEditor.editor; const container = editor.container; // 移除原有滚动监听 container.removeEventListener('scroll', editor.onScroll); // 重新添加监听,允许调用preventDefault container.addEventListener('scroll', editor.onScroll, { passive: false }); }
3. 针对只读状态的简化方案
因为你的编辑器设置了readOnly: true,可以直接禁用ACE内置的滚动处理逻辑,避免触发错误:
ngAfterViewInit() { const editor = this.aceEditor.editor; // 禁用ACE的滚动加速处理 editor.setScrollSpeed(0); // 或者直接覆盖onScroll方法,跳过preventDefault调用 editor.onScroll = () => { // 保留必要的滚动事件触发逻辑 editor._emit('scroll'); }; }
原理说明
现代浏览器中,标记为passive: true的被动事件监听器内不允许调用preventDefault(),而Brace源码的滚动事件监听可能默认启用了被动模式却仍执行该方法,从而引发错误。通过重新绑定事件并关闭被动模式,或者修改ACE的滚动处理逻辑,就能规避这个问题。
内容的提问来源于stack exchange,提问作者Scott B
相关产品推荐
相关产品推荐

