我被困在这里,任何暗示都会很好
我有一个Objects对象[]和一个divnames []数组。我的对象上有play()和stop()等函数。对象及其功能在多种情况下进行了测试,它们正在运行。现在我尝试迭代divnames []并将适当对象[]的动作分配给mouseover,mouseout和click。
有一个闭包问题,我修复了一个解决方案,我在StackOverflow上的另一个线程中找到了。这样可行。但剩下的问题是鼠标悬停等操作未分配给稍后加载的div。他们正在从一开始就处理页面上的对象
这就是我所拥有的:
$(function(){
for (var i=0, len=divnames.length; i<len; i++) {
if(divnames[i]){
(function( ) { // anonymous function to fix closures
var index = i; // also needed to fix closures
$('#'+divnames[index]).on("click", function() {
objects[index].play();
loadContent(divnames[index]+".php");
});
})( ); // direct function execution to fix closures
}
}
});
如上所述,闭包问题由两个注释行修复,将它们离开只会应用for循环的最后一次执行。就像现在一样,这是有效的
但是什么不起作用,是click函数也应该应用于匹配选择器的div,但尚未加载
但是,如果具有相同功能的代码没有在没有闭包修复的情况下在for循环内迭代,那确实有效,因为如果我理解正确的话,那就是预期的.on()行为。
那么我如何才能获得所需的功能?
感谢您的提前时间。
---- ----编辑
要求的其他信息:
var divnames = [];
divnames[0] = "home";
divnames[1] = "about";
divnames[2] = "projects";
function SpriteAnim (options) {
var timerId = 0;
var i = 0;
this.status = 0;
this.init = function () {
var element = document.getElementById(options.elementId);
element.style.width = options.width + "px";
element.style.height = options.height + "px";
element.style.backgroundRepeat = "no-repeat";
element.style.backgroundImage = "url(" + options.sprite + ")";
};
this.showFrame = function (which) {
if (which < options.frames) {
i = which;
element = document.getElementById(options.elementId);
element.style.backgroundPosition = "0px -" + which * options.height + "px";
}
};
this.play = function () {
this.status = 2;
timerId = setInterval(function () {
if (i < (options.frames - 1)) {
i++;
element = document.getElementById(options.elementId);
element.style.backgroundPosition = "0px -" + i * options.height + "px";
} else {
clearInterval(timerId);
this.status = 1;
}
}, 100);
};
}
正如您可能已经猜到的那样,objects []数组在对象[0],对象[1],对象[2]中包含3个SpriteAnim对象。
objects[0] = new SpriteAnim({
width: 7,
height: 7,
frames: 8,
sprite: "myanim1.png",
elementId: "anim0"
});
objects[1] = new SpriteAnim({
width: 7,
height: 7,
frames: 8,
sprite: "myanim1.png",
elementId: "anim1"
});
objects[2] = new SpriteAnim({
width: 7,
height: 7,
frames: 8,
sprite: "myanim2.png",
elementId: "anim2"
});
答案 0 :(得分:4)
您需要使用事件委派,并在父元素而不是元素本身上侦听这些事件。这样,如果稍后添加新元素,则无需重新绑定它们。
$("#buttons").on("click", ".button", function(){
console.log("You clicked on a .button element.");
});
在这种情况下,我们绑定#buttons
上的click事件,但仅当调用元素与选择器.button
匹配时。你的标记将是这样的:
<div id="buttons">
<a class="button">Foo</a>
<a class="button">Bar</a>
</div>
当任何.button
元素发生咔嗒声,并且气泡到#buttons
父元素时,它将被拦截并且处理程序将被触发。
答案 1 :(得分:1)
这是因为索引是在绑定语句之外声明的。当点击进入该调用时,它不知道[index]是什么对象。
如果你想保持相同的结构,请像这样重写你的功能:
$(function(){
for (var i=0, len=divnames.length; i<len; i++) {
if(divnames[i]){
(function( ) { // anonymous function to fix closures
var index = i; // also needed to fix closures
$('#'+divnames[index]).on("click", function(e) {
switch ($(e.id).attr('name')){
case 'home':
objects[0].play();
loadContent('home.php');
break;
case 'about':
// do same
case 'projects':
// do same
default:
break;
}
});
})( ); // direct function execution to fix closures
}
}
});
实际上,你应该这样做:
$(document).on('click','div[name=home],div[name=projects],div[name=about]', function(){
var name = $(this).attr('name');
switch (name){
case 'home':
objects[0].play();
break;
// and so on
}
loadContent(name + '.php');
});
当你点击你的div时,这就是它所知道的全部:
objects[index].play();
loadContent(divnames[index]+".php");