2

我被困在这里,任何提示都会很好。
我有一个 Objects 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 循环的最后一次执行。就像现在一样,这行得通。
但不起作用的是,点击功能也应该应用于与选择器匹配的 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[] 数组在 objects[0]、objects[1]、objects[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"
});
4

2 回答 2

4

您需要使用事件委托,并在父元素而不是元素本身上侦听这些事件。这样,如果您稍后添加新元素,则无需重新绑定到它们。

$("#buttons").on("click", ".button", function(){
    console.log("You clicked on a .button element.");
});

在这种情况下,我们绑定到 on 上的 click 事件#buttons,但仅当调用元素与选择器匹配时.button。您的标记将类似于以下内容:

<div id="buttons">
    <a class="button">Foo</a>
    <a class="button">Bar</a>
</div>

当任何元素上发生单击.button并冒泡到#buttons父元素时,它将被拦截并触发处理程序。

于 2012-10-28T03:01:01.220 回答
1

这是因为 index 在您的绑定语句之外声明。当点击进入该调用时,它不知道 objects[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");
于 2012-10-28T04:26:55.200 回答