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

如何在Flutter Widget中监听JavaScript回调?

如何在Flutter Web中监听Paddle的eventCallback回调

方案一:通过window.postMessage实现通信

1. 修改index.html中的Paddle脚本

把原本的eventCallback改成将事件数据通过postMessage发送给Flutter:

<script type="text/javascript">
  Paddle.Setup({
    eventCallback: function (eventData) {
      console.log(eventData);
      // 发送事件数据到Flutter
      window.postMessage({ 
        type: 'paddleEvent', 
        data: eventData 
      }, '*');
    }
  });
</script>

2. 在Dart代码中监听事件

使用dart:html包监听window的message事件,解析并处理Paddle的回调数据:

import 'dart:html' as html;
import 'package:flutter/material.dart';

class PaddleEventListenerWidget extends StatefulWidget {
  @override
  _PaddleEventListenerWidgetState createState() => _PaddleEventListenerWidgetState();
}

class _PaddleEventListenerWidgetState extends State<PaddleEventListenerWidget> {
  dynamic _latestPaddleEvent;

  @override
  void initState() {
    super.initState();
    // 注册message事件监听
    html.window.addEventListener('message', _handlePaddleEvent);
  }

  void _handlePaddleEvent(html.Event event) {
    final messageEvent = event as html.MessageEvent;
    final eventData = messageEvent.data;
    
    // 过滤出Paddle的事件
    if (eventData is Map && eventData['type'] == 'paddleEvent') {
      setState(() {
        _latestPaddleEvent = eventData['data'];
      });
      // 在这里添加你的业务逻辑处理
      print('收到Paddle事件: $_latestPaddleEvent');
    }
  }

  @override
  void dispose() {
    // 移除监听,避免内存泄漏
    html.window.removeEventListener('message', _handlePaddleEvent);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(_latestPaddleEvent != null 
            ? '最新事件: ${_latestPaddleEvent.toString()}' 
            : '等待Paddle事件'),
      ),
    );
  }
}

方案二:使用package:js直接绑定JS函数

1. 添加依赖

在pubspec.yaml中引入js包:

dependencies:
  flutter:
    sdk: flutter
  js: ^0.6.7

2. 修改index.html中的脚本

定义一个全局JS函数,让Paddle的eventCallback直接调用它:

<script type="text/javascript">
  // 全局函数,用于接收Paddle事件
  window.handlePaddleEvent = function(eventData) {
    console.log(eventData);
  };

  Paddle.Setup({
    eventCallback: function (eventData) {
      window.handlePaddleEvent(eventData);
    }
  });
</script>

3. 在Dart代码中绑定回调

通过package:js将Dart函数绑定到全局JS函数,直接接收事件:

import 'package:flutter/material.dart';
import 'package:js/js.dart';

// 声明全局JS函数
@JS()
external set handlePaddleEvent(void Function(dynamic eventData) callback);

class PaddleEventWidget extends StatefulWidget {
  @override
  _PaddleEventWidgetState createState() => _PaddleEventWidgetState();
}

class _PaddleEventWidgetState extends State<PaddleEventWidget> {
  dynamic _eventData;

  @override
  void initState() {
    super.initState();
    // 将Dart函数绑定到全局JS函数
    handlePaddleEvent = allowInterop(_onPaddleEvent);
  }

  void _onPaddleEvent(dynamic eventData) {
    setState(() {
      _eventData = eventData;
    });
    // 处理事件逻辑
    print('Paddle事件数据: $_eventData');
  }

  @override
  void dispose() {
    // 清空回调,防止内存泄漏
    handlePaddleEvent = allowInterop((_) {});
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Text(_eventData != null 
            ? '事件详情: ${_eventData.toString()}' 
            : '未收到事件'),
      ),
    );
  }
}

两种方案对比:

  • 方案一无需额外依赖,适合快速实现,兼容性好;
  • 方案二代码更简洁直接,逻辑更清晰,适合复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:45:34