jQuery的:点击在for循环与封闭修复功能绑定 [英] jQuery: click function bind in for-loop with closure fix

查看:92
本文介绍了jQuery的:点击在for循环与封闭修复功能绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

林陷在这里,任何暗示将是很好。

我有对象的数组对象[]和divnames的[]数组。我的对象具有类似于上播放()和stop()函数。对象及其功能多种情况进行了测试,他们的工作。现在,我试着去遍历divnames []并指定相应的对象[]将鼠标悬停,鼠标移开,点击动作。

有一个封闭的问题,我固定一个解决方案,我这里在计算器上另一个线程发现。这样可行。但剩下的问题是,鼠标悬停等动作没有分配给已加载以后的div。他们正在是从开头页上的对象。

这里是我有:

  $(函数(){
    对于(VAR I = 0,LEN = divnames.length; I< LEN,我++){
        如果(divnames [I]){
            (函数(){//匿名函数来解决关闭
                VAR指数= I; //还需要解决关闭
                $('#'+ divnames [指数])。在(点击,函数(){
                    对象[指数] .play();
                    loadContent(divnames [指数] +。PHP的);
                });
            })(); //直接函数的执行来解决关闭
        }
    }
});

如上所述,闭合问题是由两个注释行固定,使他们走将只应用for循环的最后执行。因为它是现在,那工作。

但是,什么不工作,是该点击功能也应适用于选择器匹配的div,但尚未装载。

但是,这并工作,如果有相同的功能的code未里面迭代对于没有封闭修复循环,因为多数民众赞成预期。对()的行为,如果我理解正确。

让我怎么同时获得所需的功能,以工作?

感谢您的时间提前。

---- ----修改

的要求的其他信息:

  VAR divnames = [];
divnames [0] =家;
divnames [1] =约;
divnames [2] =项目;功能SpriteAnim(选项){
变种的timerId = 0;
    变种I = 0;
    this.status = 0;
this.init =功能(){
    VAR元=的document.getElementById(options.elementId);
    element.style.width = options.width +PX
    element.style.height = options.height +PX
    element.style.backgroundRepeat =不重复;
    element.style.backgroundImage =URL(+ options.sprite +);
};
this.showFrame =函数(){
    如果(这< options.frames){
                    I =其中;
        元素=的document.getElementById(options.elementId);
        element.style.backgroundPosition =0像素 - +其中* options.height +像素;
    }
};
this.play =功能(){
            this.status = 2;
    的timerId =的setInterval(函数(){
        如果(ⅰ≤(options.frames - 1)){
                            我++;
            元素=的document.getElementById(options.elementId);
            element.style.backgroundPosition =0像素 - + I * options.height +像素;
                    }其他{
                        clearInterval(的timerId);
                        this.status = 1;
                    }
    },100);
};
}

正如你可能已经猜到了,对象[]数组包含对象3 SpriteAnim对象[0]​​,对象[1],对象[2]。

 对象[0]​​ =新SpriteAnim({
    宽度:7,
    高度:7,
    框架:8,
    精灵:myanim1.png
    elementId:anim0
});
对象[1] =新SpriteAnim({
    宽度:7,
    高度:7,
    框架:8,
    精灵:myanim1.png
    elementId:anim1
});
对象[2] =新SpriteAnim({
    宽度:7,
    高度:7,
    框架:8,
    精灵:myanim2.png
    elementId:anim2
});


解决方案

这是因为指数是你的绑定声明之外的声明。当点击进入这一号召,它不知道是什么物体[索引]。

如果你想保持相同的结构,返工你的函数是这样的:

  $(函数(){
    对于(VAR I = 0,LEN = divnames.length; I< LEN,我++){
        如果(divnames [I]){
            (函数(){//匿名函数来解决关闭
                VAR指数= I; //还需要解决关闭
                $('#'+ divnames [指数])。在(点击,功能(E){
                    开关($(e.id).attr('名')){
                        情况下的家:
                            对象[0]​​ .play();
                            loadContent('home.php');
                            打破;
                        案件关于:
                        //做同样的
                        案工程:
                        //做同样的
                        默认:
                            打破;
                    }
                });
            })(); //直接函数的执行来解决关闭
        }
    }
});

实际上,你应该这样做:

 的$(document)。在('点击','格[名称=家园] DIV [名称=项目],DIV [名称=约]',函数(){
    变种名称= $(本).attr('名');
    开关(名称){
        情况下的家:
            对象[0]​​ .play();
            打破;
            // 等等
    }
    loadContent(名称+的.php');
});

编辑:

当你点击你的分区,这是所有都知道的:

 对象[指数] .play();
loadContent(divnames [指数] +。PHP的);

Im stuck here, any hint would be nice.
I have an array of Objects objects[] and an array of divnames[]. My object has functions like play() and stop() on it. The Object and its' functions were tested in multiple situations, they are working. Now im Trying to iterate over the divnames[] and assign actions of the appropriate objects[] to mouseover, mouseout and click.
There was a closure problem, that i fixed with a solution that i found in another thread here on StackOverflow. That works. But the problem remaining is that the mouseover etc. actions are not assigned to divs that are loaded later on. They are working on objects that are on the page from the beginning.
Here is what i have:

$(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
        }
    }
});

As stated above, closure problem is fixed by the two commented lines, leaving them away will only ever apply the last execution of the for-loop. As it is now, that works.
But what doesnt work, is that the click function should also be applied to divs matching the selector, but are not yet loaded.
But that does work if the code with the same functionality is not iterated inside a for loop without the closure-fix, because thats expected .on() behaviour if i understand correctly.

So how do i get both desired functionalities to work?

Thanks for your time in advance.

----edit----

Additional information as requested:

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);
};
}

As you probably have already guessed, the objects[] array contains 3 SpriteAnim objects in objects[0], objects[1], objects[2].

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"
});

解决方案

It's because index is declared outside of your binding statement. When the click goes into that call, it has no idea what objects[index] is.

If you want to keep the same structure, rework your function like this:

$(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
        }
    }
});

Realistically, you should do this:

$(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');
});

EDIT:

When you click your div, this is all it will be aware of:

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

这篇关于jQuery的:点击在for循环与封闭修复功能绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆