我有一个颤振项目,我在其中添加了Web支持。现在在我的页面中,我有 2 个按钮。我想当用户点击每个按钮时,显示一个网页。所以为了我创建自定义小部件:
@override
Widget build(BuildContext context) {
print("url is ------> ${url}");
isAddedElement();
_iframeElement.height = double.maxFinite.toString();
_iframeElement.width = double.maxFinite.toString();
_iframeElement.src = url;
_iframeElement.style.border = 'none';
_iframeElement.id = 'iframe';
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
_iframeWidget = HtmlElementView(
// key: UniqueKey(),
viewType: 'iframeElement',
);
return SizedBox(
height: 600,
width: 600,
child: _iframeWidget,
);
}
我想isAddedElement
方法检查iframeElement.id = 'iframe'
是否存在?如果存在,我想用新网页更改 src:
bool isAddedElement() {
IFrameElement frame = document.querySelector('iframe');
if (frame != null) frame.src = url;
}
但是document.querySelector('iframe')
总是返回 null?
查询返回null
,很可能是因为 flutter 在shadowDom
中添加了HtmlElementView
小部件,而这些元素在document
范围内不可用。
为了访问该元素,您需要通过一个通常放置在名为flutter-platform-view
的 custome 标签下的shadowroot
。因此,以下方法可能有效。
通过flt-platform-view
访问
尝试访问 iframe 元素,如下所示。
document.getElementsByTagName('flutter-platform-view')[0].shadowRoot.getElementById('iframe');
访问 IframeElement 实例
您已经拥有IframeElement
实例的引用,可以使用它检查您需要什么,如下所示。
bool isAddedElement() {
//IFrameElement frame = document.querySelector('iframe');
if (_iframeElement!= null && _iframeElement.src == null) _iframeElement.src = url;
}
但是我不明白为什么在您的代码中甚至在设置 Iframe 元素之前就调用isAddedElement()
。
您可以在 github 中找到有关为什么它放在阴影 dom 后面的更多详细信息。
这是使用第一种方法的完整工作演示。实时版本可作为代码笔演示提供
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:html';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: IframeDemo(),
),
),
);
}
}
class IframeDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return MyWidget();
}
}
class MyWidget extends State<IframeDemo> {
String _url;
IFrameElement _iframeElement;
@override
initState() {
super.initState();
_url = 'https://en.wikipedia.org/wiki/Twitter';
_iframeElement = IFrameElement()
..src = _url
..id = 'iframe'
..style.border = 'none';
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
}
void updateUrl(String page) {
setState(() {
// building a new url
_url = 'https://en.wikipedia.org/wiki/$page';
// Setting the url to the src field of the iframe element.
HtmlElement elem = document.getElementsByTagName('flt-platform-view')[0];
IFrameElement ifrelem = elem.shadowRoot.getElementById('iframe');
ifrelem..src = _url;
});
}
@override
Widget build(BuildContext context) {
print('url is $_url');
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaterialButton(
color: Colors.blueAccent,
child: Text('Show Twitter wiki'),
onPressed: () {
updateUrl('Twitter');
},
),
SizedBox(
width: 50,
),
MaterialButton(
color: Colors.orangeAccent,
child: Text('Show Facebook Wiki'),
onPressed: () {
updateUrl('Facebook');
},
),
],
),
SizedBox(
height: 100,
),
SizedBox(
height: 600,
width: 600,
child: HtmlElementView(
// key: UniqueKey(),
viewType: 'iframeElement',
),
),
],
);
}
}