I am displaying a html file that is kind of a quiz player(html + js). Displaying works fine but at the player when user presses finish button and with the js script tags inside the html file score is calculated and they are getting their score. I want to access that score variable inside my flutter app.
So I need to make my html file and flutter talk. Please help.
html.IFrameElement _iframeElement = html.IFrameElement();
_iframeElement.src = _url;
_iframeElement.style.border = 'none';
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
Widget _iframeWidget;
_iframeWidget = HtmlElementView(
key: UniqueKey(),
viewType: 'iframeElement',
);
You can send message from one window to another with postMessage
, and access it via addEventListener
and remember that the iframe is the child of your flutter page (and flutter is the parent), so:
To send data from flutter to the iframe, you can use _iFrameElement.contentWindow?.postMessage
(after the iframe loaded), and to get that data in iframe, you can use window.addEventListener
.
To send data from iframe, you can use window.parent.postMessage
, and
to get that data in flutter, you can use window.addEventListener
.
A sample code would be:
Flutter:
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
class IFramePage extends StatefulWidget {
const IFramePage({Key? key}) : super(key: key);
@override
State<IFramePage> createState() => _IFramePageState();
}
class _IFramePageState extends State<IFramePage> {
int i = 0;
IFrameElement _iFrameElement = IFrameElement();
@override
void initState() {
_iFrameElement.src = 'http://localhost/iframe/iframe.html';
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iFrameElement,
);
_iFrameElement.onLoad.listen((event) {
// Send message to iframe when loaded
_iFrameElement.contentWindow
?.postMessage('Hello! Clicked: $i times', "*");
});
// Get message from iframe
window.addEventListener("message", (event) {
var data = (event as MessageEvent).data ?? '-';
if (data == 'clicked') {
setState(() {
i++;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text('clicked $i time(s)'),
SizedBox(
width: 300,
height: 300,
child: HtmlElementView(
key: UniqueKey(),
viewType: 'iframeElement',
),
),
],
),
);
}
}
and IFrame:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div>This is my iframe</div>
<button type="button" onclick="sendData()">Click Me!</button>
</body>
<script>
// Send data to parent window
const sendData = () => window.parent.postMessage('clicked', "*");
// Get data from parent window
window.addEventListener("message", (event) => console.log(event.data));
</script>
</html>