【问题标题】:Declare a global variable from inside a function从函数内部声明一个全局变量
【发布时间】:2012-05-23 10:22:33
【问题描述】:

我有以下代码,这是使用他们的 Javascript API 在我的页面中跟踪嵌入的 Youtube 视频所必需的:

function onYouTubePlayerReady(playerId) {
      var youtubeplayer = document.getElementById('youtubeplayer');
      youtubeplayer.addEventListener("onStateChange", "onytplayerStateChange");
      youtubeplayer.setPlaybackQuality('large');
      }

function onytplayerStateChange(newState) {
    //Make it autoplay on page load
    if (newState == -1) {
        youtubeplayer.playVideo();
        }

    var tiempo = youtubeplayer.getCurrentTime();
    //Rounds to 2 decimals
    var tiempo = Math.round(tiempo*100)/100;
    alert(tiempo);
    }

(与 Youtube API 相关的细节并不重要,但如果你好奇,它们在我之前的问题中 Youtube Javascript API: not working in IE)。

现在,我的问题是 onYoutubePlayerReady() 函数声明了“youtubeplayer”,它是对 DOM 对象的引用,我也需要从另一个函数 onytplayerstateChange() 访问该变量......但是“youtubeplayer”被声明为局部变量。这适用于 IE 8、Safari...,但不适用于 Firefox 12。当然,我可以通过以下方式获得对“youtubeplayer”的引用,而不使用“var”:

youtubeplayer = document.getElementById('youtubeplayer');

事实上,这就是它在 Youtube 的示例代码中的样子,但是如果我这样写,代码在 IE 8 中不起作用(而它在 Firefox 12 中起作用;有关更多详细信息,请参阅我之前的问题)。

...所有这些都让我想到:有没有办法从函数内部声明一个全局变量(如上面的“youtubeplayer”),以便其他函数也可以访问它?适用于所有浏览器的东西?

【问题讨论】:

  • 你为什么不在函数外声明你的变量?
  • 为什么不在函数外声明变量?因为 Youtube 的 API 不允许我这样做。它的结构方式是,当加载视频播放器对象时,它会调用一个名为“onYouTubePlayerReady()”的回调函数,它会设置其他所有内容。
  • 感谢您提供另一个问题的链接,顺便说一句。我从那里得到了很好的想法,我会尽快进行测试。

标签: javascript dom youtube-api


【解决方案1】:

另一种声明全局变量的方法是将其创建为全局“窗口”对象的额外属性——这样做

window.youtubeplayer = document.getElementById('youtubeplayer'); 

这应该可以被页面上的其他任何东西访问。所以你的完整代码应该是这样的;

function onYouTubePlayerReady(playerId) {
  window.youtubeplayer = document.getElementById('youtubeplayer');
  window.youtubeplayer.addEventListener("onStateChange", "onytplayerStateChange");
  window.youtubeplayer.setPlaybackQuality('large');
}

function onytplayerStateChange(newState) {
  //Make it autoplay on page load
  if (newState == -1) {
    window.youtubeplayer.playVideo();
  }

  var tiempo = window.youtubeplayer.getCurrentTime();
  //Rounds to 2 decimals
  var tiempo = Math.round(tiempo*100)/100;
  alert(tiempo);
}

【讨论】:

    【解决方案2】:

    您可以在 ready 函数中创建一个事件处理程序并直接将其传入,而不是将您的 onytplayerStateChange 函数的字符串引用传递给事件侦听器,如下所示:

    function onYouTubePlayerReady(playerId) {
        var youtubeplayer = document.getElementById('youtubeplayer');
        var stateChangeHandler = function (newState) {
            //Make it autoplay on page load
            if (newState == -1) {
                youtubeplayer.playVideo();
            }
            var tiempo = youtubeplayer.getCurrentTime();
            //Rounds to 2 decimals
            var tiempo = Math.round(tiempo*100)/100;
            alert(tiempo);
        };
        youtubeplayer.addEventListener("onStateChange", stateChangeHandler);
        youtubeplayer.setPlaybackQuality('large');
    }
    

    甚至直接传入一个匿名函数:

    function onYouTubePlayerReady(playerId) {
        var youtubeplayer = document.getElementById('youtubeplayer');
        youtubeplayer.addEventListener("onStateChange", function (newState) {
            //Make it autoplay on page load
            if (newState == -1) {
                youtubeplayer.playVideo();
            }
            var tiempo = youtubeplayer.getCurrentTime();
            //Rounds to 2 decimals
            var tiempo = Math.round(tiempo*100)/100;
            alert(tiempo);
        });
        youtubeplayer.setPlaybackQuality('large');
    }
    

    这保留了“onYouTubePlayerReady”函数内的 youtubeplayer 变量的范围,并绕过了建立全局变量的需要。

    【讨论】:

    • 嗯...我不知道 Youtube 的 API 是否支持这个。他们的文档将 addEventListener() 中的第二个参数显示为字符串,而不是函数。尽管如此,我会在其他场合记下这个提示:-)
    • 啊,我看到这个 API 不是模拟普通的 addEventListener,而是只允许传递给 flash 接口的字符串引用。看起来有一种方法可以传入an anonymous function as a string to be eval'd
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2015-12-14
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多