簡體   English   中英

如何在Javascript中向帶有元素數組的參數添加事件處理程序?

[英]How to Add Event Handler with Arguments to an Array of Elements in 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, dao_id, 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, {
                duration: 1,
                delay: (down_delay++)
        });
    }
}

首先,記住click事件中的執行范圍。 該上下文中的this關鍵字指的是被單擊的元素。 有沒有辦法可以從點擊的元素中確定dao_id?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM