How can I programmatically generate keypress events from Javascript code running in Safari? It looks like WebKit is using the DOM level 3 model for creating keyboard events from Javascript, and the DOM level 3 keyboard event model does not support the keypress event. Is there another way that I can use?
I'm looking for as pure a Safari/WebKit DOM solution as possible. I'd really prefer not to modify the web page, and I'd also rather not add dependencies on external libraries. I need to activate any existing keypress handlers, so it won't work to add a new handler and directly call it.
It looks like WebKit has the keyCode and charCode properties of the keypress event defined in its UIEvent class, but they are read-only. Is there any way to set those properties? The following does not work:
var evt = document.createEvent('UIEvents');
evt.initUIEvent('keypress', true, true, window, 0);
evt.keyCode = 114; // 'r'
evt.charCode = 114;
alert("keyCode = " + evt.keyCode + ", charCode = " + evt.charCode); // both 0
Setting the detail property in the call to initUIEvent also seems to have no effect.
How can I programmatically generate keypress events from Javascript code running in Safari? It looks like WebKit is using the DOM level 3 model for creating keyboard events from Javascript, and the DOM level 3 keyboard event model does not support the keypress event. Is there another way that I can use?
I'm looking for as pure a Safari/WebKit DOM solution as possible. I'd really prefer not to modify the web page, and I'd also rather not add dependencies on external libraries. I need to activate any existing keypress handlers, so it won't work to add a new handler and directly call it.
It looks like WebKit has the keyCode and charCode properties of the keypress event defined in its UIEvent class, but they are read-only. Is there any way to set those properties? The following does not work:
var evt = document.createEvent('UIEvents');
evt.initUIEvent('keypress', true, true, window, 0);
evt.keyCode = 114; // 'r'
evt.charCode = 114;
alert("keyCode = " + evt.keyCode + ", charCode = " + evt.charCode); // both 0
Setting the detail property in the call to initUIEvent also seems to have no effect.
Share Improve this question edited Dec 8, 2008 at 18:08 Greg asked Dec 5, 2008 at 22:58 GregGreg 10.8k6 gold badges48 silver badges68 bronze badges 2- 1 Did any of the solutions listed work for you? Asking for help then bailing is bad. If the answers aren't what you want, try to clarify. – TM. Commented Dec 12, 2008 at 2:17
- it doesn't work in safari, however it works fine in firefox. – Scy Commented Mar 26, 2013 at 2:25
4 Answers
Reset to default 8Use the TextEvent (introduced by DOM3). Since you're looking to generate keypress events, I'm guessing you're working with characters. In the code below, textToInsert is a string, and textarea the element I'm dispatching the event to.
var eventObject = document.createEvent('TextEvent');
eventObject.initTextEvent('textInput',
true,
true,
null,
textToInsert);
textarea.dispatchEvent(eventObject);
This works on Safari 3.1.2 (consequently on Chrome).
Sounds like a very similar (non browser specific) question was asked and answered already:
Trigger a keypress with jQuery...and specify which key was pressed
I have had the same problem. I wanted to be able to write a test that when the enter key is pressed on the GUI a line item (li) is added to a list. For then, I needed to "generate" a keypress. Having tried to generate the event, simulate an event, mock out the event (jqMock), here's a very simple solution.
I can continue on with BDDing my code using jsSpec and jQuery code. This test would be a little harder if you used a plugin to manage the keypresses (eg hotkeys jQuery plugin)
Here's what I want to do:
describe 'I need to be able to edit items in a list', {
... [setup code and other tests]
'should create a new item if I press enter': function(){
value_of($('#todo').items().size()).should_be(7)
// be on the last item in the list
task = $('#todo').items().filter(':last').focus()
// press enter
task.__keypress(13)
// check that an item was added
value_of($('#todo').tasks().size()).should_be(8)
},
}
Here's the code that binds the handler. Note with this solution I intercept the event and only pass through the which
code - this allows me to pass in the value from the test. That is all I need at the moment. Obviously, if I wanted to intercept more I would need to expand what is passed in (for example, see jquery.hotkeys plugin):
$().items().bind('keypress', function(event){$().__keypress(event.which)})
And here's the handler:
__keypress: function(which){
switch(which)
{
...
case 13: // enter
[my code that creates a new item]
break;
default:
}
},
ps: if anyone is able to mock window.event let me know. I didn't have any luck using jqMock.
http://docs.jquery./Events/keypress#fn
In other words, you attach a keypress event to some element. Using an element with the ID of "someid", for example:
<script language="text/javascript" src="jquery.js"></script>
<script language="text/javascript">
$(function() {
// add a keypress handler
$("#someid").keypress(function(e){
alert('you just pressed ' + e.which);
});
// imitate the keypress
$("#someid").keypress();
});
</script>