0

What i am trying to id attach addEventListener() to all the input fields so that every time a keyup event is activated so alert messages pop up for every input field

var inputs = document.querySelectorAll(".form-control");


for(var i=0;i<inputs.length;i++){
    elem = inputs[i]
  elem.addEventListener("keyup",alert(i)) 

}

this code does not work. it only works on page load. it only loops it one time

Holly Johnson
  • 509
  • 1
  • 13
  • 25
  • So this is the age old issue of "what is `i` during the loop?" The answer is, `i` is equal to the last value in the loop. In order to achieve, this, a closure is created – Sterling Archer May 08 '17 at 02:32
  • `it only works on page load. it only loops it one time` have your tried putting it in `window.onload`? ie, `window.onload=function(){var inputs= //...}` – chiliNUT May 08 '17 at 02:33
  • The second parameter of *addEventListener* is supposed to be a function. You are assigning the result of `alert(i)`, which is *undefined* so not assigning a function at all. – RobG May 08 '17 at 02:35
  • @SterlingArcher - That other question isn't what's wrong here, though it could be the *next* problem after [this issue](http://stackoverflow.com/questions/16310423/addeventlistener-calls-the-function-without-me-even-asking-it-to) is fixed. – nnnnnn May 08 '17 at 02:55

1 Answers1

2

What actually happens in the line elem.addEventListener("keyup",alert(i)) is that the function-call alert(i) is executed and the return value of that function call is then added as an event listener. This obviously doesn't make sense, because 1. alert doesn't return anything and 2. you only want to execute it when the event happens.

What you actually seem to want to do is bind the function-call alert(i) itself to the event listener, not its return value.

You could assign the alert-function to the keyup event using elem.addEventListener("keyup",alert). But in that case you can't pass any arguments to it. If you want to do this, you can use Function.bind to create a new function from a function and a list of arguments.

elem.addEventListener("keyup", alert.bind(null, i))

If you need to support old browsers which do not support bind yet, this is an alternative syntax which generates an anonymous function as an event handler:

elem.addEventListener("keyup", function() {
    alert(i);
})

There is, however, another issue with your code. Every event handler will have the same value for i. Check the question mentioned by Sterling Archer's comment on the question for a solution.

Philipp
  • 67,764
  • 9
  • 118
  • 153
  • Oddly, the [W3C HMTL specification](http://w3c.github.io/html/webappapis.html#dom-window-alert) does not define a return value for *alert* (whereas it does for *confirm* and *prompt*) (nor does the [*WHATWG spec*](https://html.spec.whatwg.org/multipage/webappapis.html#dom-alert)). I expect it should be *undefined* since it's not defined. – RobG May 08 '17 at 02:46
  • elem.addEventListener("keyup", function() { alert(i); }) i tried this and this only alerts 1 time. thank you for your help. ill keep reading as much as i can – Holly Johnson May 08 '17 at 02:48
  • confirm and prompt need return values since they need to relay back the action the user took, ie, the value they gave to prompt or the choice they made with confirm, alert makes sense not to return a value since it just shows an alert and doesnt ask for user input, its essentially a void function, and in js void functions return undefined – chiliNUT May 08 '17 at 02:53
  • @HollyJohnson AFAIK the keyup-event only happens for the currently focused input element (or the `document` if no input is currently focused). If you want to do something for the other inputs, then your event handler must process the array of inputs. – Philipp May 08 '17 at 03:02
  • That is what i am trying to do. On keyup process all the inputs and then [for input in inputs call function someFunc(input)] – Holly Johnson May 08 '17 at 03:05
  • @chiliNUT— "*…alert makes sense not to return a value…*". No it doesn't. ECMAScript defines all functions as returning a value, so specifications for host object methods should do the same thing (IMHO of course). Adding "return undefined" as the last step in the algorithm isn't much to ask. :-) – RobG May 08 '17 at 03:31
  • I don't get why any function would unconditionally return undefined rather than not return anything at all since all functions without a return value implicitly return undefined? – chiliNUT May 08 '17 at 03:43