【问题标题】:Is there a way to simulate pressing multiple keys on mouse click with javascript?有没有办法用javascript模拟在鼠标点击时按下多个键?
【发布时间】:2015-01-05 03:12:48
【问题描述】:

我正在开发 chrome 扩展,以使 Netflix 视频播放器打开隐藏的质量变化面板。

Netflix 会根据您的互联网速度自动更改视频质量。

但是有一种已知的方法可以打开隐藏面板并手动更改质量。

这是在 HTML5 Player Only 中打开隐藏面板的方法 CTRL + SHIFT + ALT + S

有没有办法当用户点击标题时,
它模拟键盘键CTRL + SHIFT + ALT + S ?

$('body').on('click', 'div.player-status .player-status-main-title', function () {
    alert('Clicked!');
    //Simulate?
});

【问题讨论】:

  • 如果它是一个 HTML5 函数,这意味着它使用 javascript 运行。为什么不完全跳过按键步骤,只识别并触发打开面板的功能?
  • @DiMono 我试过了,但是我不是很擅长javascript,我没能识别出这个功能,如果你需要netflix账号自己试试我会给你账号

标签: javascript jquery html google-chrome google-chrome-extension


【解决方案1】:

试试这个(无法测试,因为我无法访问 Netflix 测试,确认从 11.11.14 开始工作)。

function simulateCtrlShiftAltS() {
  // Prepare function for injection into page
  function injected() {
    // Adjust as needed; some events are only processed at certain elements
    var element = document.body;

    function keyEvent(el, ev) {
      var eventObj = document.createEvent("Events");
      eventObj.initEvent(ev, true, true);

      // Edit this to fit
      eventObj.keyCode = 83;
      eventObj.which = 83;
      eventObj.ctrlKey = true;
      eventObj.shiftKey = true;
      eventObj.altKey = true;

      el.dispatchEvent(eventObj);
    }

    // Trigger all 3 just in case
    keyEvent(element, "keydown");
    keyEvent(element, "keypress");
    keyEvent(element, "keyup");
  }

  // Inject the script
  var script = document.createElement('script');
  script.textContent = "(" + injected.toString() + ")();";
  (document.head||document.documentElement).appendChild(script);
  script.parentNode.removeChild(script);
}

此代码改编自 cmets 到您链接的答案:https://stackoverflow.com/a/10520017/2518069

准确地说,来自这个例子:http://jsbin.com/awenaq/4

关于“按需调整”:

有些页面处理元素上的事件,有些页面会等到它冒泡到bodydocument 之类的东西。您可以通过转到 Dev Tools、Sources 并启用 Event Listener Breakpoints > Keyboard 来窥探这一点。从那里,您将能够看到哪个事件触发了您需要的更改,以及哪个元素捕获了它 - 当断点触发时,它将位于 this

另外,请注意,如果播放器实际上是一个插件,所有这些可能都不起作用。我在 YouTube HTML5 播放器上对此进行了测试:它适用于除全屏之外的所有内容(我认为这是一种安全限制?),并在元素 #movie_player 处处理。

【讨论】:

  • 谢谢,您的代码似乎触发了按键(我检查了控制台,我确定它正在工作)但是当我按下键盘上的按键时,Netflix 没有响应! ....如果您需要 Netflix 帐户来尝试自己,我会为您提供帐户,只需要一种私人方式将我的帐户发送给您
  • 我做到了,这就是我得到的jsfiddle.net/Jim_Toth/yn9804q5 见第 18531 行,我试图触发函数本身,但我得到控制台错误 Uncaught ReferenceError: m is not defined
  • 您不应该尝试触发该功能;您只需要知道哪个元素捕获了事件。在断点被触发时,这将是作用域变量中的this
  • 这个:body#page-WiPlayer.ua-chrome.ua-chrome-38.le-blink.os-win.os-win-81.ua-not-ie.sc-wn。 sc-strm.struts.global-header
  • 那是手动触发事件,实际显示界面?
【解决方案2】:

由于 Netflix 播放器代码无法使用 jQuery 设置事件侦听器,因此我建议使用原生 js-events 的解决方案。 Netflix 也可能需要一个比简单地在 1 毫秒内触发四个键事件更自然的事件计时(参见 SO - question)。

下面的函数创建四个本机keydown-KeyboardEvents,并按照您给定的顺序为键提供正确的属性。它们之间的延迟为 50 毫秒,以模拟更自然的行为。 我添加了一个紧随其后的带有“S”的keypress-event,因为某些设备会触发它。

在 Timeouts 中,一个 IIFE(立即调用的函数表达式)用于将事件作为参数传递给 Timeout-callback。

function simulateCtrlShiftAltS() {
    var keys = [
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0017', key: 'Control', keyCode: 17, which: 17, altKey: false, ctrlKey: true, shiftKey: false},
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0016', key: 'Shift', keyCode: 16, which: 16, altKey: false, ctrlKey: true, shiftKey: true},
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0018', key: 'Alt', keyCode: 18, which: 18, altKey: true, ctrlKey: true, shiftKey: true},
            {view: document.defaultView, bubbles: true, location: 0, keyLocation: 0, keyIdentifier: 'U+0053', key: 'S', keyCode: 83, which: 83, altKey: true, ctrlKey: true, shiftKey: true}
        ], body = document.body;
    for (var i = 0; i < 5; i++) {
        var events = [new KeyboardEvent(i == 4 ? 'keyup' : 'keydown', keys[i] || keys[3])];
        if (i == 3) events.push(new KeyboardEvent('keypress', keys[i]));
        if (events[0].keyCode == 0) events.forEach(function(ev) {
            ['keyCode', 'which'].forEach(function(p) {
                delete ev[p]; Object.defineProperty(ev, p, {value: (keys[i] || keys[3])[p], enumerable: true});
            });
        });
        window.setTimeout(function(evts) {
            return function() {evts.forEach(function(ev) {body.dispatchEvent(ev);});};
        }(events), i * 50);
    }
}

您可以简单地将函数传递给点击处理程序:

$('body').on('click', 'div.player-status .player-status-main-title', simulateCtrlShiftAltS);

编辑: 发现 webkit 浏览器没有正确设置 keyCode- 和 which- 属性。我不推荐使用.initKeyboardEvent(),因为它已被弃用,并且浏览器处理它的方式非常不同。所以我添加了一个方法来重新定义事件对象中的这些属性。它是 灵感来自termi's answer on this SO-question。我也从T切换到S

现在this FIDDLE works 适用于 FF、Chrome 和 Opera,但不适用于 IE 和 Safari(没有实现 KeyboardEvent API)。我会尝试为他们找到并实施一个简单的解决方案。

编辑 2: 由于它仍然无法正常工作,我们在“S”上添加了一个按键事件。查看更改后的代码。如果这还不够,我们将在放弃之前逐步释放 ALT、SHIFT 和 CTRL。

【讨论】:

  • 可能需要注入这个into the page content
  • 我在 Netflix 上进行了测试,但它不起作用...我认为通过 T 存在问题 请参阅jsfiddle.net/Jim_Toth/0wuj6s2j/1,当我移除 T 键时,检查器工作格 jsfiddle.net/Jim_Toth/0wuj6s2j
  • @Jim T-keyCode 是 84 不是 16(你的警报)。 It's working in FF。但是 Webkits 在初始化 KeyboardEvent 时总是将keyCode 设置为0。不知道为什么,我会寻找解决方案。
  • 顺便说一句,密钥不是 (T) 它是 (S),对此感到抱歉...并且请从 $('body').on('click', 'div. player-status .player-status-main-title',.....
  • @MartinErnst 我测试了新编辑,但不幸的是我遇到了与 Xan 的代码相同的问题,Netflix 没有像我按下键盘上的键一样响应触发器:(跨度>
猜你喜欢
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 2021-09-07
  • 2014-02-13
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 2021-03-07
相关资源
最近更新 更多