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

从dart:html迁移到package:web后,如何处理onContextMenu事件?

问题

在从dart:html迁移到package:web的过程中,我需要更新一段监听文档右键(上下文菜单)事件的代码。

原dart:html实现代码:

import 'dart:html' as html;

html.window.document.onContextMenu.listen((event) {});

尝试迁移到package:web的代码:

import 'package:web/web.dart' as web;

web.window.document.onContextMenu.listen((event) {});

运行时触发错误:

The getter 'onContextMenu' isn't defined for the type 'Document'.

请问使用package:web监听文档contextmenu事件的正确方式是什么?如何实现dart:html中onContextMenu的等效功能?

解决方案

package:web的Document类没有提供onContextMenu这类封装好的事件流getter,需要直接调用原生Web API风格的addEventListener方法绑定事件,这和原生JavaScript的事件绑定逻辑完全一致:

基础实现方式

直接使用addEventListener绑定contextmenu事件:

import 'package:web/web.dart' as web;
import 'dart:js_interop' as js_interop;

void main() {
  web.document.addEventListener(
    'contextmenu',
    js_interop.allowInterop((web.Event event) {
      // 阻止默认右键菜单(可选)
      event.preventDefault();
      // 在这里编写你的事件处理逻辑
    }),
  );
}

模拟Stream监听(贴近dart:html使用习惯)

如果习惯dart:html中通过listen监听Stream的方式,可以自己封装一个Stream来适配:

import 'package:web/web.dart' as web;
import 'dart:js_interop' as js_interop;
import 'dart:async';

final _contextMenuController = StreamController<web.Event>.broadcast();

Stream<web.Event> get documentContextMenuStream => _contextMenuController.stream;

void initContextMenuListener() {
  web.document.addEventListener(
    'contextmenu',
    js_interop.allowInterop((web.Event event) {
      _contextMenuController.add(event);
    }),
  );
}

// 使用示例
void main() {
  initContextMenuListener();
  documentContextMenuStream.listen((event) {
    event.preventDefault();
    // 处理事件逻辑
  });
}

核心说明

  • package:web完全对齐原生Web API,事件名称使用小写的contextmenu,和dart:html的驼峰式onContextMenu对应;
  • 必须通过js_interop.allowInterop将Dart函数转换为JavaScript可调用的函数,否则无法正常绑定事件;
  • 如需阻止浏览器默认右键菜单,调用event.preventDefault()即可,逻辑和原生JS一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:46:09