javascript - poner - Disparar un evento de teclado en Chrome
monitorevents (5)
Estoy intentando disparar un evento de teclado a una página usando javascript en Chrome. Tenía un enfoque que solía funcionar en Firefox:
pressKey = function(key, shift) {
var evt = document.createEvent(''KeyboardEvent'');
evt.initKeyEvent("keypress", false, true, null, false, false,
shift, false, keyCode(key), key.charCodeAt(0));
document.dispatchEvent(evt);
}
donde key es la clave deseada y keyCode cambia letras minúsculas a mayúsculas y también llama a charCodeAt ().
Mi problema es que los eventos en Safari / Chrome no tienen initKeyEvent, sino initKeyboardEvent. La principal diferencia que pude notar fue que debe pasar la clave como keyIdentifier (que se parece a un carácter Unicode) en lugar de pasar el código clave y el keychar. Sin embargo, todavía no puedo lograr que funcione.
También probé el enfoque JQuery descrito here sin éxito.
EDITAR: Depuré esto un poco más y parece que el evento en Chrome activa los oyentes, pero keyCode / charCode siempre es 0. He intentado establecer evt.keyCode o evt.charCode sin éxito alguno.
Dependiendo de sus necesidades, un TextEvent podría funcionar. (Funcionó para mí para mis necesidades, para Chrome. No es una prueba cruzada de navegador, pero la pregunta era específicamente sobre Chrome.)
// get a reference to the DOM element you want to affect
var input = document.getElementsByTagName(''input'')[0];
// create a TextEvent
var textEvent = document.createEvent(''TextEvent'');
// initialize the TextEvent
textEvent.initTextEvent(''textInput'', true, true, null, String.fromCharCode(13)+"/r/n", 9, "en-US");
// dispatch (''fire'') the TextEvent
input.dispatchEvent(textEvent);
He rastreado esto hasta un error en Webkit donde los eventos creados solo contienen KeyIdentifier pero no keyCode / charCode como se puede ver en el código fuente del navegador . Parece que hay un parche para resolver esto. Así que supongo que esta no es una pregunta adecuada nunca más ...
Puede createEvent(''Event'')
error de Webkit utilizando createEvent(''Event'')
lugar de createEvent(''KeyboardEvent'')
, y luego asignar la propiedad keyCode
. Vea esta respuesta y este ejemplo .
Si desea hacerlo de la manera correcta, puede usar DOM Keyboard Event Level 4 KeyboardEvent constructo y propiedad clave .
En los últimos navegadores o con DOM Keyboard Event Level 3/4 polyfill puede hacer algo como esto:
element.addEventListener(function(e){ console.log(e.key, e.char, e.keyCode) })
var e = new KeyboardEvent("keydown", {bubbles : true, cancelable : true, key : "Q", char : "Q", shiftKey : true});
element.dispatchEvent(e);
//If you need legacy property "keyCode".
// Note: In some browsers you can''t overwrite "keyCode" property. (At least in Safari)
delete e.keyCode;
Object.defineProperty(e, "keyCode", {"value" : 666})
Tenga en cuenta que keyCode y charCode están en desuso en la última versión de Spec (www.w3.org/TR/DOM-Level-3-Events/). Por lo tanto, no es posible que Chrome implemente initKeyEvent con el soporte de keyCode . Pero siempre puede anular este valor: ACTUALIZACIÓN : mal método:
var evt = document.createEvent(''KeyboardEvent'');
evt.initKeyEvent("keypress", false, true, null, false, false,
shift, false, keyCode(key), key.charCodeAt(0));
if(evt.keyCode != keyCode(key)) {
delete evt.keyCode;
// Note: In some browsers you can''t overwrite "keyCode" property. (At least in Safari)
Object.defineProperty(evt, "keyCode", { keyCode(key) });
}
O puede actualizar el prototipo del evento: ACTUALIZACIÓN : mal método:
// Note: In some browsers you can''t overwrite "keyCode" property. (At least in Safari)
var _native_keyCode_getter = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, "keyCode");
Object.defineProperty(KeyboardEvent.prototype, "keyCode", {
"enumerable" : true,
"configurable" : true,
"get" : function() {
if("__keyCode" in this)return this["__keyCode"];
return _native_keyCode_getter.call(this);
},
"set" : function(newValue) {
return this["__keyCode"] = isNaN(newValue) ? 0 : newValue;
}
});
Actualización Hay varias implementaciones de initKeyboardEvent. En mi polyfill KeyboardEvent lo detecto de alguna manera como este ( gist ):
var _initKeyboardEvent_type = (function( e ) {
try {
e.initKeyboardEvent(
"keyup" // in DOMString typeArg
, false // in boolean canBubbleArg
, false // in boolean cancelableArg
, global // in views::AbstractView viewArg
, "+" // [test]in DOMString keyIdentifierArg | webkit event.keyIdentifier | IE9 event.key
, 3 // [test]in unsigned long keyLocationArg | webkit event.keyIdentifier | IE9 event.location
, true // [test]in boolean ctrlKeyArg | webkit event.shiftKey | old webkit event.ctrlKey | IE9 event.modifiersList
, false // [test]shift | alt
, true // [test]shift | alt
, false // meta
, false // altGraphKey
);
return ((e["keyIdentifier"] || e["key"]) == "+" && (e["keyLocation"] || e["location"]) == 3) && (
e.ctrlKey ?
e.altKey ? // webkit
1
:
3
:
e.shiftKey ?
2 // webkit
:
4 // IE9
) || 9 // FireFox|w3c
;
}
catch ( __e__ ) { alert("browser do not support KeyboardEvent") }
})( document.createEvent( "KeyboardEvent" ) );
var e = document.createEvent( "KeyboardEvent" );
...
if( "initKeyEvent" in e ) {//FF
//https://developer.mozilla.org/en/DOM/event.initKeyEvent
e.initKeyEvent( type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _keyCode );
}
else if( "initKeyboardEvent" in e ) {//https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent()
if( _try_initKeyboardEvent ) {
if( _initKeyboardEvent_type == 1 ) { // webkit
//http://.com/a/8490774/1437207
//https://bugs.webkit.org/show_bug.cgi?id=13368
e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _shiftKey, _altKey, _metaKey, _altGraphKey );
}
else if( _initKeyboardEvent_type == 2 ) { // old webkit
//http://code.google.com/p/chromium/issues/detail?id=52408
e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _ctrlKey, _altKey, _shiftKey, _metaKey, _keyCode, _keyCode );
}
else if( _initKeyboardEvent_type == 3 ) { // webkit
e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _ctrlKey, _altKey, _shiftKey, _metaKey, _altGraphKey );
}
else if( _initKeyboardEvent_type == 4 ) { // IE9
//http://msdn.microsoft.com/en-us/library/ie/ff975297(v=vs.85).aspx
e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _key, _location, _modifiersListArg, _repeat, _locale );
}
else { // FireFox|w3c
//http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent-initKeyboardEvent
//https://developer.mozilla.org/en/DOM/KeyboardEvent#initKeyboardEvent()
e.initKeyboardEvent( type, _bubbles, _cancelable, _view, _char, _key, _location, _modifiersListArg, _repeat, _locale );
}
}
}
Solo quiero arrojar este fragmento básico por ahí. Funciona en Chrome y se basa en el hack mencionado por Paul Irish.
Utiliza charCode en lugar de keyCode (que puede ser útil en determinadas situaciones), pero se adapta a keyCode si así lo desea.
var keyboardEvent = new KeyboardEvent(''keypress'', {bubbles:true});
Object.defineProperty(keyboardEvent, ''charCode'', {get:function(){return this.charCodeVal;}});
keyboardEvent.charCodeVal = [your char code];
document.body.dispatchEvent(keyboardEvent);