Adding keypress Events that use an existing function - javascript

I have used a function which is activated on click events. I want to do the same using keypress events.
function addToText(target) {
var exp = target.target;
//alert(exp.value);
if (newExp) {
//clearText();
document.getElementById("expression").value = exp.value;
newExp=false;
}
else
document.getElementById("expression").value = document.getElementById("expression").value + exp.value;
}
This is the function used. How do I modify it to use for keypress events also. Currently, it does not work initially(for keypress events). But after clicking once, then any keypress returns the same number that was previously clicked.
Full code here:http://codepen.io/jpninanjohn/pen/JXVpYb?editors=1010

Here's is your final solution, I test if charcode is between 48 and 57, what it means, numbers between 0 and 9.
document.addEventListener('keypress', function(e){
if (e.which >= 48 && e.which <= 57)
document.getElementById("expression").value+= String.fromCharCode(e.which);
});

You can use this function-
window.onkeyup = function(e) {
var key = e.keyCode ? e.keyCode : e.which;
document.getElementById("expression").value += key-48; //for getting the number
alert(key);
if (key == 38) {
//whatever
}else if (key == 40) {
// whatever
}
}
source
And you need to add + to the =
document.getElementById("expression").value+=
instead of -
document.getElementById("expression").value=

You have to add a different function for keyPress event, because the keypress event get the value of pressed key differently, not target.target
function addToTextKeypress(event) {
var exp = String.fromCharCode(event.keyCode);
//alert(exp);
if (newExp) {
//clearText();
document.getElementById("expression").value = exp;
newExp=false;
}
else
document.getElementById("expression").value = document.getElementById("expression").value + exp;
}
Later you need to remove exp.value since it has the direct value

Related

Move player javascript

I do not understand this part :
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
explain what this code does, please)
MVC :
Controller:
this.init = function() {
keys = {};
}
self.trgt = function(){
if(this.event.target === myContainer.querySelector('#start')) {
myModel.startGame();
window.addEventListener('keydown', self.keyDown);
window.addEventListener('keyup', self.keyUp);
}
}
self.keyDown = function() {
keys[event.keyCode] = 1;
};
self.keyUp = function() {
delete (keys[event.keyCode]);
};
self.moveHero = function(keycode) {
myModel.moveHero(keycode);
};
setInterval(function() {
for (let keycode in keys) {
self.move(keycode);
}
}, 20);
Model:
if (!sometask) {
if (keycode == 37 || keycode == 65) {
self.moveLeft();
}
if (keycode == 38 || keycode == 87) {
self.moveTop();
}
if (keycode == 39 || keycode == 68) {
self.moveRight();
}
if (keycode == 40 || keycode == 83) {
self.moveBottom();
}
}
};
the code in question:
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
is just assigning which keys are currently pressed. Lets say event.keyCode = 37, In this instance your keys variable, which is an object, will now have a property that says keys[37] = 1, and it will remain that way until the keyUp function is called, deleting it. Whiile keys[37] = 1, the character will continue moving left, and this will stop once that key is deleted.
self.keyDown = function() { keys[event.keyCode] = 1; };
self.keyUp = function() { delete (keys[event.keyCode]); };
Translating to plain English:
If the user press the keyDown (number 40) then set the key 40 in the object keys to 1.
If the user press the keyUp (number 38) then delete from the keys object the key 38
These lines are to set functions that will be called each time the event keyDown (press a key) or keyUp (release the key) are called.
So let's focus on the actual code inside the function :
for keyDown, it sets a variable in a dictionary to a value. for instance, if you press down 'a', 'a' key on the keyboard has some int value which is 65 (see https://keycode.info/), and it will set the keys[65] = 1.
As long as you keep the button press, this value will stay, but as soon as you release it, the value is unset by using delete .
And so on for each keyboard key.
Then the main loop of the game will look which variables are set (by using "for ... in keys), and will execute a move function for each variable that has a special values, corresponding, I guess, to a-w-s-d or left-up-right-down.

Hotkey combinations don't work if done fast

I'm trying to make a hotkey for a web app, for example Ctrl + z performs the undo function.
It seems that when I press the keys fast (as I'm used to from using desktop apps a lot), it doesn't register. The single key press registers, but it misses the combination for some reason.
From what I understand, you have to keep track of which buttons are held down via keypress events, which is what I've done below.
Try the code below. Hitting Z outputs Z. Hitting CTRL then Z slowly outputs CTRL + Z. Hitting CTRL then Z quickly outputs Z. When I perform the action at the same speed in say Notepad for windows, it works flawlessly almost every time.
https://codepen.io/samkeddy/pen/YQjgdZ?editors=1010#0
var ctrlPressed=false, altPressed=false;
window.addEventListener("keydown", function (e) {
hotkey = e;
if (e.keyCode == 17) ctrlPressed = true;
if (e.keyCode == 18) altPressed = true;
e.preventDefault();
});
window.addEventListener("keyup", function (e) {
hotkey = window.event;
if (e.keyCode == 17) ctrlPressed = false;
if (e.keyCode == 18) altPressed = false;
if (e.keyCode == 90){
if (altPressed && ctrlPressed && e.keyCode == 90)
addText('ALT + CTRL + Z');
else if (ctrlPressed && e.keyCode == 90)
addText('CTRL + Z');
else
addText('Z');
}
});
//meaningless, just adds text to doc so you can see it
function addText(text) {
var theDiv = document.getElementById("output");
theDiv.appendChild(document.createElement("br"));
var content = document.createTextNode(text);
theDiv.appendChild(content);
}
Use e.ctrlKey to check if ctrl is down instead of variables, and just check for the hotkey combination on keydown, don't do anything on key up.
https://codepen.io/samkeddy/pen/gRdBpq
function KeyPress(e) {
var evtobj = window.event? event : e
if (evtobj.keyCode == 90 && evtobj.ctrlKey) addText("CTRL + Z");
else if (evtobj.keyCode == 90) addText("Z");
}
document.onkeydown = KeyPress;

How to implement user-customizable keyboard shortcuts (in javascript/on the web)

The title says most of it. I'd like a javascript/html solution for how to make persistent, user-configurable keyboard shortcut listeners (plus any nice thoughts on how to actually persist the preferences if you have 'em).
It seems both straightforward and slightly tricky at the same time :)
Thanks!
If you want to allow the user get shortcuts like "Control"+(...), you just have to capture the keys pressed, so check if "Control" is pressed with such keys pressed to do an action.
This is an simple and bad example of doing this:
var Pressed={
CTRL:false,
Spacebar:false
},Keyboard={ // an object containing Keyboard keys code
CTRL:17,
Spacebar:32
};
window.onkeydown=function(e){ // user started pressing an key (event)
var Key=(e.keyCode||e.which||e.key); // capture key pressed from event
if(Key==Keyboard.CTRL){ // CTRL is pressed
Pressed.CTRL=true
Pressed.Spacebar=false // CTRL has to be pressed before than Spacebar
}else if(Key==Keyboard.Spacebar){ // Spacebar is pressed
Pressed.Spacebar=true
}
if(Pressed.CTRL&&Pressed.Spacebar){ // Case CTRL+Spacebar are pressed
e.preventDefault(); // prevent Opera from quitting from the page
console.log("CTRL+Spacebar were pressed.")
}
},
window.onkeyup=function(e){ // event when an key is released
var Key=(e.keyCode||e.which||e.key); // capture key released from event
if(Key==Keyboard.CTRL){ // CTRL is released
Pressed.CTRL=false
}else if(Key==Keyboard.Spacebar){ // Spacebar is released
Pressed.Spacebar=false
}
};
To update...
You can try something like this:
For demo purpose, I have just logged if Alt, Ctrl or Shift + 'Key' and if key is defined in shortcuts, then print Special action else 'Normal action'. Also I have disabled propagation of key events for inputs, but this section can be removed if not required.
JSFiddle
Code
(function keyLogger() {
var isCtrlPressed = false;
var isAltPressed = false;
var isShiftPressed = false;
var shortcutKeys = [
13, // Enter
32, // Space
37, // Left Arrow
38, // Up Arrow
39, // Right Arrow
40, // Down Arrow
90, // z
]
function registerEvents() {
document.onkeydown = function(event) {
var keyCode = event.keyCode ? event.keyCode : event.which;
if (keyCode >= 16 && keyCode <= 18) {
updateKeyFlags(keyCode, true);
}
if (isCtrlPressed || isAltPressed || isShiftPressed) {
if (shortcutKeys.indexOf(keyCode) >= 0) {
console.log("Special action");
} else {
console.log("Normal action");
}
}
}
document.onkeyup = function(event) {
var keyCode = event.keyCode ? event.keyCode : event.which;
if (keyCode >= 16 && keyCode <= 18) {
updateKeyFlags(keyCode, false);
}
}
// To prevent logging from Inputs.
// Can be removed if this action is required.
var inputs = document.getElementsByTagName("input");
for (var i in inputs) {
inputs[i].onkeyup = function(event) {
event.stopPropagation();
}
inputs[i].onkeydown = function(event) {
event.stopPropagation();
}
}
}
function updateKeyFlags(keyCode, flag) {
switch (keyCode) {
case 16:
isShiftPressed = flag;
break;
case 17:
isCtrlPressed = flag;
break;
case 18:
isAltPressed = flag;
break;
}
}
registerEvents();
})();
<div>
<input type="text">
<input type="text">
</div>

Calling click from keydown, but getting the correct checkbox checked property

This isn't a jQuery only question as it has to do with events and order of operation. Consider the following code, which is based on jQuery multiSelect plugin (please post citation if you can find it):
Fiddle with it here
var debug = $('#debug');
var updateLog = function (msg){
debug.prepend(msg + '\n');
};
var title = $('#title').focus();
var container = $('#container');
title.keydown(function(e){
// up or down arrows
if (e.keyCode == 40 || e.keyCode == 38) {
var labels = container.find('label');
var idx_old = labels.index(labels.filter('.hover'));
var idx_new = -1;
if (idx_old < 0) {
container.find('label:first').addClass('hover');
} else if (e.keyCode == 40 && idx_old < labels.length - 1) {
idx_new = idx_old + 1;
} else if (e.keyCode == 38 && idx_old > 0) {
idx_new = idx_old - 1;
}
if (idx_new >= 0) {
jQuery(labels.get(idx_old)).removeClass('hover');
jQuery(labels.get(idx_new)).addClass('hover');
}
return false;
}
// space/return buttons
if (e.keyCode == 13 || e.keyCode == 32) {
var input_obj = container.find('label.hover input:checkbox');
input_obj.click();
return false;
}
});
// When the input is triggered with mouse
container
.find('input:checkbox')
.click(function(){
var cb = $(this);
var class = "checked";
if (cb.prop(class)){
cb.parent('label').addClass(class);
} else {
cb.parent('label').removeClass(class);
}
updateLog( cb.closest('label').text().split(/[\s\n]+/).join(' ') + ': '
+ this.checked + ' , '
+ cb.prop(class));
title.focus();
})
;
Notice the difference in the checkbox value for when you click directly on the checkbox, versus when you select the checkbox with the space/enter key. I believe this is because it's calling click during the keydown event, so the value of the checkbox is not yet changed; whereas if you actually click the input, the mouseup event occurs before the click (?), so the setting is applied.
The multiselect plugin does not call the click event, it has almost duplicate code. I'm curious if it would be better to pass a parameter to the click event (or use a global) to detect if it issued by the keyboard or mouse, or if it is better to just do what the plugin did and have the code inside the keydown function.
Obviously, if the log were after the click() runs, the keydown would return trues, but there are things that happen inside of click that are based on the input's checked status.
Changed it to use the change event instead of the click event for the checkboxes
http://jsfiddle.net/QJsPc/4/

How to Trigger an event with keys(ctrl +)(jQuery)

How can I trigger an event with jQuery if I press the Ctrl key plus the ++ key(zoom in).
key = Ctrl ++
Try this
$(window).keypress(function(e){
if((e.which == 61 && e.ctrlKey) || (e.which == 43 && e.ctrlKey)){
//Ctrl + "+" is pressed, 61 is for =/+ anr 43 is for Numpad + key
}
});
An example of binding to Ctrl+I. Note that you can't override default browser behavior, so many of the Ctrl+(letter) shortcuts are reserved (Ctrl+T = new tab, Ctrl+N = new Window, Ctrl+P = Print etc...)
$(window).keydown(function(e){
if(e.which == 17)
$(window).bind('keydown.ctrlI', function(e){
if(e.which == 73){
e.preventDefault();
alert('CTRL+I');
}
});
});
$(window).keyup(function(e){
if(e.which == 17)
$(window).unbind('keydown.ctrlI');
});
// the element at which you are firing the event
var div = $('#foo');
// the event handler
div.bind('paint', function() {
$(this).addClass('painted');
});
$(window).keydown(function(e) {
// if CTRL + + was pressed
if ( e.ctrlKey && e.which === 187 ) {
// trigger the event
div.trigger('paint');
}
});
Live demo: http://jsfiddle.net/NMYJW/

Categories