JavaScript key undefined in IE over SSL - javascript

I'm working on a web app that works fine inside the LAN using HTTP but when I test it remotely over SSL it fails for IE (7 & 8). Firefox, Camino and Safari all work perfectly.
I've tracked down the issue to key being undefined. The relevant bit of code is:
function showResult(e,str,num) {
var key = (window.Event) ? e.which : e.keyCode;
if(((key > 32 && key < 58) || (key > 64 && key < 91) || (key > 95 && key < 123)) && (str.length >= num)) {
Any clues as to why key would be undefined for IE over SSL but works fine over HTTP? Better yet, can someone tell me how to overcome this problem? FWIW, I don't need to support IE prior to version 7.
Update:
There was an answer which suggested replacing
var key = (window.event) ? e.which : e.keyCode;
with
var key;
e = e || window.event;
key = e.keyCode || e.which;
That works. The problem now is that I can't accept that answer because it has been deleted.

Ok, I'll re-add that answer, even though it wasn't mine, and add some info along the way so you can feel OK with accepting it even if it wasn't my answer from the beginning.
So, the suggested code is this:
var key;
e = e || window.event;
key = e.keyCode || e.which;
What does || do? For one it's the logical or operator, which would return true if one of the sides evaluate to boolean true.
It also has another use in JS. If you give it two arguments and the first one is undefined, it will return the second argument. This means, in the code above, that if e is undefined, you instead get window.event which is IE's traditional event object.
Same thing goes with e.keyCode || e.which whichever one exists is used. So in the end, you're likely to end up with a valid key code on various browsers. All is good in wonderland.
But wait, doesn't your original code do something similar?
var key = (window.Event) ? e.which : e.keyCode;
Uh-huh. What's that? JavaScript is case-sensisitive, so window.Event is not the same as window.event in the code above. window.event is IE's traditional event object that you would use get information about the event that occurred, while window.Event (which you can see from the initial capital letter) is a constructor, or more specifically in this case an interface.
Point is, in that code it was used to detect Mozilla. If it exists, choose e.which (One of the places where Mozilla stores the key code) otherwise go for e.keyCode where IE would store the key code.
However, this is based on the flawed assumption that IE doesn't have the window.Event constructor defined. It does have it defined as of IE8, at least. This means that e.which is chosen over e.keyCode, on newer versions of IE. e.which has never and will never be supported in IE. That's why key ends up being undefined.
But, uhm, why does it differ between encrypted and unencrypted connections? That's a good question. While I cannot know for sure without access to your development environment, I would assume it has something with IE's compatibility modes.
IE has historically (over the last 10 years) been the most quirky and non-standard browser around. This has lead to people a) programming ignorantly according to IE's standards b) creating workarounds for IE's behaviors. If MS just made IE standards-compliant, that would break many pages which rely on IE's quirky behavior in one way or the other. Microsoft has ackowledged this by making IE8+ emulate older versions of IE so pages won't break, unless told otherwise.
I can only assume that, for whatever reason, in your test environment the page ends up running in the "IE7" mode which might not have the window.Event constructor/interface defined. This would make your old code use e.keyCode which is ey OK. Then perhaps in your production environment, or maybe just because of the encrypted connection (only ghawd knows what MS is doing) you end up with a newer IE mode so window.Event is actually defined and e.which is chosen. This makes IE a cheeky monkey.
Bottom line: Use the new code.

Most probably, you've included a script over http (rather than https), which will fail to load because the page itself is secure and the included file insecure.

Related

What is the reliable way to detect OS using Javascript?

The use of navigator.userAgent is not advised as per MDN. In my application I want to have a shortcut for del key.
In mac del key (is backspace) with charCode = 8.
In windows del key charCode = 46.
I want to treat both keyEvents same. I am currently using userAgent but it is unreliable as that property can be spoofed. I am wondering what is the best way to know the client OS otherwise.
More deprecated navigator properties
navigator.appVersion
navigator.platform
/* code objective */
if ((keycode == 8 && os == 'macintosh') || keycode == 46) {
//This is keyboard shortcut to perform delete
}
Relying on KeyboardEvent.metaKey and KeyboardEvent.Backspace solved my problem
Full Key Values - https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
For more details refer: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key#Key_values
Thanks to #Teoli2003 for twitter reply - https://twitter.com/Teoli2003/status/663995373766221824

Should e.which be checked before e.keyCode or vice-versa?

Say that I am not using jQuery, and want to support IE8 along with the other mainstream browsers.
In order to normalize events, I am following this pattern:
document.onkeydown = function(e) {
var code;
if (!e) {
var e = window.event;
}
code = e.which || e.keyCode;
// More stuff here...
};
However, I suspect that if I changed the order of my e.which vs e.keyCode check, like so...
code = e.keyCode || e.which;
...then my code might act differently across browsers.
Question: Does the order matter? Is one order "better" than the
other?
Bonus: If I'm only supporting IE8 and up, does e.charCode matter?
Another bonus: Should I use var e = window.event or just e = window.event?
1. Yes, the order matters.
The order you should use is indeed:
code = e.which || e.keyCode;
This is because most browsers support e.which (IE<9 excluded, of course). This way, any browser (IE>=9 and FF, Chrome, Opera, Safari, etc.) that supports e.which will use it, and those that don't will use e.keyCode.
Should you switch the order to:
code = e.keyCode || e.which;
You'll get e.keyCode for virtually every browser (instead of e.which) which will tell you the key that was pressed but not the resulting character (which I suspect is not what you want).
2. No, e.charCode does not matter.
Browser support for e.charCode is spotty at best. Even IE9 documentation states that it's for compatibiity only. Most popular modern browsers return undefined or 0 (or ASCII, or Extended ASCII, if you're lucky and even then it's only on keypress).
Additional reading for both 1 and 2 should probably be done at:
http://www.quirksmode.org/dom/w3c_events.html#link4
http://www.quirksmode.org/js/keys.html
Should you wish to play around with key events, I made a fiddle for you to report the [relevant] properties of the event parameter when you type in the sole input field.
3. You should definitely use var e = window.event;.
If you don't use var, you're effectively declaring window.e = window.event which is silly. Use var to keep e defined in the scope of your handler.

Trying to figure out if there is a bug in jQuery or if it's something I'm doing

$(document).keydown(function (event)
{
alert(event.which);
});
For the semicolon key, ;, this gives 59 in Firefox and 186 in Chrome. However, from the jQuery reference page for the keydown event, it says
"While browsers use differing properties to store this information, jQuery normalizes the .which property so you can reliably use it to retrieve the key code. This code corresponds to a key on the keyboard, including codes for special keys such as arrows."
Am I missing something?
The which property is a "one stop shop" for which key was pressed, allowing you to ignore the differences between the keyCode and charCode properties. That is the "normalization" that jQuery provides.
The difference in the value of which comes down to a difference between the way the various browsers supply the information - so you'll have to write code to handle the different values that come back. There are a few references to this behavior online.
A quick Google search says you will simply have to test for both. This is a consistent inconsistency with Firefox.
I don't know about jQuery but I'd suggest sticking to keypress events for typing keys and only using keydown events for special keys such as arrows.
Here is the entirety of the "normalization" that jQuery does:
if ( event.which == null ) {
event.which = original.charCode != null ? original.charCode : original.keyCode;
}
Looks like it just gets keyCode if charCode doesn't exist. And charCode is only used if event.which doesn't already exist. It doesn't change the numbers around to make them consistent.

window.event.keyCode how to do it on Firefox? [duplicate]

This question already has answers here:
ReferenceError: event is not defined error in Firefox
(2 answers)
Closed 6 years ago.
I'm using this code to check for keydown and display the string 'Pressed' while a key is down.
<body onKeyDown="doKey(window.event.keyCode)" onKeyUp="doKey2(window.event.keyCode)">
<script>
function doKey($key) {
document.getElementById('keydown').innerHTML='Pressed';
}
function doKey2($key) {
document.getElementById('keydown').innerHTML='';
}
</script>
<div id="keydown"></div>
The problem is that for some reason it's only working on Chrome. I think the 'window.event.keyCode' doesn't return anything. How do I make it work at least in Firefox too? Thanks
Some browsers have a global event object, other send the event object to the event handler as a parameter. Chrome and Internet Exlporer uses the former, Firefox uses the latter.
Some browsers use keyCode, others use charCode.
Use arguments[0] to pick up the event object sent as a parameter, and if there is no object there, there is a global object instead:
onkeydown="doKey(arguments[0] || window.event)"
In the method you can check for either keyCode or charCode
function doKey(event) {
var key = event.keyCode || event.charCode;
...
}
Note the lowercase name onkeydown. If you are using XHTML event names has to be lowercase, or the browser might ignore it.
<html>
<body onKeyDown="doKey(event)" onKeyUp="doKey2(event)">
<script>
function doKey(e) {
evt = e || window.event; // compliant with ie6
document.getElementById('keydown').innerHTML = evt.keyCode+' Pressed';
}
function doKey2(e) {
document.getElementById('keydown').innerHTML='';
}
</script>
<div id="keydown"></div>
</body>
</html>
If we passed event as parameter, most modern browsers will work well. I have tested with Chrome 12, Firefox 4, IE 7/8/9.
I've run into the same problem, as I'm sure thousands of coders have.
The problem is that the browsers (other than IE) don't like window.event.
I'm poking around trying to find a solution (which is how I stumbled across this), and I found the following (so far):
1) Write JQuery:
$(document).keyup(function(e) {
var GetKey = e.keyCode;
`enter code here`
}
});
2) Redefine the key variable:
var key = (window.event) ? evt.keyCode : evt.which;
I tried the JQuery solution. It seems to be okay in FF, but I ran into an unexpected bug in IE that I'm still trying to solve. I haven't yet tried the second solution; that's next, if I can't get the JQuery to work.

what browser is document.layers sniffing?

I am looking at some JS code from the 20th century, and they are using document.layers in code that is trying to get the current key code. What browser are they sniffing for?
i am about to replace the code with something like this:
var fn = function(event){
event = event || window.event;
var code = event.charCode || event.keyCode;
}
but i am afraid of breaking something arcane and releasing the evil
document.layers exists in Netscape 4 and holds all <layer> and <ilayer> elements.
It was an early precursor to true DHTML.
For more information, see here. (Ten years old)
Netscape 4 is not able to display any modern web-page due to it's total lack of CSS support - so if you drop the support for this browser then you are not breaking anything that isnt already broken.

Categories

Resources