如何用js_interop替代js库实现Flutter Web滚动监听回调
用
dart:js_interop替代package:js实现JS与Dart的回调交互 步骤1:替换依赖与导入
移除pubspec.yaml中的package:js依赖,改用Dart SDK内置的JS互操作库:
import 'dart:js_interop'; import 'dart:js_interop_unsafe' as js_unsafe; import 'dart:html' as html; // 用于访问全局window对象 import 'package:flutter/material.dart';
步骤2:替换回调注册逻辑
原来的allowInterop可以用dart:js_interop_unsafe中的同名方法替代,同时调整全局变量的赋值方式:
方式1:直接通过window设置全局变量
class _YourWidgetState extends State<YourWidget> { double _zoomLevel = 1.0; @override void initState() { super.initState(); // 将Dart函数转换为JS可调用函数,赋值给全局的dartCtrlWheelEventHandler html.window.dartCtrlWheelEventHandler = js_unsafe.allowInterop(_ctrlWheelEventHandler); } void _ctrlWheelEventHandler(num deltaY) { setState(() { _zoomLevel += deltaY > 0 ? -0.1 : 0.1; _zoomLevel = _zoomLevel.clamp(0.5, 2.0); }); print(_zoomLevel); } // ... 其余Widget代码 }
方式2:使用外部注解定义全局setter
如果你更倾向于保留类似原@JS注解的写法,可以定义外部setter并转换函数类型:
// 定义全局变量的外部setter @JS() external set dartCtrlWheelEventHandler(JSFunction f); class _YourWidgetState extends State<YourWidget> { double _zoomLevel = 1.0; @override void initState() { super.initState(); // 将Dart函数转换为JSFunction并赋值 dartCtrlWheelEventHandler = js_unsafe.allowInterop(_ctrlWheelEventHandler).cast<JSFunction>(); } void _ctrlWheelEventHandler(num deltaY) { setState(() { _zoomLevel += deltaY > 0 ? -0.1 : 0.1; _zoomLevel = _zoomLevel.clamp(0.5, 2.0); }); print(_zoomLevel); } // ... 其余Widget代码 }
注意事项
dart:js_interop_unsafe中的allowInterop仅适用于信任的JS环境(比如你自己编写的index.html代码),避免用于不可信的第三方JS代码- 保持index.html中的监听器逻辑不变,确保它能正确调用全局的
dartCtrlWheelEventHandler函数:
<script> document.addEventListener('wheel', (e) => { if (e.ctrlKey) { e.preventDefault(); typeof dartCtrlWheelEventHandler === 'function' && dartCtrlWheelEventHandler(e.deltaY); } }); </script>
内容的提问来源于stack exchange,提问作者RJJ
相关产品推荐
相关产品推荐

