[removed] generate dynamically handler

后端 未结 1 752
囚心锁ツ
囚心锁ツ 2021-01-25 00:17

I\'m programming in Javascript.

I need to dynamically generate the event handlers for the onclick event.

Here above the code:

for (v         


        
1条回答
  •  北海茫月
    2021-01-25 01:09

    Three options:

    Use a Builder Function

    The usual way is to have a builder function for the handlers:

    for (var i = 1; i < CurrValue; i++) {
        getId('btnReadRFIDTag_' + i).onclick = buildHandler(i);
    }
    function buildHandler(index) {
        return function() {
            ReadRFIDTag(getId('txtCode_' + index));
        };
    }
    

    The function built by the buildHandler closes over the index argument from that call to buildHandler, rather than over i, and so it sees the right value.

    Use ES5's Function#bind

    If you can rely on ES5 (or you include an ES5 shim, as this is a shimmable feature), you can do it with Function#bind:

    // Using Function#bind (option 1)
    for (var i = 1; i < CurrValue; i++) {
        var elm = getId('btnReadRFIDTag_' + i);
        elm.onclick = function(index) {
            ReadRFIDTag(getId('txtCode_' + index));
        }.bind(elm, i);
    }
    

    Used like that, it creates unnecessary extra functions, so you could also use it like this:

    // Using Function#bind (option 2)
    for (var i = 1; i < CurrValue; i++) {
        var elm = getId('btnReadRFIDTag_' + i);
        elm.onclick = myHandler.bind(elm, i);
    }
    
    function myHandler(index) {
        ReadRFIDTag(getId('txtCode_' + index));
    }
    

    Use Event Delegation

    Instead of putting a handler on each button, if they're all in a container (and ultimately, of course, they are, even if it's just document.body), you can put the handler on that container and then use event.target to find out which button was clicked. I wouldn't do that with old-style onclick, but you can with addEventListener or attachEvent:

    var container = /* ...get the container... */;
    if (container.addEventListener) {
        container.addEventListener('click', clickHandler, false);
    }
    else if (container.attachEvent) {
        container.attachEvent('onclick', function(e) {
           return clickHandler.call(this, e || window.event);
        });
    }
    else {
        // I wouldn't bother supporting something that doesn't have either
    }
    
    function clickHandler(e) {
        var btn = e.target;
        while (btn && btn !== this && btn.id.substring(0, 15) !== "btnReadRFIDTag_") {
            btn = btn.parentNode;
        }
        if (btn && btn !== this) {
            ReadRFIDTag(getId('txtCode_' + btn.id.substring(15)));
        }
    }
    

    The way that works is by hooking the click event on the container, and then when the click bubbles up (down?) to it, it looks at where the click originated and sees if that (or an ancestor of it) is one of the buttons we care about. If it is, we act on it.

    0 讨论(0)
提交回复
热议问题