Est-il possible de simuler des événements clés de presse de façon programmatique?
est-il possible de simuler des événements clés de presse de manière programmatique en JavaScript?
18 réponses
une version non-jquery qui fonctionne à la fois dans webkit et gecko:
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
40, // keyCodeArg : unsigned long the virtual key code, else 0
0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
si vous êtes d'accord pour utiliser jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
Ce que vous pouvez faire est de déclencher par programmation keyevent auditeurs par le feu keyevents . Il est logique de permettre cela du point de vue de la sécurité. En utilisant cette capacité, vous pouvez alors appliquer un typique observateur-modèle . On pourrait appeler cette méthode "simulation".
ci-dessous est un exemple de la façon d'accomplir ceci dans la norme DOM W3C avec jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
cet exemple est adapté de: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
En jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
mais depuis peu, il n'y a pas de moyen [DOM] de déclencher des événements clés en sortant du bac à sable du navigateur. et tous les principaux fournisseurs de navigateurs adhéreront à ce concept de sécurité.
comme pour les plugins comme Adobe Flash - qui sont basés sur le NPAPI-, et permettent de contourner le bac à sable: ce sont élimination progressive ; Firefox .
Explication Détaillée:
vous ne pouvez pas et vous ne devez pas pour des raisons de sécurité (comme Pekka l'a déjà souligné). Vous aurez toujours besoin d'une interaction utilisateur entre les deux. En outre, imaginez la chance des vendeurs de navigateur obtenir poursuivi par les utilisateurs, comme divers programmateurs clavier événements ont conduit à des attaques par usurpation.
de cette post pour des alternatives et plus de détails. Il y a toujours le copier-coller flash. Voici un élégant exemple . En même temps c'est un témoignage pourquoi le web s'éloigne des vendeurs de plugin.
il existe un État d'esprit similaire en matière de sécurité appliqué dans le cas de la Politique opt-in CORS pour accéder au contenu à distance par programmation.
la réponse est:
il n'y a aucun moyen de déclencher programmatiquement des touches d'entrée dans l'environnement sandboxed browser dans des circonstances normales .
Bottomline: Je ne dis pas que ce ne sera pas possible à l'avenir, sous des modes de navigateur et/ou des privilèges spéciaux vers le but final du jeu, ou des expériences utilisateur similaires. Cependant avant d'entrer ces en mode, l'Utilisateur sera invité à fournir des permissions et des risques, similaires au Fullscreen API model .
utile: dans le contexte de KeyCodes, cet outil et la cartographie de keycode sera pratique.
Divulgation: La réponse est basée sur la réponse ici .
vous pouvez utiliser dispatchEvent()
:
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
Je ne l'ai pas testé, mais il est adapté du code sur dispatchEvent()'s documentation . Vous voudrez probablement lire à travers cela, et aussi les docs pour createEvent() et initKeyEvent().
vous pouvez créer et envoyer des événements clavier, et ils déclencheront des gestionnaires d'événements enregistrés appropriés, mais ils ne produiront pas de texte , s'ils sont envoyés à l'élément d'entrée par exemple.
pour simuler complètement l'entrée de texte, vous devez produire une séquence d'événements clavier plus explicitement définir le texte de l'élément d'entrée. La séquence des événements dépend de la façon dont vous voulez simuler l'entrée de texte.
le forme la plus simple serait:
$('input').val('123');
$('input').change();
vous pouvez envoyer des événements clavier sur un élément comme celui-ci
element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
en S'appuyant sur la réponse d'alex2k8, voici une version révisée qui fonctionne dans tous les navigateurs que jQuery supporte (le problème était dans les arguments manquants à jQuery.événement.trigger, qui est facile à oublier en utilisant cette fonction interne).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
vous pouvez même pousser plus loin et le laisser non seulement simuler l'événement, mais en fait insérer le caractère (si c'est un élément d'entrée), mais il ya beaucoup de cross-browser gotcha en essayant de le faire. Mieux utiliser un plugin plus élaboré comme SendKeys .
cette approche prend en charge le navigateur croisé changeant la valeur de code clé . Source
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
pour ceux qui sont intéressés, vous pouvez, en fait, recréer des événements d'entrée de clavier de manière fiable. Afin de changer le texte dans la zone d'entrée (déplacer curseurs, ou la page via un caractère d'entrée), vous devez suivre de près le modèle D'événement DOM: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
le modèle devrait faire:
- focus (expédié sur le DOM avec l'objectif fixé)
Puis pour chaque caractère:
- keydown (répartis sur les DOM)
- avant l'entrée (expédiée à la cible si c'est un textarea ou input)
- keypress (expédié sur le DOM) "151970920 d'entrée" (envoyé à la cible si ses un textarea ou d'entrée)
- le changement (envoyé à la cible si ses select)
- keyup (expédié sur le DOM)
, Puis, éventuellement, pour la plupart:
- flou (envoyé sur le DOM avec la cible fixée)
cela modifie réellement le texte dans la page via javascript (sans modifier les énoncés de valeur) et déclenche n'importe quels auditeurs/gestionnaires javascript de manière appropriée. Si vous gâchez la séquence, javascript ne se déclenchera pas dans l'ordre approprié, le texte dans la boîte de saisie ne changera pas, les sélections ne changeront pas ou le curseur sera ne pas passer à l'espace suivant dans la zone de texte.
malheureusement, le code a été écrit pour un employeur sous une NDA donc je ne peux pas le partager, mais il est certainement possible, mais vous devez recréer la totalité de l'entrée clé "stack" pour chaque élément dans le bon ordre.
il suffit d'utiliser CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex veux simuler les touches ctrl+z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
dans certains cas keypress
événement ne peut pas fournir funtionality requis, généralement, les événements est combiné à partir des deux événements par conséquent tiré keydown
, et le suivant it keyup
pour la même clé. Il suffit donc de générer les événements un par un:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
Voici une bibliothèque qui aide vraiment: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
je ne sais pas d'où il vient, mais il est utile. Il ajoute une méthode .simulate()
à window.KeyEvent
, donc vous l'utilisez simplement avec KeyEvent.simulate(0, 13)
pour simuler un enter
ou KeyEvent.simulate(81, 81)
pour un 'Q'
.
Je l'ai eu à https://github.com/ccampbell/mousetrap/tree/master/tests .
cela a fonctionné pour moi et il ne simule un keyup pour mon textaera. si vous le voulez pour la page entière vient de mettre le KeySimulation()
sur <body>
comme ceci <body onmousemove="KeySimulation()">
ou si pas onmousemove
alors onmouseover
ou onload
fonctionne aussi.
<script>
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
</script>
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Voici une solution qui fonctionne en Chrome et Chrome (n'ont testé que ces plates-formes). Il semble que Chrome ait un bug ou sa propre approche pour gérer les codes clés, de sorte que cette propriété doit être ajoutée séparément au clavier Event.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
dès que l'utilisateur appuie sur la touche en question, vous pouvez stocker une référence à ce même et l'utiliser sur n'importe quel autre élément HTML:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
vous pouvez définir le keyCode si vous créez votre propre événement, vous pouvez copier les paramètres existants à partir de n'importe quel événement de clavier réel (ignorant les cibles depuis son travail de dispatchEvent) et:
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
Une seule ligne à la vanille web Javascript inspecteur guy prêt pour le console dans un copier+coller (ce mec est déjà attrayante pour la plupart des devs, donc, ne pas essayer d'embellir lui - il est censé être unique.. en ligne)
var pressthiskey = "q"/* <--- :) !? q for example */; var e = new Event("keydown"); e.key=pressthiskey; e.keyCode=e.key.charCodeAt(0); e.which=e.keyCode; e.altKey=false; e.ctrlKey=true; e.shiftKey=false; e.metaKey=false; e.bubbles=true; document.dispatchEvent(e);
c'est Ce que j'ai réussi à trouver:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
vous devriez utiliser une certaine lib JS avec le soutien pour emballer le modèle D'événement DOM. À partir de là, vous pouvez tirer et tester vos maîtres.