Javascript - Dynamically assign onclick event in the loop

前端 未结 7 1084
无人共我
无人共我 2020-11-27 19:38

I have very simple html page with js code:


    
        
    
    

        <         


        
相关标签:
7条回答
  • 2020-11-27 20:13

    I attach an event handler:

            window.onload = function() {
                var folderElement;
                tagFolders = document.getElementById("folders");
                for (i = 0; i < folders.length; i++) {
                    folderElement = folderButtons[i];
                    folderElement = document.createElement("button");
                    folderElement.setAttribute("id", folders[i]);
                    folderElement.setAttribute("type", "button");
                    folderElement.innerHTML = folders[i];
                    if (typeof window.addEventListener !== "undefined") {
                        folderElement.addEventListener("click", getFolderElement, false);
                    } else {
                        folderElement.attachEvent("onclick", getFolderElement);
                    }
                    tagFolders.appendChild(folderElement);
                }
    

    which can retrieve anything from the element that triggered the event:

    // This function is the event handler for the folder buttons.
    function getFolderElement(event) {
        var eventElement = event.currentTarget;
        updateFolderContent(eventElement.id);
    }
    

    in which case you have to embed the option inside the element / tag. In my case I use the id.

    0 讨论(0)
  • 2020-11-27 20:20

    You pass just the reference of the variable to the function, not it's value. So every time the loop is iterated, it assigns a reference to your anonymous function and all of them point to the same value in memory. But since you use the same variable name in the loop, you overwrite the value of the variable. You can concatenate the variable to a string to preserve it's value. For example like that:

    btnShow.onclick = new Function("", "showParam(" + arrOptions[i] + ");");
    

    The first parameter is the name of the function but afaik it is optional (it can be left blank or omitted at all).

    0 讨论(0)
  • 2020-11-27 20:22

    For jquery, check out the adding event data section from the API:

    ...
    for (var i = 0; i < arrOptions.length; i++) {
    
        $('<input id="btn" type="button" value="Show Me Option"><input>').appendTo("#divButtons")
    
        $('#btn').bind("click", {
            iCount: i},
        function(event) {
            showParam(arrOptions[iCount]);
        });
    }
    
    0 讨论(0)
  • 2020-11-27 20:26

    Consider the fact that when the onclick() function is executed, all it has is:

    showParam(optionPar);
    

    , verbatim. The optionPar will be resolve at the time the click event is executed, and at this point it most likely be the latest value you assigned to it. You should generally avoid passing variables in such a way.

    The problem you are trying to solve is best solved by re-writing the piece such as:

                btnShow.value = "Show Me Option";
                var optionPar = arrOptions[i];
                btnShow.optionPar = optionPar;
                btnShow.onclick = function(e) {
                    // if I'm not mistaking on how to reference the source of the event.
                    // and if it would work in all the browsers. But that's the idea.
                    showParam(e.source.optionPar);
                }
    
    0 讨论(0)
  • 2020-11-27 20:33

    The accepted answer is correct but I feel that no real explanation was done.

    Let me try to explain, the issue here is classical missing closure.

    The variable 'i' is getting increased by 1 per loop iteration, and the on-click event actually is not being executed, whether only applied to the a element, it getting summarize up to the length of arrOptions which is 10.

    So, the loop continues up until 'i' is 10, Then, whenever the on-click event is being triggered, it takes the value of i which is 10.

    now, for the solution, in the solution we are using a closure, so that when we apply the value of 'i' to the on-click event of the a element, it actually gets the exact value of i at in time.

    The inner function of the onclick event create a closure where it references the parameter (arrOptions[i]), meaning what the actual i variable is at the right time.

    The function eventually closes with that value safely, and can then return its corresponding value when the on-click event is being executed.

    0 讨论(0)
  • 2020-11-27 20:34

    The accepted answer seems to work, but seems to be confusing and a somewhat cumbersome way to do it. A better way perhaps might be to use the data attribute for the element you're looking to assign the event listener for. It's simple, easy to understand, and way less code. Here's an example:

    btnShow.data = arrOptions[i];
    
    btnShow.onclick = function() {
      showParam(this.data);
    }
    
    0 讨论(0)
提交回复
热议问题