Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript event handling and flow control

I'm attempting to build a webpage that loads depending on the input provided. I'm having some trouble wrapping my head around event handling in javascript, basically. Coming from python, if I wanted to wait for a specific keyboard input before moving on to the next object to display, I would create a while loop and put a key listener inside it.

Python:

def getInput():
  while 1:
    for event in pygame.event.get(): #returns a list of events from the keyboard/mouse
      if event.type == KEYDOWN:
        if event.key == "enter": # for example
          do function()
          return
        elif event.key == "up":
          do function2()
          continue
        else: continue # for clarity

In trying to find a way to implement this in DOM/javascript, I seem to just crash the page (I assume due to the While Loop), but I presume this is because my event handling is poorly written. Also, registering event handlers with "element.onkeydown = function;" difficult for me to wrap my head around, and setInterval(foo(), interval] hasn't brought me much success.

Basically, I want a "listening" loop to do a certain behavior for key X, but to break when key Y is hit.

like image 941
intelligencer Avatar asked Aug 21 '09 15:08

intelligencer


People also ask

What is JavaScript event handling?

Event handlers can be used to handle and verify user input, user actions, and browser actions: Things that should be done every time a page loads. Things that should be done when the page is closed. Action that should be performed when a user clicks a button. Content that should be verified when a user inputs data.

What is Flow Control in JavaScript?

The control flow is the order in which the computer executes statements in a script. Code is run in order from the first line in the file to the last line, unless the computer runs across the (extremely frequent) structures that change the control flow, such as conditionals and loops.

What is an event flow JavaScript?

Event Flow : Event flow is the order in which event is received on the web page. If you click on an element like on div or on the button , which is nested to other elements, before the click is performed on the target element.


2 Answers

In JavaScript, you give up control of the main loop. The browser runs the main loop and calls back down into your code when an event or timeout/interval occurs. You have to handle the event and then return so that the browser can get on with doing other things, firing events, and so on.

So you cannot have a ‘listening’ loop. The browser does that for you, giving you the event and letting you deal with it, but once you've finished handling the event you must return. You can't fall back into a different loop. This means you can't write step-by-step procedural code; if you have state that persists between event calls you must store it, eg. in a variable.

This approach cannot work:

<input type="text" readonly="readonly" value="" id="status" />

var s= document.getElementById('status');
s.value= 'Press A now';
while (true) {
    var e= eventLoop.nextKeyEvent(); // THERE IS NO SUCH THING AS THIS
    if (e.which=='a')
        break
}
s.value= 'Press Y or N';
while (true) {
    var e= eventLoop.nextKeyEvent();
    if (e.which=='y') ...

Step-by-step code has to be turned inside out so that the browser calls down to you, instead of you calling up to the browser:

var state= 0;
function keypressed(event) {
    var key= String.fromCharCode(event? event.which : window.event.keyCode); // IE compatibility
    switch (state) {
        case 0:
            if (key=='a') {
                s.value= 'Press Y or N';
                state++;
            }
            break;
        case 1:
            if (key=='y') ...
            break;
    }
}

s.value= 'Press A now';
document.onkeypress= keypressed;

You can also make code look a little more linear and clean up some of the state stuff by using nested anonymous functions:

s.value= 'Press A now';
document.onkeypress= function(event) {
    var key= String.fromCharCode(event? event.which : window.event.keyCode);
    if (key=='a') {
        s.value= 'Press Y or N';
        document.onkeypress= function(event) {
            var key= String.fromCharCode(event? event.which : window.event.keyCode);
            if (key=='y') ...
        };
    }
};
like image 127
bobince Avatar answered Nov 14 '22 22:11

bobince


you should not use such loops in javascript. basically you do not want to block the browser from doing its job. Thus you work with events (onkeyup/down).

also instead of a loop you should use setTimeout if you want to wait a little and continue if something happened

you can do sth like that:

<html>
<script>
var dataToLoad = new Array('data1', 'data2', 'data3' );
var pos = 0;
function continueData(ev) {
  // do whatever checks you need about key
  var ele = document.getElementById("mydata");
  if (pos < dataToLoad.length)
  {
     ele.appendChild(document.createTextNode(dataToLoad[pos]));
     pos++;
  }
}
</script>
<body onkeyup="continueData()"><div id="mydata"></div></body></html>

everytime a key is released the next data field is appended

like image 31
Niko Avatar answered Nov 14 '22 21:11

Niko