Javascript jQuery:单击函数bind-in for-loop with-closure-fix

Javascript jQuery:单击函数bind-in for-loop with-closure-fix,javascript,jquery,arrays,object,closures,Javascript,Jquery,Arrays,Object,Closures,我被困在这里,任何提示都很好。 我有一个Objects[]数组和一个divname[]数组。我的对象上有play()和stop()等函数。对象及其功能在多种情况下进行了测试,它们正在工作。现在,我正在尝试迭代divnames[],并将相应对象[]的操作分配给mouseover、mouseout和click。 有一个关闭问题,我用在StackOverflow上的另一个线程中找到的解决方案修复了这个问题。这很有效。但剩下的问题是,mouseover等操作没有分配给稍后加载的div。他们正在处理从一开

我被困在这里,任何提示都很好。
我有一个Objects[]数组和一个divname[]数组。我的对象上有play()和stop()等函数。对象及其功能在多种情况下进行了测试,它们正在工作。现在,我正在尝试迭代divnames[],并将相应对象[]的操作分配给mouseover、mouseout和click。
有一个关闭问题,我用在StackOverflow上的另一个线程中找到的解决方案修复了这个问题。这很有效。但剩下的问题是,mouseover等操作没有分配给稍后加载的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
        }
    }
});

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

$("#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
父元素时,它将被拦截并触发处理程序。

这是因为索引是在绑定语句之外声明的。当点击进入该调用时,它不知道什么是对象[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
        }
    }
});
编辑: 当您单击div时,它只会知道以下内容:

objects[index].play();
loadContent(divnames[index]+".php");

你能分享你的两个阵列吗;这可能会帮助我们为您提供一个更好的答案。如果问题出在for循环和闭包修复结构中,为什么它可以完美地与所示的单个元素选择器配合使用?我正在尝试应用您的解决方案,但由于每个divname都有一个对象,需要独立于其他对象进行反应,这非常令人困惑。@KarlKratzisheim提供了您的数组,也许我可以为您提供一个更定制的解决方案。我添加了var index2=index;在绑定内部,并具有对象[index2].play();相反仍然不起作用,与选择器匹配的延迟加载元素没有反应。还是我误解了解决方案应该是什么样子?你误解了。此中的代码:
$('#'+divnames[index])。打开(“单击”…
是所有将被触发的内容,因此在您单击时,它周围的循环将永远不会被击中。您必须确定在适当的上下文中单击了哪个按钮。与其尝试使您的解决方案适合问题,不如将重点放在使正确的解决方案适合问题上。正确的解决方案是绑定事件,正如我在第二个代码示例。我只是想向您解释为什么它不起作用。谢谢您的帮助。我只有一个问题:如果我在click事件中放置一个简单的console.log(“hello”);即使它不需要知道任何东西,也不会显示出来。我想这是因为$('#'+divnames[index])for循环的内部永远不会知道它在单击时的索引?嗯,$('#'+divnames[index])只是一个选择器。它是一个针对dom的查询,用于选择要将单击事件绑定到的元素。因此,如果您只是使用.on('click')执行此操作,我认为它应该触发日志调用。
$(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');
});
objects[index].play();
loadContent(divnames[index]+".php");