Javascript Youtube API不适用于动态生成的对象数组

Javascript Youtube API不适用于动态生成的对象数组,javascript,arrays,object,youtube-api,Javascript,Arrays,Object,Youtube Api,我对Youtube API有一个看似奇怪的问题。。。 我正在编写一个脚本,该脚本将检测页面上的所有youtube视频,然后使用youtube API替换它们。通过这种方式,我将能够检测API事件,例如视频结束时,以显示消息。我正在为页面上的每个视频创建一个youtube播放器对象的新实例。到目前为止一切都很好 我动态生成视频容器,并将视频容器ID和视频ID保存到对象数组中(下面是我当前的代码) 奇怪的是,当我动态生成这个对象数组(使用array.push())时,Youtube API不起作用。

我对Youtube API有一个看似奇怪的问题。。。 我正在编写一个脚本,该脚本将检测页面上的所有youtube视频,然后使用youtube API替换它们。通过这种方式,我将能够检测API事件,例如视频结束时,以显示消息。我正在为页面上的每个视频创建一个youtube播放器对象的新实例。到目前为止一切都很好

我动态生成视频容器,并将视频容器ID和视频ID保存到对象数组中(下面是我当前的代码)

奇怪的是,当我动态生成这个对象数组(使用array.push())时,Youtube API不起作用。 如果我显式声明这个对象数组,Youtube API就可以正常工作


更清楚地说,这不适用于Youtube API(举例说明):

截图:


这项工作:

var playerInfoList = [
    {containerID:'social_share_custom_0', videoID:'KSyHWMdH9gk'},
    {containerID:'social_share_custom_1', videoID:'b-u5LE6X6ME'}
];
截图:


我制作了一个示例页面来演示这一点,如下所示:

<html>
<head>

</head>
<body>

<?php
    $content = '
    <h3>This is a sample page to demonstrate the issue...</h3>
    Text before <br /><br />
    <iframe width="560" height="315" src="//www.youtube.com/embed/KSyHWMdH9gk?rel=0" frameborder="0" allowfullscreen></iframe>
    Text in between.
    <iframe width="560" height="315" src="//www.youtube.com/embed/b-u5LE6X6ME?rel=0" frameborder="0" allowfullscreen></iframe>
    <br /><br />Text after.';

    $return_HTML  = '';

    // match any iframes
    $pattern = '~<iframe.*</iframe>|<embed.*</embed>~';
    preg_match_all($pattern, $content, $matches);


    // START Youtube Script
    $YT_scripts = '
            <script>
                /*
                ** Array of objects
                ** params containerID, videoID
                */
                var playerInfoList = []; ';

    $index = 0;
    foreach ($matches[0] as $match) {

        $embedPattern = '%(?:https?://)?(?:www\.)?(?:youtu\.be/| youtube\.com(?:/embed/|/v/|/watch\?v=))([\w-]{10,12})[a-zA-Z0-9\< \>\"]%x';

        $res=false;
        $res = preg_match($embedPattern, $match, $embedOutput); 

        if( $res ){
            $YT_scripts .= '
            //new object
            var newItem = {containerID:"social_share_custom_'.$index.'", videoID:"'.$embedOutput[1].'"};

            //put it into array
            playerInfoList.push(newItem);';             

            $wrappedframe = '<div class="social_share_custom_video_container" id="social_share_custom_'.$index.'"></div>';
            $content = str_replace($match, $wrappedframe, $content);
        }
    $index++;
    }

    $content .= $YT_scripts.'</script>';    
    $return_HTML .= $content;   

    echo $return_HTML;
?>

<script>
//Load Yotube API
var tag = document.createElement("script"); 
tag.src = "https://www.youtube.com/iframe_api"; 
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

/*
// if we declare this explicitly, Youtube API works.
// if this array if generated DYNAMICALLY (if we comment this out), Youtube API does not work.
var playerInfoList = [
    {containerID:'social_share_custom_0', videoID:'KSyHWMdH9gk'},
    {containerID:'social_share_custom_1', videoID:'b-u5LE6X6ME'}
];
*/

console.log( 'Object array length: ' + playerInfoList.length );

    function onYouTubeIframeAPIReady() {
        if(typeof playerInfoList === 'undefined')
            return; 

        for(var i = 0; i < playerInfoList.length;i++) {
            var player = createPlayer(playerInfoList[i]);
        }
    }

    function createPlayer(listItem){
        console.log( listItem.containerID + ' - ' + listItem.videoID );

        return new YT.Player(listItem.containerID, {
            height: '350',
            width: '480',
            videoId: listItem.videoID,
            events: {
                'onReady': onPlayerReady,
                'onStateChange': onPlayerStateChange,
                'onError' : onPlayerError
            }
        });
    }

    // autoplay video
    function onPlayerReady(event){
        // video is Ready
    }

    // when video ends
    function onPlayerStateChange(event) {        
        console.log(event);

        if(event.data == 0) {
            // video Ended
            // showEndVideoPrompt();
            console.log('Video Ended.');
        }
        else if (event.data === 1) {
            //video Started
        }
        else if (event.data === 2) {
            //video Stopped
        }           
    }

    function onPlayerError(event) {
        // video Error
    }
</script>

</body>
</html>

//加载管API
var tag=document.createElement(“脚本”);
tag.src=”https://www.youtube.com/iframe_api"; 
var firstScriptTag=document.getElementsByTagName(“脚本”)[0];
firstScriptTag.parentNode.insertBefore(标记,firstScriptTag);
/*
//如果我们明确声明这一点,Youtube API就会起作用。
//如果此数组是动态生成的(如果我们对此进行注释),那么Youtube API将无法工作。
变量playerInfoList=[
{containerID:'social_share_custom_0',videoID:'KSyHWMdH9gk'},
{containerID:'social_share_custom_1',videoID:'b-u5LE6X6ME'}
];
*/
log('Object array length:'+playerInfoList.length);
函数onyoutubeiframeapiredy(){
如果(playerFolist的类型==='undefined')
返回;
对于(变量i=0;i
我花了将近两天的时间尝试不同的事情,但仍然不知道为什么会发生这种情况。我在这里搜索了类似的问题,但没有找到任何其他关于动态生成的对象数组和Youtube API的问题

如果您能帮助解决此问题,我们将不胜感激。如果你需要更多信息,请告诉我。
感谢所有能够伸出援助之手的人:)

问题是由于您用于提取视频ID的正则表达式。最后一位
[a-zA-Z0-9\<\>\”]
正在通过使用ID的最后一个字符而不是将其与其余字符一起捕获来破坏
视频ID
。删除它应该可以解决问题。

您是否检查了浏览器控制台的Javascript错误?@levi是的,我检查了错误,但代码上没有错误,Javascript上也没有错误ole也是。我正在使用Chrome的最新版本。我有一个程序员朋友也在检查这个问题,他也发现了同样的问题。在我看来,这要么是一个bug,要么是一些我对Youtube API不感兴趣的东西……你完全正确,真正的问题是正则表达式。我也刚刚发现它“吃”“最后一个字符是作为更新发布的,只是发现你已经发布了:)不幸的是,我根本不懂正则表达式,所以我使用的是我在网上找到的东西。你知道我们如何修复它,使它不会“吃掉”最后一个字符吗?作为其他读者的参考,这是一个糟糕的正则表达式:
$embeddepattern='%(?:https?:/)(?:www\)(?:youtu\.be/| youtube\.com(?:embed/|/v/|/watch\?v=)([\w-]{10,12})[a-zA-Z0-9\\\\>\\\\\\\\\\\\\\\\\\\]%x'
只需删除最后一部分,就剩下了:
%(?:https:/)(:https://youtube://watch embed/.)([\w-]{10,12})%x'
修复了它。非常感谢@Levi
<html>
<head>

</head>
<body>

<?php
    $content = '
    <h3>This is a sample page to demonstrate the issue...</h3>
    Text before <br /><br />
    <iframe width="560" height="315" src="//www.youtube.com/embed/KSyHWMdH9gk?rel=0" frameborder="0" allowfullscreen></iframe>
    Text in between.
    <iframe width="560" height="315" src="//www.youtube.com/embed/b-u5LE6X6ME?rel=0" frameborder="0" allowfullscreen></iframe>
    <br /><br />Text after.';

    $return_HTML  = '';

    // match any iframes
    $pattern = '~<iframe.*</iframe>|<embed.*</embed>~';
    preg_match_all($pattern, $content, $matches);


    // START Youtube Script
    $YT_scripts = '
            <script>
                /*
                ** Array of objects
                ** params containerID, videoID
                */
                var playerInfoList = []; ';

    $index = 0;
    foreach ($matches[0] as $match) {

        $embedPattern = '%(?:https?://)?(?:www\.)?(?:youtu\.be/| youtube\.com(?:/embed/|/v/|/watch\?v=))([\w-]{10,12})[a-zA-Z0-9\< \>\"]%x';

        $res=false;
        $res = preg_match($embedPattern, $match, $embedOutput); 

        if( $res ){
            $YT_scripts .= '
            //new object
            var newItem = {containerID:"social_share_custom_'.$index.'", videoID:"'.$embedOutput[1].'"};

            //put it into array
            playerInfoList.push(newItem);';             

            $wrappedframe = '<div class="social_share_custom_video_container" id="social_share_custom_'.$index.'"></div>';
            $content = str_replace($match, $wrappedframe, $content);
        }
    $index++;
    }

    $content .= $YT_scripts.'</script>';    
    $return_HTML .= $content;   

    echo $return_HTML;
?>

<script>
//Load Yotube API
var tag = document.createElement("script"); 
tag.src = "https://www.youtube.com/iframe_api"; 
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

/*
// if we declare this explicitly, Youtube API works.
// if this array if generated DYNAMICALLY (if we comment this out), Youtube API does not work.
var playerInfoList = [
    {containerID:'social_share_custom_0', videoID:'KSyHWMdH9gk'},
    {containerID:'social_share_custom_1', videoID:'b-u5LE6X6ME'}
];
*/

console.log( 'Object array length: ' + playerInfoList.length );

    function onYouTubeIframeAPIReady() {
        if(typeof playerInfoList === 'undefined')
            return; 

        for(var i = 0; i < playerInfoList.length;i++) {
            var player = createPlayer(playerInfoList[i]);
        }
    }

    function createPlayer(listItem){
        console.log( listItem.containerID + ' - ' + listItem.videoID );

        return new YT.Player(listItem.containerID, {
            height: '350',
            width: '480',
            videoId: listItem.videoID,
            events: {
                'onReady': onPlayerReady,
                'onStateChange': onPlayerStateChange,
                'onError' : onPlayerError
            }
        });
    }

    // autoplay video
    function onPlayerReady(event){
        // video is Ready
    }

    // when video ends
    function onPlayerStateChange(event) {        
        console.log(event);

        if(event.data == 0) {
            // video Ended
            // showEndVideoPrompt();
            console.log('Video Ended.');
        }
        else if (event.data === 1) {
            //video Started
        }
        else if (event.data === 2) {
            //video Stopped
        }           
    }

    function onPlayerError(event) {
        // video Error
    }
</script>

</body>
</html>