How to simulate a keypress in a Greasemonkey scrip

2019-08-03 15:39发布

I have found lots of info online about how to use the initEvent and dispatchEvent functions, but I can't for the life of me get them to work in practice.

I'm trying to get a script to press the Enter key every 5 seconds. My userscript code (minus irrelevant metadata) is below:

// ==UserScript==
// @namespace      http://userscripts.org/scripts/show/153134
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js
//
// @grant          unsafeWindow
//
// ==/UserScript==

$(function(){
window.setInterval(function(){
    var ev = document.createEvent("KeyboardEvent");
    ev.initKeyEvent("keypress", true, false, window, 0, 0, 0, 0, 13, 13);
        window.dispatchEvent(evt);
}, 5000);
});

Checkout my script on userscript to see how poorly it works (add a user include domain and test it on any <textarea>). Is Greasemonkey just not letting it through, or do I need to do something differently?

2条回答
叛逆
2楼-- · 2019-08-03 15:44

The only way I've been able to send keystrokes to the document and have them bubble properly is by creating an additional script insertion within the GM script. This example uses jQuery to simulate the keystroke event, it detects when the key "x" is pressed and sends "enter" to the document.

var script = document.createElement("script");
script.setAttribute("type", "application/javascript");

script.textContent = "(" + function(){
    $(document).keypress(function(e) {
        if(e.which == 120) {
            var p = jQuery.Event('keydown');
            p.which = 13;
            p.keyCode = 13;
            $('body').trigger(p);
        }
    });
} + ")()";

document.body.appendChild(script);
document.body.removeChild(script);

(edit: fixed equals/equivalency error)

查看更多
▲ chillily
3楼-- · 2019-08-03 15:45

There is a copy-paste error in that code.
Don't use window.dispatchEvent(evt);;
use window.dispatchEvent(ev);

Sending the event to window may not be what you need either. (Or it could be. Link to the target page.)

Maybe send the event to the document:

document.body.dispatchEvent(ev);

Or send it to a specific node:

var targetNode  = document.querySelector ("#content textarea"); // Etc.
targetNode.dispatchEvent (ev);


Or, since you are using jQuery:

var ev = $.Event('keypress');
ev.which = 13; // Carriage-return (Enter)
$('body').trigger(ev);
查看更多
登录 后发表回答