Just wondering. Is it possible to invoke a key press event in JavaScript without ACTUALLY pressing the key ? For example lets say, I have a button on my webpage and when that button is clicked I want to invoke a event as if a particular key has been pressed. I know it weird but can this be done in JavaScript.
Yes, this can be done using initKeyEvent. It's a little verbose to use, though. If that bothers you, use jQuery, as shown in #WojtekT's answer.
Otherwise, in vanilla javascript, this is how it works:
// Create the event
var evt = document.createEvent( 'KeyboardEvent' );
// Init the options
evt.initKeyEvent(
"keypress", // the kind of event
true, // boolean "can it bubble?"
true, // boolean "can it be cancelled?"
null, // specifies the view context (usually window or null)
false, // boolean "Ctrl key?"
false, // boolean "Alt key?"
false, // Boolean "Shift key?"
false, // Boolean "Meta key?"
9, // the keyCode
0); // the charCode
// Dispatch the event on the element
el.dispatchEvent( evt );
If you're using jquery:
var e = jQuery.Event("keydown");
e.which = 50; //key code
$("#some_element").trigger(e);
Related
How does a website recognize keystrokes, mouse movement?
Is there a way to send a command ("like pressing down your left mouse button) via JavaScript, without actually pressing down your mouse button?
If my question is too unclear, I'm very happy to explain further. I'm new and just trying to start somewhere but am lost.
Can you recommend me some good learning material, so I can read into it, thank you very much.
Mouse, Keyboard, and other Events
Sites recognize keyboard and mouse 'events' by subscribing a function to them.
You can do that thru html like so: onkeypress="keypressFunction()", onmousemove="mousemoveFunction()", onclick="clickFunction()"... and other events
<div onclick="clickFunction()">Clickable</div>
Of course these functions keypressFunction(), mousemoveFunction(), clickFunction() need to exist somewhere in your site, whether inside
<script>
function clickFunction(){ alert('clicked!') }
</script>
or included from file: <script src="myscripts.js"></script> .
You can also subscribe to events using just javascript:
//Write `document` instead of `element` to apply to whole document
//Or you can find element by id like document.getElementById('id')
//You can of course use any other method of finding elements such
// as querySelector or use variables you already made before
element.onkeypress = function(eventArgs){
eventArgs = eventArgs || window.event;
// use eventArgs.keyCode to get which key
};
Or, more common and safe, subscribe with addEventListener:
element.addEventListener('keypress', function(eventArgs){
eventArgs = eventArgs || window.event;
// use eventArgs.keyCode to get which key
});
Note you dont have to write the prefix on in the event names (eg onkeypress) if using addEventListener.
You can of course also use already made functions:
element.onkeypress = myFunction;
and
element.addEventListener('keypress', myFunction);
All of these events usually pass an event-specific parameter to give more data about what exactly happened in the event.
For example, onclick passes MouseEvent args, so you can know where the mouse was (X and Y coords on screen) when the thing was clicked, were the alt/shift/ctrl keys held, and which mouse button was clicked (left, right, middle).
Keyboard events have their own event args with info on which keyboard key was pressed, if its being held, and so on. You can find all event arguments here.
Simulating events
Some basic events, such as a mouse click on an element, can be simulated with just element.click();, but that doesnt give you much control over the event args that are getting passed.
To properly send an event, you need to create a browser event object, and dispatch it on an element:
//Call oncontextmenu (right mouse click) on an element:
var element = document.getElementById('Id_here');
if (window.CustomEvent) {
element.dispatchEvent(new CustomEvent('contextmenu'));
} else if (document.createEvent) {
var ev = document.createEvent('HTMLEvents');
ev.initEvent('contextmenu', true, false);
element.dispatchEvent(ev);
} else { // Internet Explorer
element.fireEvent('oncontextmenu');
}
With that event object you can pass some data, here is simulating a keypress:
var element = document.getElementById('Id_here');
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
65, // keyCode: unsigned long - the virtual key code, else 0. 65 - 'a'
0 // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
element.dispatchEvent(keyboardEvent);
Jquery gives some nice functions to make simulating events easier, but you can find those all over stack overflow, not even to mention google. Just search js simulating keypress/mouse, js subsribe to key/mouse event, and all the other things you can imagine.
I have an accepted answer but am open to better ones
Be gentle, this is my first question here
I am building a web browser plugin to automate a series of processes for my organization. I pretty much have everything handled but this one problem that I have been stuck on for two days... and its like really simple I think.
In a lookup field in our ERP, you must press Shift + Right to cycle through certain options.
I am attempting to trigger this or send this any kind of way that I can.
Jquery version 2.0.3
The required event only fires on key up
The required event is not firing when I simulate input
I suspect it needs to be targeted at the input, or perhaps its related to not being trusted/being simulated
It occurs to me, that as I am using a browser extension, perhaps it is something I can simulate from this? I dont know if thats a good way to put it... I wonder what the extension could do here that plain JS or JQ on a page could not.
Update(Dec 11): So per above thought, I am looking into modifying the Jquery framework that is being used. I have saved a local copy as an local override and used these two resources to implement.
Override Javascript file in chrome
https://www.ghacks.net/2018/02/27/make-permanent-changes-to-web-pages-with-chromes-overrides-dev-tool/
I am in process of determining if local overrides are persistent (Edit: they appear to be after restart of computer, lets see if its a long term solution) but I was able to console.log my code and see it in the console.
Next steps will be modifying the handler to perform the actions I need. and/or feed the information I want fed to the system.
Update(Dec 12): probably dont need to override the whole file with this answer how to override a javascript function
Here is my function that triggers the event handler (with no result) which was modified from here
function simulateKey (currentTarget, isTrusted, key, code, keyCode, type, modifiers) {
var evtName = (typeof(type) === "string") ? "key" + type : "keydown";
var modifier = (typeof(modifiers) === "object") ? modifier : {};
console.log("In simulate key function");
var event = document.createEvent("HTMLEvents");
event.initEvent(evtName, true, false);
event.keyCode = keyCode;
event.key = key;
event.code = code;
event.isTrusted = isTrusted;
event.Target = currentTarget;
for (var i in modifiers) {
event[i] = modifiers[i];
}
document.dispatchEvent(event);
}
Here is how I use it (a little hardcoded at the moment, just for testing purposes)
function changeLookup(Lookup) {
console.log("Change Lookup");
var event_object = Lookup;
console.log("Key Event Firing");
$("input[data-name='Entity.Customer.Key']").focus();
simulateKey(Lookup, true, "ArrowRight", "ArrowRight", 39, "up", {shiftKey: true });
console.log("Key Event Fired");
}
I have looked at or tried the following solutions
Trigger a built in event in javascript?
Arrow key pressed while shift key is held down
Is it possible to simulate key press events programmatically?
How to trigger event in JavaScript?
Execute Key Press Event
Firing a Keyboard Event in Safari, using JavaScript
I have reviewed the following documentation
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
https://developer.mozilla.org/en-US/docs/Web/API/Event
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
I am at my wits end here...
The answer was found here Keydown Simulation in Chrome fires normally but not the correct key
I modified it to keyup and juggled some of the parameters so the shift key was pressed... Seems like OP in the other thread did some strange stuff with the parameters in such a way as to press ctrl and shift... So I fixed that for the initKeyboardEvent but not for initKeyEvent
keyUpEventSim = {};
keyUpEventSim.keyup = function(target, k, ctrlKey, altKey, shiftKey, metaKey) {
var oEvent = document.createEvent('KeyboardEvent');
// Chromium Hack
Object.defineProperty(oEvent, 'keyCode', {
get : function() {
return this.keyCodeVal;
}
});
Object.defineProperty(oEvent, 'which', {
get : function() {
return this.keyCodeVal;
}
});
if (oEvent.initKeyboardEvent) {
oEvent.initKeyboardEvent("keyup", true, false, document.defaultView, false, false, ctrlKey, altKey, shiftKey, metaKey);
} else {
oEvent.initKeyEvent("keyup", true, false, document.defaultView, false, false, true, false, k, 0);
}
oEvent.keyCodeVal = k;
if (oEvent.keyCode !== k) {
alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")");
}
target.dispatchEvent(oEvent);
}
called it as follows
function changeLookup(Lookup) {
Lookup.focus();
keyUpEventSim.keyup(Lookup,39, false, false, true, false);
}
I am trying window.parent.document.dispatchEvent(keyboardEvent).
I am doing this to catch keyboardevent's keycode value and will perform some operation based on which key is pressed. Without this keycode is coming as 0 even when i am running in browser.
My code goes something like
window.setTimeout(function () {
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
false, // altKeyArg
false, // shiftKeyArg
false, // metaKeyArg
666, // keyCodeArg : unsigned long the virtual key code, else 0
null // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
delete keyboardEvent.keyCode;
Object.defineProperty(keyboardEvent, "keyCode", {"value" : 666});
window.parent.document.dispatchEvent(keyboardEvent);
}, 10000);
i am giving value 666 just to test.
This works fine when i run it in chrome.
but this line of code Object.defineProperty(keyboardEvent, "keyCode", {"value" : 666});
thorws "TypeError: Attempting to change value of a readonly property. defineProperty." when i run code in set top box.
this is plnkr link for above code http://plnkr.co/edit/my8HkFpRqZRDrFYgIxXL?p=preview
How can I capture correct keycode in set top box so I can automate key press event?
Can any extra line be added/modified to above code that will give correct key code on set top box?
I am answering my own question as I found this link which is solving this problem.
Set top box is using webkit to run JavaScript code and when keyboardEvent is registered and dispatchEvent is called over that for any key press, webkit gives keyCode as 0 for any keyboardEvent.
To overcome this problem, instead of using keyboardEvent use generic event to programmatically triggering events.
Code can be seen in this link. Here function __triggerKeyboardEvent is using generic event to programmatically trigger event.
It works perfectly in set top box.
I'll start with some context: I wrote a little typing app that displays text on the screen and tracks your wpm as you type using the keypress event. Out of boredom I wanted to play around with it a little bit and have a way that it would auto type after typing a hidden command (shortend kontra code using just the arrow keys). So I have a array of characters that I am iterating through and attempting to simulate the keypress event in my each loop as shown below.
$.each(_arrToCopy, function (index, value) {
setTimeout(function () {
console.log(value);
jQuery.event.trigger({ type: 'keypress', which: value.charCodeAt(0) });
//typeIt(value);
}, time);
time += 500;
});
The issue I'm having is it appears that my event is only triggering one time and then not triggering again. The setTimeout function was an early attempt to slow the loop down in case I was just processing things too quickly. After that didn't work I implemented a nearly pure javascript function (the typeIt()) function to fake the keyboard event. It is below.
function typeIt(character) {
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
console.log(String.fromCharCode(character.charCodeAt(0)) + ' ' + (character.charCodeAt(0)));
keyboardEvent[initMethod](
"keypress", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
false, // altKeyArg
false, // shiftKeyArg
false, // metaKeyArg
0, // keyCodeArg
character.charCodeAt(0) // charCodeArgs
);
document.dispatchEvent(keyboardEvent);
}
This also typed once, but it appears to be typing the wrong character. So I circled back to trying to make the jQuery trigger work and have gotten stuck on that. I can get it to type the first letter, but after that it appears to completely stop firing. I was wondering if there's potentially a way to reset the event trigger if it's only able to fire once in the loop without being reset, or if that's even the issue here.
If for the sake of more context you want to take a look at what this is going in, I have a mock up here (although what I'm actually working on is now a bit more refined c# app will a full backend): http://codepen.io/jiggawagga/pen/wBoaRY
Thanks in advance team stackoverflow
I had this issue in simple jQuery click event. I did below and it worked fine. See if it solves your issue
jQuery(document).off().on('click', '.my-div', function(){
// SOME EVENT GOES HERE
})
Refer http://api.jquery.com/off/
I copied your code into a jsfiddle to try it out. The only thing I had to change to get it to work was changing this:
jQuery.event.trigger({ type: 'keypress', which: value.charCodeAt(0) });
to this:
$('#out').trigger({ type: 'keypress', which: value.charCodeAt(0)});
Basically triggering the event on the element that is to receive it. I'm not very well versed in jQuery so this might not be the solution you're after. But it worked for me.
The full js for the fiddle:
var _arrToCopy = Array.prototype.slice.call("lorem ipsum");
var time = 0;
$('#out').keypress(function(e){
$(this).text($(this).text() + String.fromCharCode(e.which));
});
$.each(_arrToCopy, function (index, value) {
setTimeout(function () {
console.log(value);
$('#out').trigger({ type: 'keypress', which: value.charCodeAt(0)});
}, time);
time += 500;
});
And the HTML:
<p id="out">
I am writing some UI tests using Selenium and i have a JavaScript Tree control, using the Dojo toolkit.
I have implemented a context menu for each node of the tree using the examples that Dojo provide, but I need the Selenium test to "invoke" the right click on the tree node, but I cannot get this to work. The tests simply do not simulate the right-click event through JavaScript, and the context menu does not show up.
Has anyone had any experience in invoking the right click on a context menu using Dojo and Selenium? Or have any ideas as to how to do it?
try this instead, reason what things didn't quite work is that the context menu is in fact bound to the oncontextmenu event.
function contextMenuClick(element){
var evt = element.ownerDocument.createEvent('MouseEvents');
var RIGHT_CLICK_BUTTON_CODE = 2; // the same for FF and IE
evt.initMouseEvent('contextmenu', true, true,
element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
false, false, false, RIGHT_CLICK_BUTTON_CODE, null);
if (document.createEventObject){
// dispatch for IE
return element.fireEvent('onclick', evt)
}
else{
// dispatch for firefox + others
return !element.dispatchEvent(evt);
}
}
Just for good measure, here is a bit of doco on the parameters:
var myEvt = document.createEvent('MouseEvents');
myEvt.initMouseEvent(
'click' // event type
,true // can bubble?
,true // cancelable?
,window // the event's abstract view (should always be window)
,1 // mouse click count (or event "detail")
,100 // event's screen x coordinate
,200 // event's screen y coordinate
,100 // event's client x coordinate
,200 // event's client y coordinate
,false // whether or not CTRL was pressed during event
,false // whether or not ALT was pressed during event
,false // whether or not SHIFT was pressed during event
,false // whether or not the meta key was pressed during event
,1 // indicates which button (if any) caused the mouse event (1 = primary button)
,null // relatedTarget (only applicable for mouseover/mouseout events)
);
Great question!
I did some research, and it seems like you can fire a mouse event like is shown here, and make it a right-click by setting the button or which property to 2 (documented here).
Perhaps this code will work:
function rightClick(element){
var evt = element.ownerDocument.createEvent('MouseEvents');
var RIGHT_CLICK_BUTTON_CODE = 2; // the same for FF and IE
evt.initMouseEvent('click', true, true,
element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
false, false, false, RIGHT_CLICK_BUTTON_CODE, null);
if (document.createEventObject){
// dispatch for IE
return element.fireEvent('onclick', evt)
}
else{
// dispatch for firefox + others
return !element.dispatchEvent(evt);
}
}
Here is a more correct version if you do not care about where the context menu gets fired up
function fireContextMenu(el) {
var evt = el.ownerDocument.createEvent("HTMLEvents")
evt.initEvent('contextmenu', true, true) // bubbles = true, cancelable = true
if (document.createEventObject) {
return el.fireEvent('oncontextmenu', evt)
}
else {
return !el.dispatchEvent(evt)
}
}
If you do, we may have to use the previous one, fix up it's behaviour in IE, and populate the screenX, screenY, clientX, clientY etc appropriately
I am trying this in firefox and chrome, but dispatching the contextmenu event doesn't make browser to open context menu. Event is triggered because my callback for oncontextmenu is fired, but context menu is still missing. Anybody have an idea, because I used all code samples from above?