当网页(由 Flutter for Web 创建)向上或向下滚动时,嵌入式 Youtube 视频小部件消失
Posted
技术标签:
【中文标题】当网页(由 Flutter for Web 创建)向上或向下滚动时,嵌入式 Youtube 视频小部件消失【英文标题】:Embedded Youtube video widget disappears while the web page (created by Flutter for Web) is scrolled up or down 【发布时间】:2020-05-10 11:01:07 【问题描述】:我设法将嵌入的 Youtube 视频放在使用 Flutter for Web 创建的网页上。问题是该视频小部件在页面向上或向下滚动时消失,并在滚动停止时重新出现。 Chrome 开发者控制台显示此错误remote.js:34 GET chrome-extension://invalid/ net::ERR_FAILED
Firefox 没有发出任何错误消息,但 Youtube 视频的闪烁也发生在那里。看起来网页在滚动过程中不断地一次又一次地获取 Youtube 视频信息。我该如何解决这个问题?
import 'package:flutter/material.dart';
import 'dart:html' as html;
import 'dart:ui' as ui;
void main()
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'video',
(int viewId) => html.IFrameElement()
..width = '640'
..height = '360'
..src = 'https://www.youtube-nocookie.com/embed/IyFZznAk69U'
..style.border = 'none');
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints)
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.purple,
child: Center(
child: Container(
height: 360,
width: 640,
color: Colors.green,
child: HtmlElementView(viewType: "video"),
),
),
),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
Text("test", textDirection: TextDirection.ltr),
],
),
),
);
);
【问题讨论】:
@muhleder at github 似乎有一个解决方案。希望他的 PR 将很快被合并。 github.com/flutter/flutter/issues/51865#issuecomment-607203018 【参考方案1】:我相信这是 Flutter 的一个已知问题,因为视图正在重建,它也会重建网页。奇怪。
如果你看flutter_webview_plugin,作者写道:
警告:webview 没有集成到小部件树中,它是 Flutter 视图之上的原生视图。您将看不到与 webview 占据的屏幕区域重叠的小吃栏、对话框或其他颤动小部件。
如果你能找到一种方法将 webview 从小部件树中取出,我敢打赌它无需刷新即可工作,但它当然会呈现在其他所有内容之上。
如果你想出一个解决办法,请告诉我,因为我在同一条船上。
【讨论】:
【参考方案2】:我们在这个案例中发现了 Flutter Web 的问题,并写了一封 design doc 描述问题和潜在的解决方案。
TL;问题DR: 某些DOM 操作会导致某些HTML 标记丢失其状态(如iframe),从而导致它们“重新加载”。 Flutter 在重新排列应用程序的渲染树时经常使用这些操作,并且似乎比手工制作的网站更频繁地触发该问题。 JS-only example.
TL;解决方案的DR:我们需要使用Web Components套件中的SLOT tag,因此Flutter在渲染树时不会触及用户HtmlViewElement的实际内容重新排列。相反,我们只移动一个 SLOT 标签。 JS-only example.
// Some problematic methods:
target.insertBefore(lastChild, firstChild); // lastChild reloads
target.appendChild(firstChild); // firstChild reloads
// (Maybe other methods cause iframes to reload?)
修复的早期概念证明显示出希望。任何人都可以关注此 Github 问题中的修复进度:flutter/flutter#80524。
【讨论】:
以上是关于当网页(由 Flutter for Web 创建)向上或向下滚动时,嵌入式 Youtube 视频小部件消失的主要内容,如果未能解决你的问题,请参考以下文章
使用 Flutter for Web 和 Mobile 的卡片高度/宽度