首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >加载多个YouTube视频iFrame接口

加载多个YouTube视频iFrame接口
EN

Stack Overflow用户
提问于 2015-04-18 05:05:18
回答 1查看 5.8K关注 0票数 17

我在以下代码中遇到了问题,但我不确定问题出在哪里。

在我的主页上,我用javascript定义了一个数组,用来保存我创建的YouTubePlayer对象的列表。我还在这里加载了YouTube应用程序接口。

我还有(有时是几个) YouTube用户控件,它包含引导模式中的YouTube div。它还包含一个用于将新的YouTubePlayer对象推送到主页js中的数组的JavaScript。最后,在用户控件上,我定义了在bootstrap模式的“显示”和“隐藏”事件上自动启动和停止视频的方法。

最后,为了(希望)解决要加载的文档和要加载的YouTube应用程序接口之间的竞争条件,我设置了两个布尔变量(一个用于文档,一个用于API),并在调用initVideos函数之前检查这两个变量是否都为真,该函数迭代YouTubePlayer对象数组并对其进行初始化,从而在窗口中设置YT.Player对象。我想,问题的一部分是我不能静态地设置window.player1等,因为我永远不知道会加载多少YouTube用户控件。

无论何时触发引导模式事件,我从窗口检索的YT.Player pauseVideo()**.** 对象都不包含 playVideo() 和的方法,这是问题所在

在我的母版页上:

$(document).ready(function () {
    window.docReady = true;

    if (window.apiReady)
        initVideos();
});

function onYouTubeIframeAPIReady() {
    window.apiReady = true;

    if (window.docReady)
        initVideos();

    initVideos();
}

function initVideos() {

    if (typeof ytPlayerList === 'undefined')
        return;

    for (var i = 0; i < ytPlayerList.length; i++) {
        var player = ytPlayerList[i];
        var pl = new YT.Player(player.DivId, {
            playerVars: {
                'autoplay': '0',
                'controls': '1',
                'autohide': '2',
                'modestbranding': '1',
                'playsinline': '1',
                'rel': '0',
                'wmode': 'opaque'
            },
            videoId: player.VideoId,
            events: {
                'onStateChange': player.StateChangeHandler
            }
        });

        window[player.Id] = pl;
    }
}

在用户控件上:

window.ytPlayerList.push({
    Id: "<%=ClientID%>player",
    DivId: "<%=ClientID%>player",
    VideoId: "<%=VideoId%>",
    StateChangeHandler: hide<%=ClientID%>Player
});

function hide<%=ClientID %>Player(state) {
    if (state.data == '0') {
        hide<%=ClientID %>Video();
    }
}

function show<%=ClientID %>Video() {
    $('#<%=ClientID %>video-modal').modal('show');
}

function hide<%=ClientID %>Video() {
    $('#<%=ClientID %>video-modal').modal('hide');
}

$(document).ready(function() {
    $("#<%=ClientID%>Video").click(function() {
        show<%=ClientID%>Video();
    });

    $("#<%=ClientID %>video-modal").on('shown', function () {
        window["<%=ClientID%>player"].playVideo();
    });

    $("#<%=ClientID %>video-modal").on('hide', function () {
        window["<%=ClientID%>player"].pauseVideo();
    });
});

这可能是缺乏js专业知识,但我完全卡住了。任何帮助都将不胜感激。另外,作为参考,我得到的异常是

Uncaught TypeError: window.ctl100_phContent_ctl100player.playVideo is not a function
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-30 02:21:08

所以问题是,视频只有在YouTube接口加载完视频元素后才会获得该playVideo()方法。此视频元素是异步加载的,因此代码将继续执行$(document).ready(function() { jQuery代码,其中将尝试附加在该时间点尚不存在的playVideo()函数。

我在HTML/JS页面中重现了这个错误:

<!doctype html>
<html class="no-js" lang="">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title></title>
</head>
<body>
    <div id="ctl100_phContent_ctl100player" style="border:1px solid red;"></div>
    <div id="ctl100_phContent_ctl101player" style="border:1px solid red;"></div>
    <div id="ctl100_phContent_ctl102player" style="border:1px solid red;"></div>

    <script src="https://www.youtube.com/iframe_api"></script>
    <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.6.2.min.js"><\/script>')</script>
    <script>
        window.ytPlayerList = [];
        window.players = [];

        window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl100player', DivId: 'ctl100_phContent_ctl100player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_1' });
        window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl101player', DivId: 'ctl100_phContent_ctl101player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_2' });
        window.ytPlayerList.push({ Id: 'ctl100_phContent_ctl102player', DivId: 'ctl100_phContent_ctl102player', VideoId: 'IaHxPi9dM7o', StateChangeHandler: 'hide_player_3' });

        function onYouTubeIframeAPIReady() {
            initVideos();
        }

        function initVideos() {
            for (var i = 0; i < ytPlayerList.length; i++) {
                var player = ytPlayerList[i];
                var pl = new YT.Player(player.DivId, {
                    height: '390',
                    width: '640',
                    videoId: player.VideoId,
                });
                window[player.Id] = pl;
            }
        }

        window.ctl100_phContent_ctl100player.playVideo();
    </script>
</body>
</html>

这给了我与您所描述的相同的错误。因此,为了测试我的理论(并确保没有其他脚本错误),我这样做:

setTimeout(function() {
        window.ctl100_phContent_ctl100player.playVideo() 
}, 1000);

这确实起作用了。因此,这确实是问题所在。然而,我们不确定1000ms是否足以保证播放器被初始化。所以你可以做的是-如果你不想重构太多-开始监听播放器的onready事件:

    function initVideos() {
        for (var i = 0; i < ytPlayerList.length; i++) {
            var player = ytPlayerList[i];
            var pl = new YT.Player(player.DivId, {
                height: '390',
                width: '640',
                videoId: player.VideoId,
                events: {
                     'onReady': window[player.Id + '_ready']
                }
            });
            window[player.Id] = pl;
        }
    }

假设您使用代码生成来创建如下函数:

    function ctl100_phContent_ctl100player_ready() {
        // Hook up the hide() / onShow() and other behaviors here
        // ... to prove that playVideo() is a function here, I'm calling it
        window.ctl100_phContent_ctl100player.playVideo();
    }
    function ctl100_phContent_ctl101player_ready() {
        window.ctl100_phContent_ctl101player.playVideo();
    }
    function ctl100_phContent_ctl102player_ready() {
        window.ctl100_phContent_ctl102player.playVideo();
    }

因此,这不是针对您的问题的复制-粘贴解决方案,而是应该让您深入了解代码无法工作的原因。可能有更优雅的方法来实现您想要做的事情,但让我们暂时保持修复的简单性。

让我知道它是否工作,或者如果你有任何其他问题。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29709320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档