【问题标题】:chrome extension: how to send 'keydown' event to page's input?chrome 扩展:如何将“keydown”事件发送到页面的输入?
【发布时间】:2013-06-17 17:02:17
【问题描述】:

我有一个测试网页,如果我在它的输入字段中按下一个键,就会发出警报:

<!doctype html>
<html>
<head>
  <script type="text/javascript" src="jquery-1.9.1.min.js"></script>
  <script>
    $( document ).ready( function() {
      $( '#foo' ).keydown( function() { alert( "debug" ); } );
    });
  </script>
</head>
<body>
  <input id='foo' type='type'/>
</body>
</html>

我有这个 chrome 扩展,它可以修改输入文本并触发 keydown 事件:

$( document ).ready( function() {
  window.setTimeout( function() {
    $( '#foo' ).val( "foo" );
    $( '#foo' ).keydown();
  }, 2000 );
});

如果我安装扩展,2 秒后(如预期)文本被修改 - 但不显示警报,所以我可以建议 keydown 事件不从扩展沙箱传递到页面 javascript 处理程序。是否可以以某种方式修改我的代码,以便扩展程序可以模拟页面上的 javascript 可以看到的 keydown?我正在通过 chrome 扩展程序自动化第三方网站,其中一个输入需要keyup 来检测值变化(我正在自动化的页面写得很糟糕 - 但我没有任何控制权,除了它的源代码) .

【问题讨论】:

    标签: google-chrome-extension


    【解决方案1】:

    您的代码不起作用,因为 jQuery 的 keydown() 方法实际上并没有触发“真正的”keydown 事件。相反,jQuery 在jQuery.cache 中查找“绑定”事件处理程序,并调用相应的函数。

    由于您的内容脚本的 jQuery 对象与页面的 jQuery 对象不同,因此调用 .keydown() 不会导致任何操作。

    在您的情况下,我建议在页面中inject your code,以便您的代码在与页面相同的上下文中运行。然后,调用 $('#foo').keydown() 将使用页面的 jQuery 对象,并产生预期的行为。

    不依赖任何库的通用解决方案是使用KeyboardEvent 构造函数(defined in DOM4)来触发事件:

    var event = new KeyboardEvent('keydown');
    document.querySelector('#foo').dispatchEvent(event);
    

    【讨论】:

    • 非常感谢。我对网络技术几乎没有经验,jQuery 机制的这一方面对我来说是未知的。
    • 我认为我在使用 jQuery 和 Karma 的 Jasmine 单元测试中面临同样的限制(jQuery 的不同上下文)。触发KeyboardEvent 可以解决问题,但我不知道如何通过单元测试使 jQuery 在与浏览器相同的上下文中运行...
    • @mediafreakch 请参阅我的答案中的“注入您的代码”链接。
    • @RobW 谢谢,但最后发现我的问题与我两次包含 jQuery 的事实有关(karma.conf.js + require() 在单元测试本身中)
    猜你喜欢
    • 2016-11-29
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    相关资源
    最近更新 更多