HTML5跟踪元素提示事件Buggy?

我正在尝试dynamic地将函数分配给HTML5的cue.onenter事件。 这是一项非常新的function,目前只有在启用了特定标志的Chrome中才支持(请参阅HTML5 Rocks示例)。

不过,要么是由于早期的发展,是错误的,或者我做错了什么。 基本上,我有一个正常的HTML页面上的轨道元素。 没什么奇怪的

 <audio id="audiocast" controls oncanplay="setReadyToPlay();"> <source id="audiosource" src="SomeWorkingUrlwithaudio" ></source> <track kind="metadata" id="audioTrack" label="slides" src="/data.vtt" default > </track> Your Browser does not support HTML5 </audio> 

我通过JavaScript访问它,如下所示:

 //(...) var trackElements = $("#audiocast")[0].children("track")[0]; _track = trackElements.track; _cues = _track.cues; for (var j = 0; j < _cues.length; ++j) { var cue = _cues[j]; cue.onenter = getOnEnter(j); } //(...) function getOnEnter(idx) { return function() { setCueIdx(idx); updateURL(idx); var json = JSON.parse(this.text); _currImgSrc = json.src; drawIt(); } }; 

但是,这只有一些时间。 有时我必须重新加载浏览器3次以使其工作(例如,当我input提示时绘制图像),或者它在工作时,它随机地工作,直到达到10的提示4,然后停止工作。

这只是没有意义,但也许你们中的一些人有一个想法如何提供备用和稳定的解决scheme。

附加信息:这作为Node.js应用程序运行。 下面是处理提示的媒体播放器的完整源代码。

请注意,由于堆栈溢出的沙箱脚本,该代码段将不起作用。

 /* * slideCastController.js * © by pschne2s, nkopp2s, 2012 * * Basically encapsulates the Media Player Object, handling the function of the HTML5-Player */ /****************************OBJECT DEFINITION***********************************/ CanvasRenderingContext2D.prototype.clear = CanvasRenderingContext2D.prototype.clear || function(preserveTransform) { if (preserveTransform) { this.save(); this.setTransform(1, 0, 0, 1, 0, 0); } this.clearRect(0, 0, this.canvas.width, this.canvas.height); if (preserveTransform) { this.restore(); } }; var mediaPlayer = (function() { //Members var _cueIdx = 0; var _cues = []; var _target; var _track; var _readyToPlay = false; var _currImgSrc; function setupCues() { if (_readyToPlay) { if (_track === undefined) { // var trackElements = document.getElementById("audioTrack"); var trackElements = $(_target).children("track")[0]; _track = trackElements.track; } _cues = _track.cues; $("#maxcues").text(_cues.length - 1); for (var j = 0; j < _cues.length; ++j) { var cue = _cues[j]; cue.onenter = getOnEnter(j); } _track.oncuechange = function() { //updateURL(mediaPlayerInfo.cueIdx); }; checkFragments(); } else { setTimeout(setupCues, 1); } }; function getOnEnter(idx) { return function() { setCueIdx(idx); updateURL(idx); var json = JSON.parse(this.text); _currImgSrc = json.src; drawIt(); } }; function drawIt() { var ctx = $("#slide")[0].getContext('2d'); ctx.clear(); var tmpImg = new Image(); tmpImg.onload = function() { ctx.drawImage(tmpImg, 0, 0, 592, 256); } tmpImg.src = _currImgSrc; } function checkFragments() { var fragments = purl(window.document.URL); var slide = fragments.fparam("slide"); if (slide !== undefined) { gotoCue(slide); } var action = fragments.fparam("action"); if (action == "play") { _target.play(); } }; function setCueIdx(idx) { //alert("Cue idx set to: " + idx); _cueIdx = idx; $("#cueidx").text(idx); }; function gotoCue(index) { if (index >= 0 && index < _cues.length) { _cueIdx = index; var audioElement = $("#audiocast").get(0); //mediaPlayerInfo.cues[mediaPlayerInfo.cueIdx].onenter(); audioElement.currentTime = _cues[index].startTime; } }; var updateURL = (function() { // set Base-URL (without query/hash-String) var url = location.protocol + "//" + location.host + location.pathname; var html5 = window.history.replaceState !== undefined ? true : false; return function(slideIdx) { if (html5) window.history.replaceState(null, document.title + " | Slide #" + slideIdx, url + "#slide=" + slideIdx); else location.href = url + "#slide=" + slideIdx; // No nice browser history }; })(); return { init: function() { setupCues(); }, setTarget: function(obj) { _target = obj; }, setTrack: function(obj) { _track = obj; }, setReadyToPlay: function() { _readyToPlay = true; }, gotoNextCue: function() { gotoCue(_cueIdx + 1); }, gotoPrevCue: function() { gotoCue(_cueIdx - 1); } }; })(); $(document).ready(function() { // "Unobstrusive" Function-Bindings $("#btnPrevCue").bind("click", mediaPlayer.gotoPrevCue); $("#btnNextCue").bind("click", mediaPlayer.gotoNextCue); mediaPlayer.setTarget($("#audiocast")[0]); mediaPlayer.init(); }); window.setReadyToPlay = mediaPlayer.setReadyToPlay; // does not work using other ways atm 

内容从原始问题复制


显然,audio/音轨元素真的很怪异。 不过,“救命”似乎运作得很好。 我现在这样做了:

 var _cueLookup = new Object(); _cues = _track.cues; //track-element cues. for (var j = 0; j < _cues.length; ++j) { var cue = _cues[j]; //cue.onenter = getOnEnter(j); _cueLookup[cue.id] = j; //alert(_cueLookup[cue.id]); } _track.oncuechange = function() { // "this" is a textTrack var cue = this.activeCues[0]; // assuming there is only one active cue