Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript事件处理和流控制_Javascript_Loops_Events_Event Handling - Fatal编程技术网

Javascript事件处理和流控制

Javascript事件处理和流控制,javascript,loops,events,event-handling,Javascript,Loops,Events,Event Handling,我正试图建立一个网页,根据提供的输入加载。基本上,我在javascript事件处理方面遇到了一些麻烦。来自python,如果我想在转到下一个要显示的对象之前等待特定的键盘输入,我将创建一个while循环,并在其中放置一个键侦听器 Python: def getInput(): while 1: for event in pygame.event.get(): #returns a list of events from the keyboard/mouse if even

我正试图建立一个网页,根据提供的输入加载。基本上,我在javascript事件处理方面遇到了一些麻烦。来自python,如果我想在转到下一个要显示的对象之前等待特定的键盘输入,我将创建一个while循环,并在其中放置一个键侦听器

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
在试图找到在DOM/javascript中实现这一点的方法时,我似乎只是使页面崩溃(我假设是由于While循环),但我认为这是因为我的事件处理编写得很糟糕。另外,用“element.onkeydown=function;”注册事件处理程序对我来说很难理解,而setInterval(foo(),interval)并没有给我带来多少成功


基本上,我需要一个“监听”循环来执行键X的特定行为,但在按下键Y时会中断。

您不应该在javascript中使用此类循环。基本上,您不希望阻止浏览器执行其工作。因此,您需要处理事件(onkeyup/down)

此外,如果您想稍等片刻,并在出现问题时继续,则应该使用setTimeout,而不是循环

你可以这样做:

<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>

var dataToLoad=新数组('data1','data2','data3');
var-pos=0;
功能连续数据(ev){
//做任何你需要的关于钥匙的检查
var ele=document.getElementById(“mydata”);
if(位置<数据加载长度)
{
元素appendChild(document.createTextNode(dataToLoad[pos]);
pos++;
}
}

每次释放密钥时,都会添加下一个数据字段

任何好的浏览器在遇到运行时间过长的脚本时都会崩溃。这是为了防止恶意网站锁定客户端应用程序

javascript中不能有无限循环。相反,将事件侦听器附加到窗口,并在处理程序中指向执行处理(将其视为中断而不是轮询)

例如:

function addEventSimple(obj,evt,fn) {
    if (obj.addEventListener)
        obj.addEventListener(evt,fn,false);
    else if (obj.attachEvent)
        obj.attachEvent('on'+evt,fn);
} // method pulled from quirksmode.org for cross-browser compatibility

addEventSimple(window, "keydown", function(e) {
    // check keys
});

这就是javascript的全部功能。您不需要循环等待事件发生,只要事件发生,就会调用该函数,而该函数又可以调用其他函数,执行任何需要执行的操作。可以这样认为,您不必等待您要查找的事件发生,您要查找的事件就会发生当事件发生时通知您。

您可以像这样将事件侦听器附加到窗口对象

window.captureEvents(Event.KEYPRESS);
window.onkeypress = output;
function output(event) {
  alert("you pressed" + event.which);
}

查看YUI密钥侦听器

使用键侦听器,YUI负责捕获任何事件。在javascript中,几乎没有一个实例必须在while循环中等待事件发生

如果您需要事件处理工作原理的示例,请查看以下页面


在JavaScript中,您放弃对主循环的控制。浏览器运行主循环,并在发生事件或超时/间隔时向下调用代码。您必须处理事件,然后返回,以便浏览器可以继续执行其他操作、触发事件等

因此,您不能有一个“侦听”循环。浏览器会为您这样做,为您提供事件并让您处理它,但一旦您处理完事件,您必须返回。您不能返回到另一个循环中。这意味着您不能编写一步一步的过程代码;如果在事件调用之间存在状态,则必须返回将其存储在变量中

这种方法不可能奏效:

<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') ...
您还可以使用嵌套匿名函数使代码看起来更线性,并清理一些状态信息:

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') ...
        };
    }
};

为了更容易地实现事件处理,我建议您使用诸如或(注意,这两个链接都会将您带到各自的事件处理文档)之类的库

为了使用它们,你必须记住三件事:

  • 您希望观察哪个DOM元素
  • 您想要捕获什么事件
  • 事件将触发什么操作
这三点是相互包容的,这意味着您在编写代码时需要注意这三点

考虑到这一点,使用Prototype,您可以这样做:

Event.observe($('id_of_the_element_to_observe'), 'keypress', function(ev) {
  // the argument ev is the event object that has some useful information such
  // as which keycode was pressed.
  code_to_run;
});
下面是一个更有用的示例的代码,一个CharacterCounter(比如在Twitter上找到的,但肯定不太可靠;):

var CharacterCounter=Class.create({
初始化:函数(输入、计数器、最大字符数){
这个输入=输入;
this.counter=计数器;
this.max_chars=max_chars;
观察(this.input'keypress',this.keyPressHandler.bind(this));
Event.observe(this.input'keyup',this.keyUpHandler.bind(this));
},
keyUpHandler:function(){
words\u left=this.max\u chars-$F(this.input).length;
this.counter.innerHTML=words\u left;
},
按键处理程序:功能(e){
words\u left=this.max\u chars-$F(this.input).length;

如果(如果您需要在处理程序中使用event对象,那么,
ev
实际上应该是一个
事件,因为它是传递给函数的名称。当然,就是“特殊的”并将事件对象分配给全局
窗口。event
而不是将其传递给
event
下的event handler函数。true-显然,您需要调整代码以作用于不同的按键/释放。我试图演示如何解决while循环issueThanks bobince。您对什么是分步过程code很好地解决了我的问题。希望我有足够的代表投票给你。
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') ...
        };
    }
};
Event.observe($('id_of_the_element_to_observe'), 'keypress', function(ev) {
  // the argument ev is the event object that has some useful information such
  // as which keycode was pressed.
  code_to_run;
});
var CharacterCounter = Class.create({

  initialize: function(input, counter, max_chars) {
    this.input = input;
    this.counter = counter;
    this.max_chars = max_chars;
    Event.observe(this.input, 'keypress', this.keyPressHandler.bind(this));
    Event.observe(this.input, 'keyup', this.keyUpHandler.bind(this));
  },

  keyUpHandler: function() {
    words_left = this.max_chars - $F(this.input).length;
    this.counter.innerHTML = words_left;
  },

  keyPressHandler: function(e) {
    words_left = this.max_chars - $F(this.input).length;
    if (words_left <= 0 && this.allowedChars(e.keyCode)) {
      e.stop();
    }
  },

  allowedChars: function(keycode) {
    // 8: backspace, 37-40: arrow keys, 46: delete
    allowed_keycodes = [ 8, 37, 38, 39, 40, 46 ];
    if (allowed_keycodes.include(keycode)) {
      return false;
    }
    return true
  }

});