如何在Javascript中向带有元素数组的参数添加事件处理程序?

我有一个完整依赖 JavaScript和Ajax的三步流程来加载数据并使流程从一个步骤动画到下一个步骤.更复杂的是,步骤之间的转换(向前和向后)是动画的:-(.当用户通过进程锚点的进度显示当前步骤和前面的步骤时.如果他们点击上一步骤,则将它们带回上一步.

现在,如果从步骤1开始,整个过程(向前和向后)都能正常工作,但如果直接跳到步骤3,则步骤1和步骤2的锚点也会执行与步骤3相同的操作.

这是代码的一部分,循环遍历用户所在的当前步骤的所有步骤,并依次显示每个锚点并为click事件分配适当的函数:

for (var i = 0; i < profile.current + 1; i++) {
    if ($('step_anchor_' + i).innerHTML.empty()) {
        var action = profile.steps[i].action;
        var dao_id = profile.steps[i].dao_id;

        $('step_anchor_' + i).innerHTML = profile.steps[i].anchor;
        $('step_anchor_' + i).observe('click',function(){
            pm.loadData(action,dao_id,true);
        });

        Effect.Appear('step_anchor_' + i,{
            duration: 1,delay: (down_delay++)
        });
    }
}

我知道问题在于传递action和dao_id参数的方式.我也尝试传递profile.steps [i] .action和profile.steps [i] .dao_id,但在这种情况下,无论是profile还是i或至少我的范围.

我该怎么做才能为每个步骤正确分配action和dao_id的参数? (如果它有任何区别我们正在使用Prototype和Scriptaculous)

解决方法

你的闭包范围链正在引发你的问题.通过内联声明处理函数,您已经创建了一个闭包.显然你这样做是为了利用循环.

但是,由于您已经创建了一个闭包,因此您将通过闭包范围规则进行游戏.这些规则规定,只要闭包存在,父函数中的局部变量就会保持活动状态并且可用.

你试图通过然后使用“action”和“dao_id”到你的闭包,但你在这里传递引用,而不是值.因此,当调用闭包(处理程序)时,它们使用上次分配引用的值.在您的情况下,步骤3处理程序.

关闭范围规则很容易混淆,但是即使循环块已经完成执行,“action”和“dao_id”仍然存在这一事实也可能会使您感到困惑.好吧,在JavaScript中没有块范围这样的东西.声明变量后,它将一直可用,直到函数结束或直到删除为止.以先到者为准.

总而言之,你需要打破范围链.这有两种方法:

试试这个:

for (var i = 0; i < profile.current + 1; i++) {
    if ($('step_anchor_' + i).innerHTML.empty()) {
        var action = profile.steps[i].action;
        var dao_id = profile.steps[i].dao_id;

        $('step_anchor_' + i).innerHTML = profile.steps[i].anchor;
        $('step_anchor_' + i).observe('click',function(a,b){
                return function(){pm.loadData(a,b,true)};
        }(action,dao_id));

        Effect.Appear('step_anchor_' + i,{
                duration: 1,delay: (down_delay++)
        });
    }
}

或这个:

function createHandler(action,dao_id) {
    return function(){pm.loadData(action,true);};
} 

/* snip - inside some other function */
for (var i = 0; i < profile.current + 1; i++) {
    if ($('step_anchor_' + i).innerHTML.empty()) {
        var action = profile.steps[i].action;
        var dao_id = profile.steps[i].dao_id;

        $('step_anchor_' + i).innerHTML = profile.steps[i].anchor;
        $('step_anchor_' + i).observe('click',createHandler(action,dao_id));
        Effect.Appear('step_anchor_' + i,delay: (down_delay++)
        });
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)