我已将JavaScript包装在一个自我调用函数中,以保持所有内容。但是,我遇到了一个问题,即动态构建的链接会返回错误"功能未定义"当他们被点击时。让我包括我的相关代码:
(function(window, document, $) {
function buildChapterList() {
for(var i=0; i<Object.keys(theChapterCues).length; i++) {
chapterListHTML = "<li><a class='fun-blue' href='javascript:void(0)' onClick=\"skipToChapter('"+ i +"')\">"+ theChapterCues[i]["title"] +"</a></li>";
$(chapterListHTML).appendTo("ul#chapter-list");
$("body").bind("DOMNodeInserted", function() {
$(this).find('#chapter-list li').first().addClass("active");
});
}
}
function skipToChapter(theChapter) {
if (theChapter == 0) {
theVideo.currentTime=0;
} else {
var thisChapterStart = parseInt(cues[theChapter]["chapterStart"]+1);
theVideo.currentTime=thisChapterStart/frameRate;
}
}
}(this, this.document, this.jQuery));
点击其中一个生成的链接时,我收到以下错误:
未捕获的ReferenceError:未定义skipToChapter
我在范围上遗漏了什么吗?这是一个约束性问题吗?任何建议将不胜感激。谢谢!
答案 0 :(得分:3)
skipToChapter
函数不在全局范围内,因此无法从内联单击处理程序调用。相反,您应该在构建链接时以一种不显眼的方式分配单击处理程序,如下所示。如果您这样分配,那么skipToChapter
就在范围内,您不必将其设为全局,并且您不需要不受欢迎的内联事件处理程序。
function buildChapterList() {
for(var i=0; i<Object.keys(theChapterCues).length; i++) {
chapterListHTML = $("<li><a class='fun-blue' href='javascript:void(0)'>"+ theChapterCues[i]["title"] +"</a></li>");
(function(i){
chapterListHTML.find('a').click(skipToChapter.bind(this, i));
})(i);
chapterListHTML.appendTo("ul#chapter-list");
$("body").bind("DOMNodeInserted", function() {
$(this).find('#chapter-list li').first().addClass("active");
});
}
}
答案 1 :(得分:2)
skipToChapter
函数仅在外部匿名函数中可见。您可以在此处阅读有关Javascript范围的信息:http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
解决问题的快速而肮脏的方法是在匿名函数之外定义skipToChapter
或作为窗口对象的成员。
例如:
window.skipToChapter = function(theChapter) {
if (theChapter == 0) {
theVideo.currentTime=0;
} else {
var thisChapterStart = parseInt(cues[theChapter]["chapterStart"]+1);
theVideo.currentTime=thisChapterStart/frameRate;
}
}
但是,请注意,这不是将函数绑定到事件的最佳做法,因为它使skipToChapter
全局并使用内联事件处理程序(http://robertnyman.com/2008/11/20/why-inline-css-and-javascript-code-is-such-a-bad-thing/)。
更好的方法是:
function buildChapterList() {
for(var i=0; i<Object.keys(theChapterCues).length; i++) {
chapterListHTML = "<li><a class='fun-blue' href='javascript:void(0)' data-index='" + i + "'>"+ theChapterCues[i]["title"] +"</a></li>";
var $chapterListHTML = $(chapterListHTML);
$chapterListHTML.appendTo("ul#chapter-list");
$chapterListHTML.find('a').click(skipToChapter);
$("body").bind("DOMNodeInserted", function() {
$(this).find('#chapter-list li').first().addClass("active");
});
}
}
function skipToChapter() {
var theChapter = $(this).data('index');
if (theChapter == 0) {
theVideo.currentTime=0;
} else {
var thisChapterStart = parseInt(cues[theChapter]["chapterStart"]+1);
theVideo.currentTime=thisChapterStart/frameRate;
}
}
阅读此答案,了解有关使用jQuery进行事件绑定的更多信息:Event binding on dynamically created elements?