ut_markle
ut_markle

Reputation: 13

srcElement.readOnly and target.readOnly problems in Internet Explorer

I'm not sure I understand the behavior of IE in this script I'm working. This is part of the script I'm using that seems to work fine in Chrome

$(document).keydown(function (event) {
    var keyvalue = event.which || event.keyCode; 
    var eventtarget =  event.srcElement.nodeName || event.target.nodeName; 
    var readonlycheck = event.srcElement.readOnly || event.target.readOnly;
}); 

The problem comes in on the readonlycheck variable. In IE I get the error of "Unable to get property 'readOnly' of undefined or null reference."

In Chrome, readOnly returns 'true' if it's defined and 'false' if it's not. IE gives me an error, even though it still works with the nodeName.

Where I get really confused is that I can make it work by changing the last line to eliminate the target.readOnly. So this seems to work in both browsers...

var readonlycheck = event.srcElement.readOnly;

Can anyone explain why this behaves differently for readOnly? Also, I thought srcElement was IE only, so why is Chrome still working without the target.readOnly?

Any help would be appreciated. I'm still very new to javascript and jquery so I'm sure I'm missing something.

Upvotes: 1

Views: 3006

Answers (3)

Andy E
Andy E

Reputation: 344635

The problem is the short-circuit || operator. If event.srcElement.readOnly evaluates to false, the right operand, (which should be) e.target.readOnly will be evaluated. It's the same as writing, for example:

var readonlycheck = false || e.target.readOnly;

You can use braces instead to work around this issue:

var readonlycheck = (e.target || event.srcElement).readOnly

Note that I moved the standards compliant to the left hand side so that it's evaluated first. It doesn't make much of a difference here, but on more time-consuming operations it could, so I just find that it's a good practice to get into.

I start most of my event handlers with the following code when I need the event object and the event target:

function evtHandler(evt) {
    evt = evt || window.event;
    var target = evt.target || evt.srcElement;
}

Upvotes: 0

Nope
Nope

Reputation: 22339

In your code you specify function(e) though in your function you use event instead of e.
Additionally as event.target and event.srcElement are the same thing it would make more sense to initiate the target once at the start.

    var target = event.target || event.srcElement;    

Updating your code to something similar to the below should work:

$(document).keydown(function (event) {
    var target = event.target || event.srcElement;    

    var keyvalue = event.which || event.keyCode; 
    var eventtarget =  target.nodeName; 
    var readonlycheck = target.readOnly;
}); 

Upvotes: 0

psychobunny
psychobunny

Reputation: 1247

var readonlycheck = event.srcElement.readOnly || event.target.readOnly;

should change it to

var readonlycheck = (event.srcElement !== undefined) ? event.srcElement.readOnly : event.target.readOnly;

how you wrote your code, even though srcElement.readOnly does exist, when it evaluates to false it attempts to read event.target, which breaks IE.

Upvotes: 2

Related Questions