Flutter Web Iframe html元素错误重新加载

Posted

技术标签:

【中文标题】Flutter Web Iframe html元素错误重新加载【英文标题】:Flutter Web Iframe html element error reload 【发布时间】:2020-04-19 09:31:00 【问题描述】:

我正在尝试从本地 html 文件插入 iframe。 对于这个 porpouse,我创建了一个 StatefulWidget 来在 HtmlElementView 中呈现 html。 这个 sn-p 运行良好。 我看到了 iframe,它可以工作,但它有一个奇怪的行为: 每次它在任何 setState 上重新初始化 html,甚至在 FlatButton 上重新初始化 onMousOver。

为什么?坦克

import 'dart:async';
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class MapPlugin extends StatefulWidget 
  MapPlugin();

  _MapPluginState createState() => _MapPluginState();


class _MapPluginState extends State<MapPlugin> 
  String createdViewId = 'map_element';

  @override
  void initState() 
    ui.platformViewRegistry.registerViewFactory(
        createdViewId,
        (int viewId) => html.IFrameElement()
          ..width = '800'
          ..height = '400'
          ..src = "/assets/map.html"
          ..style.border = 'none');

    super.initState();
  

  @override
  void dispose() 
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Container(
        padding: EdgeInsets.symmetric(horizontal: 10),
        decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(color: Colors.grey[300], width: 1),
            borderRadius: BorderRadius.all(Radius.circular(5))),
        width: 200,
        height: 200,
        child: Directionality(
            textDirection: TextDirection.ltr,
            child: HtmlElementView(
              viewType: createdViewId,
            )));
  

【问题讨论】:

如何调用html javascript函数调用 【参考方案1】:

将 HtmlElementView 移到构建函数之外,并将其替换为在 initState 函数 matey 中初始化的变量。

【讨论】:

【参考方案2】:

这是因为 Flutter Web 框架中的一个已知错误,每次在视图中存在 setState 或重绘任何小部件时,也会使 IFrameElement 重新加载。 在您的情况下,这是由 RaisedButton 的阴影引起的,如果按下或悬停,它将超出按钮并覆盖 iframe,使其重新加载。 事实上,如果你把 IFrame 放在全屏大小,它不会在外部调整大小或调用 setState 之外产生任何问题。

要暂时解决按钮问题,您可以将可点击小部件包装在 GestureDetector 中。 这是因为 GestureDetector 在单击或悬停时不会给出任何类型的动画,因此它不会覆盖您的框架并使其重新加载。

这是一个使用我的应用程序的示例:

Builder(
  builder: (context) => GestureDetector(
    onTap: () 
      print("Back to previous screen");
      Navigator.of(context).maybePop();
    ,
    child: RaisedButton(
      child: Row(
        children: <Widget>[
          Icon(Icons.arrow_back, color: Colors.black),
          Text("GO BACK")
        ],
      ),
      onPressed: null
    ),
  ),
),

当然,这意味着您还应该管理按钮的禁用样式版本

【讨论】:

以上是关于Flutter Web Iframe html元素错误重新加载的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数发送到嵌入式 Flutter Web 应用程序?

如何在flutter web中动态更改iframe的src?

Flutter Web iFrame 奇怪的行为

Selenium中web三大切换之iframe窗口及Alert(弹窗)切换

在 Flutter for Web 应用程序中嵌入网页作为 Widget(类似于 iframe)

在静态页面中“包装”Flutter Web