Fix 2170 ie element event change propertychange #2203

Merged
merged 2 commits into from Jan 18, 2012

Conversation

Projects
None yet
3 participants
Owner

ibolmo commented Jan 17, 2012

Adds fix and spec coverage for Element.Event.change. Specifically propertychange event in IE that was called too many times.

See #2170 and #2172.

@DimitarChristoff DimitarChristoff and 1 other commented on an outdated diff Jan 17, 2012

Source/Element/Element.Event.js
@@ -175,7 +175,7 @@ if (!window.addEventListener){
return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change'
},
condition: function(event){
- return !!(this.type != 'radio' || this.checked);
+ return event.type == 'change' || Boolean(this.checked) && event.type == 'propertychange' && event.event.propertyName == 'checked';
@DimitarChristoff

DimitarChristoff Jan 17, 2012

Member

isn't this more expensive - Boolean(this.checked) - can it affect delegation in IEx?

@arian

arian Jan 17, 2012

Owner

I don't think this check for this.checked is necessary is it? I just tested it with Specs/1.4client/Element/Element.Event.change.html and with this check it logs:

native change
change delegation

only if you check the checkbox.

Without that Boolean(this.checked) it always logs:

native change
change bubbles
change delegation

However with radio buttons it fires the event twice...

native change
change bubbles
change delegation
native change

So I guess that check is for radio buttons, however how it is in this commit, it won't work for checkboxes.

@csuwldcat, can you confirm?

@DimitarChristoff

DimitarChristoff Jan 17, 2012

Member

it is needed.

if you don't have it, on a set of radios, eg. <input name='r' value='1' checked='checked' /> <input name='r' value='2' />- it will fire change on BOTH of the input elements, one for the checked -> true and one checked -> false. this does not make sense as they represent variations of the same core element, input[name=r] and only one value will submit.

the spec test is too elementary and does not cover this - i found it through our production use and onChange branching events.

ibolmo added some commits Jan 17, 2012

@ibolmo ibolmo Fixes #2170.
Using DimitarChristoff's fix. See #2170 and #2172.

PASSED: IE6-9.
5fa8489
@ibolmo ibolmo Optimized the Element.Event.change condition. Added coverage non-radi…
…o inputs.
af074d3

@ibolmo ibolmo commented on the diff Jan 18, 2012

Source/Element/Element.Event.js
@@ -175,7 +175,7 @@ if (!window.addEventListener){
return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change'
},
condition: function(event){
- return !!(this.type != 'radio' || this.checked);
+ return this.type != 'radio' || (event.event.propertyName == 'checked' && this.checked);
@ibolmo

ibolmo Jan 18, 2012

Owner

@DimitarChristoff @arian @csuwldcat

Ok folks, have a go at it. As I understand, the issue can be resolved by just ensuring that the Event.propertyName is for checked. Then we just depend on the this.checked value (false|true).

@DimitarChristoff

DimitarChristoff Jan 18, 2012

Member

return !!(event.type === 'change' || this.checked && event.type === 'propertychange' && event.event.propertyName == 'checked') was my original suggestion. the difference is, event.type === 'propertychange' also ensures it is a radio or checkbox that has triggered it. there is no reason to go to element.type again and access a property on the element after the setup cond already has determined that and type won't change in-between.

@ibolmo

ibolmo Jan 18, 2012

Owner

There's no need for that check if we have this.type != 'radio' which I believe is the premise of the custom Element.Event.change to begin with. We were fixing the change event for radios.

Also, I prefer this.type != 'radio' vs event.type == 'propertychange' since the former is more readable.

@DimitarChristoff

DimitarChristoff Jan 18, 2012

Member

i am happy with above, seems to work and checkbox' are fine + it fixes bubbling.

return event.type == 'change' || this.type != 'radio' || (event.event.propertyName == 'checked' && this.checked); - seems faster for other els - input, select etc - when it's a native change there is no need to access type or the event object.

@ibolmo ibolmo added a commit that referenced this pull request Jan 18, 2012

@ibolmo ibolmo Merge pull request #2203 from ibolmo/fix-2170-ie-Element-Event-change…
…-propertychange

Fix 2170 ie element event change propertychange
bc70096

@ibolmo ibolmo merged commit bc70096 into mootools:master Jan 18, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment