How to know if a key is pressed having no charcode value - javascript

I want to know if ctrl,space,alt,capslock,shift like keys are pressed in my keyboard.
When i do
String.fromCharCode(e.keyCode)
,it returns blank value for these keys but when I do
alert($.trim(String.fromCharCode(e.keyCode))=='')
Then it return false for all keys except space bar.So it would be great if someone may tell me to get the keydown event of these keys

Vanilla JavaScript:
For other constants, see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
window.onkeydown = function (e) {
switch (e.keyCode) {
case KeyboardEvent.DOM_VK_SPACE:
alert('space bar!');
break;
case KeyboardEvent.DOM_VK_CAPS_LOCK:
alert('CAPS LOCK!');
break;
case KeyboardEvent.DOM_VK_CONTROL:
alert('control!');
break;
case KeyboardEvent.DOM_VK_SHIFT:
alert('shift!');
break;
case KeyboardEvent.DOM_VK_ALT:
alert('alt!');
break;
}
};
UPDATED FOR REQUIREMENT TO AVOID CASES:
Per the following test, the only numeric values that will, after trimming (and not including numbers not corresponding to the average keyboard), be reduced to an empty string are 9,10,11,12,13,32. Looking at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Virtual_key_codes , the only ones that correspond are tab, clear, return, and space .
// Run in Firefox where trim() is supported (without need for jQuery):
var arr = [];
for (var i=0; i < 0xFFFF; i++) {
if (String.fromCharCode(i).trim() == '') {
arr.push(i);
}
}
In other words, your own test is not going to catch all cases.
So you have to use numeric comparisons based on the info at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Virtual_key_codes and BASED ON EXACTLY WHAT CHARACTERS YOU NEED TO INCLUDE (or exclude).
For example, if you consider the cancel key, help key, back space, tab, etc. all to be of the type you mentioned, you can do:
window.onkeydown = function (e) {
if (e.keyCode < 0x30) {
alert('Special key pressed!');
}
};
As you can see, this allows for us to find a whole group of characters within a short amount of code (e.g., without using case). (But if we don't know exactly which characters you want to include or exclude, we can't give you a more precise answer.)

NOTE:
charCode is never set in the keydown and keyup events. In these cases, keyCode is set instead.
you can try
$(window).keydown(function (e){
if (e.ctrlKey) { there are e.altKey & e.shiftKey also.
for other keys use hardcoded integer values.
alert("control");
}
});

I'm not sure about the support of keyIdentifier but if you are using the keyup, keydown or keypress events, but you could possibly do the following. However there are no cross-browser guarantees where charcode is not defined or is zero. Not using jquery to keep things as small as possible, and only detecting the keys that you specified. See article.
Javascript
/*jslint maxerr: 50, indent: 4, browser: true */
(function () {
"use strict";
function addEvent(elem, event, fn) {
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
function listenHandler(e) {
var ret = fn.apply(null, arguments);
if (ret === false) {
e.stopPropagation();
e.preventDefault();
}
return ret;
}
function attachHandler() {
window.event.target = window.event.srcElement;
var ret = fn.call(elem, window.event);
if (ret === false) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
return ret;
}
if (elem.addEventListener) {
elem.addEventListener(event, listenHandler, false);
} else {
elem.attachEvent("on" + event, attachHandler);
}
}
function checkKeys(e) {
if ("Alt,Shift,Control,CapsLock,U+0020".indexOf(e.keyIdentifier) !== -1) {
alert(e.keyIdentifier);
}
console.log(e.keyIdentifier);
}
addEvent(window, "keydown", checkKeys);
}());
On jsfiddle
Update: reading a bit furter, keyIdentifier is not supported by all browsers and so is not fullly cross-browser friendly.
3.4. New Standard Key and Character Events
The DOM3 standard abandons all hope of creating order among
event.keyCode, event.which and event.charCode, and instead defines new
values for keydown and keyup events. For a while it deprecated the
keypress event and replaced it with the textInput event, but that was
undone. Only a few browsers implemented the first version, and, so
far, no browsers have implemented the newest version. Earlier versions
of the specification defined attributes named event.keyIdentifier and
event.keyLocation. The keyIdentifier was a string that in most cases
looked like "U+0041" where the "0041" part is the unicode value of the
character sent by the key when it is typed without modifiers, in this
case the letter "A". For keys that didn't send unicode characters, or
where the unicode value is not standardized, it was a string like
"Enter", "Shift", "Left" or "F9". The keyLocation attribute gave
values to distinguish among multiple keys that had the same
identifier, like the left and right shift keys, or the keypad number
keys. It was 0 for standard keys, 1 or 2 for left or right versions of
a keys like Shift which appear twice on the keyboard, and 3 for keys
on the numeric keypad.
WebKit implemented support for keyIdentifier and got it mostly right.
Older versions conformed to an older version of the standard and
returned two extra zeros (eg, "U+000041") but this was corrected in
version 525. Windows versions of Safari and Linux versions of Chrome
return bad keyIdentifier values for all of the non-number symbol keys
(WebKit Bug 19906 reported in July 2008). The keyLocation attribute is
always 0 or 3, so it does not distinguish between left and right
modifier keys.
Konqueror returns keyIdentifier values like "Shift" and "Enter"
correctly, but instead of returning the Unicode values, it returns the
typed character itself, "a" or "A" instead of "U+0041". All
keyLocation values are zero, except for modifiers key, which are
always one, regardless of whether the left or right one was pressed.
We cannot, however expect any more browsers to implement that
standard, since it has now changed. The DOM 3 standard no longer
mentions event.keyIdentifier or event.keyLocation. Instead we have
event.key, event.char, event.location.. So far as I know, no browser
has yet implemented this new version of the DOM 3 standard.
In this standard event.char is defined only when you type a printable
character, or another character with a defined code (like tab or
backspace). It's basically like event.charCode except that it is the
character, not the character code and can be any unicode character not
just an ASCII code. Event.key is the same as event.char for printable
keys. For other keys, even ones like tab or backspace that have
character encodings, it is a string like 'Tab', 'Left' or 'F9'. These
values are supposed to be the same on keypress events as they are on
keyup and keydown events, though keypress would not be fired for those
cases where event.char is null.
Note that neither of these pretends to be a keycode identifying a
particular physical key on the keyboard. If you press the /? key on a
US keyboard while shift is off, but press the shift key before
releasing the /? key, then then on keydown you'll get event.key=='/'
and on keyup you'll get event.key=='?'. The only way your Javascript
program will know that those two events go together is if it happens
to know that those two characters are on the same key. There is an
event.locale value that is supposed to give you some clue on what type
of keyboard is being used, but figuring out what keys go with what on
a particular keyboard is up to you.
Clearly this abandonment of the idea of keycodes is going to cause
problems, but is still probably justified. In many (most?) operating
systems, I don't think the browser can actually tell which key was
pressed. In the browser source code I've seen, the keycodes are
generated from the the character codes, not vice versa, by simply
assuming that the character came from a US keyboard. So the keycode
values never really worked for non-US keyboards.
So while the keycode concept was a handly one, it isn't really
practically extensible in the real world. If you want a keycode in the
DOM 3 universe, you'll have to go on using the legacy event.keyCode
value, which, standards or no standards, isn't going away. The DOM 3
standard seems to recognize this, and reluctantly provides an appendix
with some standards for event.keyCode and the like. It casts a rather
weak vote for what I called "IE keycodes" above.

Related

Handling multiple keys pressed at once in JavaScript

For context: this is a JavaScript app running in the Xbox One. All of this is happening through the Xbox's virtual keyboard. Keep in mind that since I have figured out how the events are being fired, this shouldn't matter anymore, just how to deal with the two events at once.
It's not really multiple keys, what is happening is when I turn on CAPS for my app, I am getting two events keys at once: shift and whatever key I am actually pressing. The problem this is causing is that shift seems to be overriding whatever I am trying to spell, and no key is displayed in my input boxes.
I currently have a global function which takes care of all special events in the app, and I would like to handle this issue from over there but am not sure how to go about this issue.
Here is what I currently have:
// this is the global function where I would like to solve the issue
onStartup(function () {
var $html = $('html')
$html.on('keydown', function (evt) {
if (evt.isDefaultPrevented()) return
console.warn('key being pressed:', evt.keyCode)
if (evt.keyCode === 16) { // Note: 16 is shift's keycode
// do something to prevent shift from overriding the actual key I want to press.
return
}
})
})
When I press a key without CAPS being turned on, say a, which has the keyCode of 65, we have the following output:
key being pressed: 65
If however I try to do a capital a (or A), this is what happens:
key being pressed: 16
key being pressed: 65
What can I do to stop the shift from preventing me from actually typing the capital keys?
I figured it out! All I had to do was when shift was fired, to call evt.stopImmediatePropagation().
So basically, for my code:
// ...
if (keycodeControls.is('shift', evt)) {
evt.stopImmediatePropagation()
}

How to detect brace stroke

I am looking for a general solution to detect braces: { or }.
I have an azety keyboard and I need to use the ALT GR stroke to type them, they are respectively located on the 4 and + keys.
As it is not the same on qwerty keyboard, and probably other dispositions,
I can not know if these characters are being typed just with the information given by the event returned by the keyup listener, I just know that the 4 has been pressed (Chrome does not event let me know that the alt gr is pushed).
Yet, if I use the keypress event, I get the correct code.
But keyup is preferable for me.
var element = document.getElementById('textbox');
element.onkeyup = function(evt){
console.log("keyup");
console.log(evt.which);
};
element.onkeypress = function(evt){
console.log("keypress");
console.log(evt.which);
};
<textarea id="textbox"></textarea>
with that code, I get this output when I type a {:
keypress
123 // { key code
keyup
52 // 4 key code
keyup
225 //alt gr key code
So, is there a solution, independant to the keyboard disposition to detect braces?
AltGr is the same as Ctrl-Alt you could ask for the modifiers while checking.
You must know that the same keyboard could change de configuration of the position of each, keys. I'm have a Spanish/English windows configuration and I change the layout several times in the same day (that changes the position of { and }).
You must use keypress

Detect shiftKey for mouse event on google maps v3 polygon

Is there a way to detect a shift-mouseclick on a polygon when using the google maps V3(.16) javascript API?
https://developers.google.com/maps/documentation/javascript/reference#MouseEvent
I do receive the mouse event, and I can see that the original event is wrapped in a google event class, which is just what's needed (Access the event.Ua.shiftKey property).
I found however that last month, google may have updated their api and now the property is renamed to event.Pa.shiftKey.
For reference, see http://i.stack.imgur.com/80npD.png for a screenshot of the event structure in the webinspector.
Is there any way to detect whether the shift key is pressed during a click on a google maps polygon using the event, and without having to rely on google-not-updating-their-api? What am I missing?
Thx!
Using undocumented properties is almost always a bad idea. If you can possibly avoid it, avoid it. In this case, the API is probably being compressed with the Closure Compiler, and so the next time they update, it may not be Pa anymore either.
Is there any way to detect whether the shift key is pressed during a click on a google maps polygon using the event, and without having to rely on google-not-updating-their-api?
If just Ua vs. Pa:
You could feature detect:
var shiftKey = (event.Ua || event.Pa).shiftKey;
That uses JavaScript's curiously powerful || operator to reference the Ua property's value, if there is one and it's truthy, or the Pa property's value otherwise.
This assumes that when they change it from Ua to Pa, they don't use Ua for something else. If there's a chance of that, this more thorough version would do it:
var shiftKey = ((event.Ua && 'shiftKey' in event.Ua) ? event.Ua : event.Pa).shiftKey;
That specifically checks for a Ua object with a shiftKey property, falling back to Pa if not found.
If it could be anything
...you can search for it:
var shiftKey;
if (Object.keys(event).some(function(key) {
if (event[key] && 'shiftKey' in event[key]) {
shiftKey = event[key].shiftKey;
return true;
}
return false;
})) {
// We found it, `shiftKey` has the value
} else {
// We didn't find it
}
Side note: Object.keys is an ES5 feature present on all modern browsers. If you need to support older browsers like IE8, it can be polyfilled.
I've just come across this problem (after noticing I couldn't just use window.event because Firefox doesn't support it)
google.maps.mouseEvent has, as T.J. Crowder said, a property which contains keys such as shiftKey, altKey, etc. In the current release of google maps api, said property is va. So of course we can't use it because its name will change in the next release of so.
So my solution has been to iterate over the google.maps.mouseEvent parameter, checking its values so see which one of them is a valid window.MouseEvent.
var newcircle= new google.maps.Circle({map:map, position:map.getCenter(), radius:1000});
google.maps.event.addListener(newcircle,'click',function(mouseEvent) {
var event = Object.values(mouseEvent)
.filter(function (property) {
return property instanceof window.MouseEvent;
});
if (event.length) {
event = event[0];
} else {
event = {};
}
var shiftKey = event.shiftKey || false;
});
Funny enough, when I tried to use a marker for this example, there wasn't an instance of window.MouseEvent in the google.maps.mouseEvent.
I ended up with a solution close to amenadiel's answer. I thought it would be better not to relay on all the possible uglified variable names, but to look for the one being a MouseEvent and use that one to check for the shiftKey property, like this:
function polygonListener(polygonEvent) {
var shiftKey = false;
for(var i in polygonEvent){
if(polygonEvent[i] instanceof window.MouseEvent){
shiftKey = polygonEvent[i].shiftKey;
break;
}
}
// Rest of the code
}
In case anyone is still looking how to get the MouseEvent from a google maps event, this is the method I've been using.
const mouseEvent = Object.values(event).find(p => p instanceof window.MouseEvent);
// then do whatever with the MouseEvent
const shiftKey = mouseEvent.shiftKey;

Keycode is always zero in Chrome for Android

I need to detect the keycode for a custom search box on my website, but the keycode always returns as zero on Chrome for Android (except for backspace, which returns 8). Has anyone else experienced this, and how did you get around it? Our website works on all mobile browsers except Chrome for Android because we can't detect a non-zero keycode or charcode.
I'm running Chrome 27.0.1453.90 on Android 4.1.2 Jelly Bean. The problem can be duplicated with something as simple as:
alert(event.keyCode);
below solution also work for me. might be useful for others also.
var getKeyCode = function (str) {
return str.charCodeAt(str.length - 1);
}
document.getElementById("a").onkeyup = function (e) {
var kCd = e.keyCode || e.which;
if (kCd == 0 || kCd == 229) { //for android chrome keycode fix
kCd = getKeyCode(this.value);
}
alert(kCd)
}
I faced this issue and this is how I figured out how to solve the problem.
First, you need to enable USB debugging onto your Android phone so
you can see the logs of your browser on your desktop machine.
Second, refresh your web app on your phone and inside your console on the desktop type "monitorEvents(document)" or whatever element you want to inspect.
Do the action you want to inspect on your phone.
And this is how I found that the keydown event was actually fired by a unique event called "textInput" which contains the information inside event.originalEvent.data.
Hope this saves you time and good luck!
The true way to get the keyCode is to use
event.which
This property on event object is standardize the event.keyCode property. You can read about it also in jQuery documentation here or in MDN here
In other way, I have a lot of experience with keyboard events on android devices.
Android browser has problems sometimes with keyboard events due to device fragmentation (different ROMs between devices or external keyboard apps). The best way is to try to use all the keyboard events (keydown, keyup and keypress) and compare every result to get the pressed key.
The best way is to use in "input" event and get all the time the last charter. The input event can control like in my answer here.
We encountered this problem recently on a China made Android phone Meizu MX3, which has a deeply customized OS based on Android 4.4.4.
The default browswer and Chrome work just fine, but for some weird reasons we don't know, event.keyCode, event.charCode and event.which return 0 all the time in some other browsers(such as CM Browser or webview of Wechat app).
We resolved this by checking the last character you input such as 'A' or ' '(space), then we convert it to ascii code using charCodeAt such as "A".charCodeAt(0) which returns 97, which is the actual char code we need.
But we can only determine the char code of visible chars using this strategy, which meets our current need thank god.
Hope you guys can get some inspiration from this.
I have faced the same issue with Android Devices of SonyXperia and HTC. I have developing hybrid application where i am validating Amount text field by reading event.keyCode() of the entered char on keydown event from text field, so that i can allow only numbers and dot(.) char to be entered. I tried but it doesn't worked, returning always 0 in these devices.
Later i came with other solution with keyup event and char matching through Regular Expression:
$("#AmountField").keyup(function (e) {
var regex = /^[0-9\.]$/;
var str = $(this).val();
var subStr = str.substr(str.length - 1);
if(!regex.test(subStr)) {
if(str.length >0){
$(this).val(str.substr(0, (str.length - 1)));
}else{
$(this).val();
}
}
});
Hope this can help for the people who facing this issue. Good Luck.
<input type="text" id="char" size="15" onblur="showKeyCode()" value="a">
<input type="button" value="Show Key Code" onclick="showKeyCode();">
<script>
function showKeyCode()
{
var character = document.getElementById ( "char" ).value.substr(this.length - 1);
var code = character.charCodeAt();
var stringall = document.getElementById ( "char" ).value;
var msg = "The Key Code for the \""+character+"\" character is "+code+".";
alert(msg);
}
</script>
For reference
If anybody still digging it.Problem appears on stock Samsung keyboard for
android devices.
Instead use onkeyup.
change the type of the input to tel : <input type="tel">
this will let you log the keyCode but it doesnt log the backspace, and it might force the keyboard on mobile to only numbers.
So in most Android browser if u use keydown or keyup you wont be able to get the data from key or keyCode or which or code
You can use event.data(Inserted data key) and event.inputType(backspace or del in mobile)
In order to achieve the functionality you need you have to apply condition based on user agent for android mobile
if (navigator.userAgent.match(/Android/i)) {
node.addEventListener('input', handleInput, false);
} else {
node.addEventListener('keydown', handleKeyDown, false);
}
const handleKeyDown = event => {
event.preventDefault();
if (!event.key) {
return false;
}
genericFunctionHandleThings(event.key, event.code === 'Backspace');
};
const handleInput = event => {
event.preventDefault(); // Here event.preventDefault doesn't stop user from typing
genericFunctionHandleThings(event.data, event.inputType === 'deleteContentBackward');
node.value = storedOrProcessedValue;
};
Here I have used node.value = storedOrProcessedValue because if we want to make some restriction for user typing we need to process and re assign it to the input
You can use this with Input type text,url,email,tel these I have tested rest I need to check
Need to use charCode instead of keyCode
<input type="text" onKeyPress="return funName(this,event)" />
<script language="javascript">
function funName(th,ev)
{
alert(ev.charCode);
}
</script>

shiftKey in Safari on iOS

Is there any way to determine in javascript whether shift key is pressed on mobile keyboard, and distinguish it from the caps lock(twice pressed shift key)
Some Facts
First, let's look at some facts about iOS keyboards I assume you already know:
When you enter the keyboard mode, the shift key is always activated
Caps Lock must be activated manually (I guess this is not used too widely)
iPhone Shift Key Handling
I investigated a bit into this issue, and here's what I found:
The shift Key triggers no key Event
There is no special iPhone Browser API to detect whether the shift key is pressed or not, except in an iOS App (duh)
The keydown, keypress, keyup event triggered by iOS look normal, except they do not indicate shiftKey usage, and apart from their timestamp and type cannot be distinguished.
You cannot manually dispatch a Keyboard Event in iOS because of this issue, keyCode and which are readonly and always set to 0. Retriggering a Keyboard event to get some indication about the shift key still being on is impossible.
Actually, The iPhone treats the shift key like some sort of Short Term Caps Lock key. The difference is that normally, you activate it once, and it deactivates automatically.
What can be done
I assume you want to indicate on an input field whether the user should be careful about having Shift/Caps Lock pressed (a password field, for example). What I came up with is some sort of a workaround, but I think it's better than nothing.
You can also test the jsfiddle here.
DOM Setup
<div id="wrapper">
<label for="test">ENTER SOMETHING HERE</label>
<input type="text" name="test" id="test"/>
</div>
<div id="warning"></div>​
Javascript
This checks wheter the user did enter capitalized input, and it assumes the user is using caps lock if two capitalized letters where entered.
var isCaps = false,
isUppercase = false,
str = '',
test = document.getElementById('test'),
warning = document.getElementById('warning');
function capsDetection(e) {
// Since where on iOS, we at least don't have to care
// about cross-browser stuff
var s = String.fromCharCode(e.which);
isCaps = isUppercase;
// if the char doesn't match its lower case friend, and the shift key is
// not pressed (which is always the case on iOS, but we leave it there
// for readability), we have uppercase input
isUppercase = (s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey);
// if its the second uppercase input in a row, we may have caps lock input
isCaps = isCaps && isUppercase;
// set the warning
if (isUppercase && !isCaps) {
str = 'You where using the shift key';
}
else if (isCaps) {
str = 'Caps lock seems to be activated';
} else {
str = '';
}
warning.innerHTML = str;
}
// the right event properties are only available on keypress
test.addEventListener('keypress', capsDetection);
As I said, better than nothing, but not a solution if you need to know the shift key is pressed without the user doing any input. That seems to be impossible right now.
I don't think that this is possible with Javascript. It is possible with objective C though.
http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html

Categories

Resources