【问题标题】:JavaScript 'keyup' and 'keydown' event listeners only trigger onceJavaScript 'keyup' 和 'keydown' 事件监听器只触发一次
【发布时间】:2019-06-19 21:26:05
【问题描述】:

我是一名 JavaScript 程序员新手——这是我使用该语言的第一个项目。我目前正在尝试运行一个临时“计时器”,该计时器在按下键时触发(keydown)并在释放键时结束(keyup)。出于测试目的,我还让每个函数在触发时打印一条语句。不幸的是,我只能让事件监听器触发一次。我希望脚本在用户按下任何键时运行并响应输入。老实说,“计时器”是一个更大项目的占位符——让 keydown/keyup 事件在用户每次按下键时运行是重要的,而不仅仅是在初始按下时。

我已经尝试了很多不同的策略,我会在等待回复的同时继续研究这个问题。起初,我怀疑这个问题是因为我在加载之前将 JavaScript 设置在 html 文档的 head 部分,但是将其移动到 body 并没有解决问题。我担心这是因为我不是每次都写一个新行,但是更改为 document.writeln 并没有帮助。我尝试了几种简单的循环代码形式,但没有成功——我目前正在研究如何使函数递归,看看是否有帮助。我还尝试将代码加载到 jquery 中,但无济于事(JQuery 甚至不会触发一次)。根据我对键盘记录所做的研究,我还对 window.setInterval 之类的东西做了一些工作,但我并不完全理解它的作用,也没有成功。

// The initial script
<!DOCTYPE html>
<html>

  <head>
    <script type="text/javascript">
    var start, finish, diff;

    // Adds event listeners
    document.addEventListener('keydown',startTimer);
    document.addEventListener('keyup',endTimer);

    // Runs on keydown, simply stores a new date
    function startTimer(e){
        start = new Date();
    }

    // Runs on keyup, stores a new date (time in milliseconds since 
epoch),
    // then takes and prints the difference between the two. 
    function endTimer(e){
        finish = new Date();
        diff = finish - start;
        document.write(diff);
    }

    </script>
  </head>

  <body>
  </body>
</html>

// "Most stable" version, utilizing onkeyup/onkeydown and writeln
<!DOCTYPE html>
<html>

  <head>

  </head>

  <body>
    <script type="text/javascript">
    var start, finish, diff;

      document.onkeydown = function(e){
          start = new Date();
          document.writeln(start);
      }

      document.onkeyup = function(e){
          finish = new Date();
          diff = finish - start;
          document.writeln(finish);
          document.writeln(diff);
      }
    </script>
  </body>
</html>

// JQuery version
<!DOCTYPE html>
<html>

  <head>

  </head>

  <body>
    <script src="jquery-3.4.1.min.js">
    var start, finish, diff;

    $("q").keydown(function(){
      start = new Date();
      document.writeln(start);
    });

    $("w").keyup(function(){
      finish = new Date();
      diff = finish - start;
      document.writeln(finish);
      document.writeln(diff);
    });

    </script>
  </body>
</html>

我希望“网站”在我每次按下一个键时打印出精确的存储日期,然后在我释放它时打印出一个新日期以及两者之间的差异。相反,当我第一次按下一个键时,它会打印出信息,然后无论我做什么都不打印。

我会注意到 JQuery 一个目前甚至没有打印出第一条消息 - 我正在做更多的研究为什么 - 我只做了非常精简的 JQuery 研究。

感谢您的帮助。

【问题讨论】:

  • 不要使用 document.writedocument.writeln - 使用 console.log - 它可能会起作用
  • jquery 代码不起作用,因为您不知道 jquery ...$('q').keydown 没有为 q 键添加事件侦听器 - 它为元素添加了 keydown 事件侦听器其标签名称为 q ... 即 HTML 中没有任何内容
  • @JaromandaX 感谢您的反馈,我知道它指的是元素名称,但我不确定如何为用户按下的任何键分配名称 - 我想我会做一些阅读。至于你的第一句话:我完全同意。正如我所说,这是我第一次使用 JavaScript,因为我一无所知,所以我完全知道 0 JQuery。
  • document.write 与 jQuery 完全无关 - 所以我的第一个声明也与 jQuery 无关:D
  • @JaromandaX 我的意思是声明:“jquery 代码不起作用,因为你不知道 jquery”对不起,我没有说清楚,这就是为什么我说我完全同意并且有没有使用 JQuery 的经验。在下载 JQuery 之前,我至少知道自己在使用 document.write

标签: javascript jquery addeventlistener onkeydown onkeyup


【解决方案1】:

我想你想要这样的东西。

// The initial script
<!DOCTYPE html>
<html>

 <head>
   <script type="text/javascript">
    var start, finish, diff;

// Adds event listeners
document.addEventListener('keydown',startTimer);
document.addEventListener('keyup',endTimer);

// Runs on keydown, simply stores a new date
function startTimer(e){
    console.log('down', e)
            start = new Date();
        }

        // Runs on keyup, stores a new date (time in milliseconds since 
//  epoch),
        // then takes and prints the difference between the two. 
        function endTimer(e){
      console.log('up', e)
           finish = new Date();
            diff = finish - start;
          console.log('diff', diff)
            document.querySelector('body').innerHTML = (diff);
        } 

   </script>
  </head>

 <body>
 </body>
</html>

问题是当你告诉endTimer 写下过去的时间量时:

document.write(diff)

您正在写入文档的根目录,而不是文档中的元素。一旦被覆盖,您就没有 DOM 对象可以从中获取事件。

【讨论】:

  • 嗯,感谢您的反馈!我将很快进行测试并编辑我的回复——我没有意识到 document.write 是这样做的——我想我想它就像 C++ cout 或 Java 的 System.out.println。我是 Web 开发的新手
  • 您应该使用performance.now() 而不是new Date()。此外,当按住键时,您的开始日期将不断重置,除非您将某些状态变量设置为false,然后仅在keyup 时重置为true
  • @GrantNoe 很好,我没有想到这一点——这可能解释了我因为差异而得到的奇怪数字。具有讽刺意味的是,我试图简化测试过程,以便可以处理您刚刚发现的错误。 ...现在我想它应该告诉我问题出在 document.write 上,因为当我没有多个时它起作用了。韦尔普,我想事后看来是 20/20。
【解决方案2】:

正如@JaromandaX 所评论的,问题在于在事件处理程序中使用document.writeln()。改用console.log() 可以解决此问题。

解释:在页面加载后使用document.write() 会清除当前文档,并用传递的任何字符串替换内容。 Credits

var start, finish, diff;

      document.onkeydown = function(e){
          start = new Date();
          console.log(start);
      }

      document.onkeyup = function(e){
          finish = new Date();
          diff = finish - start;
          console.log(finish);
          console.log(diff);
      }
<!--"Most stable" version, utilizing onkeyup/onkeydown and writeln-->
<!DOCTYPE html>
<html>

  <head>

  </head>

  <body>
  </body>
</html>

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 2017-01-08
    • 1970-01-01
    相关资源
    最近更新 更多