光标位于 youtube_player_iframe 顶部时鼠标滚动卡住

Posted

技术标签:

【中文标题】光标位于 youtube_player_iframe 顶部时鼠标滚动卡住【英文标题】:Mouse scroll stuck while cursor is on top of youtube_player_iframe 【发布时间】:2021-09-18 20:34:14 【问题描述】:

鼠标滚动卡在视频顶部。我正在使用youtube_player_iframe。另外,我不想重建 iframe 小部件。我试图用pointer_interceptor 包装它,但它并没有解决问题。我的首要任务是解决滚动问题并避免在滚动时重建小部件。在SingleChildScrollView 上包装所有内容不是一个好习惯。

我不想像这个包一样使用 YouTube API 需要实现flutter-web

如果您有其他处理方法,请随时分享。 谢谢

检查此输出video

测试小部件

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:sliver_tools/sliver_tools.dart';

import 'package:youtube_player_iframe/youtube_player_iframe.dart';

class YoutubeVideoAdTestScreen2 extends StatefulWidget 
  YoutubeVideoAdTestScreen2(Key? key) : super(key: key);

  @override
  _YoutubeVideoAdTestScreen2State createState() =>
      _YoutubeVideoAdTestScreen2State();


class _YoutubeVideoAdTestScreen2State extends State<YoutubeVideoAdTestScreen2> 
  YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: '1oF3pI5umck',
    params: YoutubePlayerParams(
      // Defining custom playlist
      startAt: Duration(seconds: 30),
      showControls: true,
      showFullscreenButton: true,
    ),
  );

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

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          MultiSliver(
            children: [
              ...List.generate(
                4,
                (index) => Container(
                  color: index % 2 == 0 ? Colors.amber : Colors.cyanAccent,
                  height: index * 50 + 100,
                ),
              ).toList(),
              SliverToBoxAdapter(
                child: YoutubePlayerIFrame(
                  gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>,
                  controller: _controller,
                  aspectRatio: 16 / 9,
                ),
              ),
              ...List.generate(
                4,
                (index) => Container(
                  color: index % 2 == 0 ? Colors.amber : Colors.cyanAccent,
                  height: index * 50 + 100,
                ),
              ).toList(),
            ],
          ),
        ],
      ),
    );
  


【问题讨论】:

【参考方案1】:

在 Flutter 应用程序中嵌入 html 元素的问题在于,这些元素的呈现方式不同。 dart api 提供了有关iframes 及其pointer events 的这些信息:

由于跨域iframe 元素的安全限制,Flutter 无法将指针事件发送 到 HTML 视图。如果iframe 是事件的目标,则不会通知包含该事件的窗口。特别是,这意味着任何落在iframe 上的指针事件都不会被 Flutter 看到,因此 HTML 视图不能与其他小部件一起参与手势检测

对此没有理想的解决方案,要么在悬停iframe 时失去滚动能力,要么失去与iframe 交互的能力,但仍然滚动它。

这个想法很简单:将另一个 AspectRatio 包裹在 PointerInterceptor 中,在 Stack 内,这样仍然提供滚动行为,但遗憾的是您无法再与 iframe 交互。

.....
SliverToBoxAdapter(
  child: Stack(
    children: [
      YoutubePlayerIFrame(
        gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>,
        controller: _controller,
        aspectRatio: 16 / 9,
      ),
      PointerInterceptor(
        child: AspectRatio(
          aspectRatio: 16 / 9,
        ),
      ),
    ],
  ),
),
......

肯定有不同的方法来实现这一点,但如果你只想滚动iframe,我发现这是最简单的。播放器仍然可以通过其_controller 进行控制,因此play()stop() 等似乎仍然有效。

编辑PointerInterceptor 是一个 pub.dev 包:https://pub.dev/packages/pointer_interceptor

【讨论】:

此时,它完全忽略了点击事件。

以上是关于光标位于 youtube_player_iframe 顶部时鼠标滚动卡住的主要内容,如果未能解决你的问题,请参考以下文章

VBS使文本框的光标位于所有字符后

当鼠标光标位于属于面板的组合框上时如何触发面板滚动事件

检测光标位于 Scintilla NET 中的注释或字符串上方

jQuery:如何专注于输入文本字段,使光标位于文本的末尾?

如果 QMenu 弹出,如何使小部件在光标位于其上时接收 QMouseEvent?

当光标位于屏幕的顶部或底部边缘时,如何使用 JQuery/Javascript 向下滚动页面?