我有一个简单的HTML 5视频块,用户可以通过按提供的上一个和下一个按钮来播放下一个视频或上一个视频。
这是我到目前为止所拥有的:
HTML
<div id="video-container">
<h1 class="movie-title">Movie title</h1>
<video class="videoplayer" id="video-player_transformed" playsinline autoplay muted="muted"></video>
</div>
JS
(function($) {
"use strict";
/**
* Ajax response data will be stored in this local variable
* @var {Array}
*/
var myData = [];
/**
* jQuery video element
* @var {Object}
*/
var $player = $("video#videoplayer");
/**
* jQuery movie title element
* @var {Object}
*/
var $title = $(".movie-title");
/**
* jQuery previous button element
* @var {Object}
*/
var $prev = $(".prev");
/**
* jQuery next button element
* @var {Object}
*/
var $next = $(".next");
/**
* Custom jQuery function to add sources to a media element
* @param {Array|String} sources
*/
$.fn.setSource = function(sources) {
// Get the media tag (video/audio)
var tag = this.prop("tagName").toLowerCase();
// Clear any existing sources
this.empty();
// Check if sources paramater is an array
if (Array.isArray(sources)) {
// Loop through each source
for (let i = 0; i < sources.length; i++) {
var src = sources[i];
var type = /(?:\.([^.]+))?$/.exec(src); // Get file extention (.mp4, .ogv, .webm etc)
if (type[0]) {
type = type[0].replace(".", "");
}
// Create and append a source tag
this.append(
$("<source>", {
src: src,
type: tag + "/" + type
})
);
}
} else {
this.attr("src", sources);
}
};
/**
* Reusable function to update player element
* @param {Object} data Expects an object with `link` and `title` attributes
*/
function updatePlayer(data) {
$player.setSource(data.link); // Set the video source
$title.text(data.title); // Add the title
}
// Disable actions because we have no data
$prev.prop("disabled", true);
$next.prop("disabled", true);
// Send request to server to recieve data
$.ajax({
dataType: "json",
url: "http://localhost:8080/videoexplainer/data/video.json,"
})
.then(function(data) {
myData = data; // replace `myData` with the ajax response data
// Check if we have data
if (myData && myData.length) {
// Re-enable actions because we have data
$prev.prop("disabled", false);
$next.prop("disabled", false);
updatePlayer(data); // Set the video source (see functions above)
$player.get(0).play(); // Play the html5 video*
// *Most browsers will not allow playing without any user interaction
}
})
.fail(function(error) {
// Request failed, inform user
alert(
"There was an error downloading videos, please refresh and try again."
);
console.warn(error);
});
// On click set video element to PREVIOUS video in myData
$prev.on("click", function() {
// Check if we have data before attempting to access it
if (myData && myData.length) {
updatePlayer(myData[i === 0 ? myData.length - 1 : --i]);
$player.get(0).play();
}
// Prevent default click action
return false;
});
// On click set video element to NEXT video in myData
$next.on("click", function() {
// Check if we have data before attempting to access it
if (myData && myData.length) {
updatePlayer(myData[i === myData.length - 1 ? 0 : ++i]);
$player.get(0).play();
}
// Prevent default click action
return false;
});
})(jQuery || window.jQuery);
不幸的是,当我运行我的应用程序时,出现以下两个错误:
There was an error downloading videos, please refresh and try again.
在浏览器控制台中,打印出以下错误:
jquery-3.3.1.min.js:2 jQuery.Deferred异常:无法读取未定义类型的属性“ toLowerCase”:无法读取未定义的属性“ toLowerCase” 在w.fn.init。$。fn.setSource(http://localhost:8080/index_test.html:122:47) 在updatePlayer(http://localhost:8080/index_test.html:154:25) 在对象。 (http://localhost:8080/index_test.html:176:21) 在l(https://code.jquery.com/jquery-3.3.1.min.js:2:29375) 在c(https://code.jquery.com/jquery-3.3.1.min.js:2:29677)处未定义
index_test.html:184 TypeError:无法读取未定义的属性“ toLowerCase” 在w.fn.init。$。fn.setSource(index_test.html:122) 在updatePlayer(index_test.html:154) 在对象。 (index_test.html:176) 在l(jquery-3.3.1.min.js:2) 在c(jquery-3.3.1.min.js:2)
此代码有什么问题?
答案 0 :(得分:4)
此行:var $player = $('video#videoplayer');
需要更改为:var $player = $('video.videoplayer');
我怎么知道这个?
$.ajax()
中存在代码错误,.then()
将失败。在这种情况下,错误出在函数.setSource()
中。它正在尝试获取不存在的元素的属性tagName
。