Created
September 17, 2011 04:54
-
-
Save lsmith/1223638 to your computer and use it in GitHub Desktop.
A fragile workaround to IE event facades calculating pageX/Y, possibly triggering a premature reflow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| You probably shouldn't use this. It relies on no other code on the page setting the | |
| document.(documentElement/body).onscroll property. If other code is on the page before | |
| this patch is executed, it will be clobbered. If after this patch is executed, all | |
| e.pageX/Y values will be wrong in IE 6-8 if the window is scrolled. | |
| Every major library handles IE's e.pageX/Y deficiency the same way today. Yes, it might | |
| cause a reflow, but the 90%+ case will be that the document's scrollTop/Left properties | |
| are accessed, but no reflow is triggered. DOM access sucks and all, but it's incredibly | |
| unlikely this will show up on your performance profiling. | |
| There's more risk in including this than in not including it, IMHO. Full details at | |
| http://yuilibrary.com/projects/yui3/ticket/2531101 | |
| You've been warned. | |
| */ | |
| YUI.add('ie-pagex-patch', function (Y) { | |
| var doc = Y.config.doc, | |
| imp = doc.implementation, | |
| scrollEl = doc.compatMode === "CSS1Compat" ? "documentElement" : "body", | |
| _docScroll = YUI.namespace('Env.evt._docScroll'), | |
| proto = Y.DOMEventFacade.prototype, | |
| resolve = Y.DOM2EventFacade.resolve, | |
| buttonMap = { | |
| 0: 1, // left click | |
| 4: 2, // middle click | |
| 2: 3 // right click | |
| }; | |
| function updateDocScroll() { | |
| var scroller = doc[scrollEl]; | |
| _docScroll.top = scroller.scrollTop; | |
| _docScroll.left = scroller.scrollLeft; | |
| } | |
| if (imp && (!imp.hasFeature('Events', '2.0'))) { | |
| // lazyEventFacade config uses a different IE facade | |
| if (Y.DOMEventFacade._lazyProperties) { | |
| delete Y.DOMEventFacade._lazyProperties.pageX; | |
| delete Y.DOMEventFacade._lazyProperties.pageY; | |
| proto.init = function () { | |
| var e = this._event, | |
| overrides = this._wrapper.overrides, | |
| define = Y.DomEventFacade._define, | |
| lazyProperties = Y.DomEventFacade._lazyProperties, | |
| prop; | |
| this.altKey = e.altKey; | |
| this.ctrlKey = e.ctrlKey; | |
| this.metaKey = e.metaKey; | |
| this.shiftKey = e.shiftKey; | |
| this.type = (overrides && overrides.type) || e.type; | |
| this.clientX = e.clientX; | |
| this.clientY = e.clientY; | |
| this.pageX = e.pageX || (e.clientX + (_docScroll.left || 0)); | |
| this.pageY = e.pageY || (e.clientY + (_docScroll.top || 0)); | |
| for (prop in lazyProperties) { | |
| if (lazyProperties.hasOwnProperty(prop)) { | |
| define(this, prop, lazyProperties[prop]); | |
| } | |
| } | |
| if (this._touch) { | |
| this._touch(e, this._currentTarget, this._wrapper); | |
| } | |
| }; | |
| } else { | |
| proto.init = function () { | |
| Y.DOMEventFacade.superclass.init.apply(this, arguments); | |
| var e = this._event, | |
| t; | |
| this.target = resolve(e.srcElement); | |
| this.pageX = e.pageX || (e.clientX + (_docScroll.left || 0)); | |
| this.pageY = e.pageY || (e.clientY + (_docScroll.top || 0)); | |
| if (e.type == "mouseout") { | |
| t = e.toElement; | |
| } else if (e.type == "mouseover") { | |
| t = e.fromElement; | |
| } | |
| this.relatedTarget = resolve(t || e.relatedTarget); | |
| if (e.button !== undefined) { | |
| this.which = this.button = buttonMap[e.button] || e.button; | |
| } | |
| }; | |
| } | |
| // Document scroll position is cached globally, so only make this | |
| // subscription once for all instances. | |
| if (!_docScroll.subscribed) { | |
| // Static loaded modules in head need to delay the subscription until | |
| // the body is in the DOM. | |
| if (scrollEl === 'body' && !doc.body) { | |
| Y.on('available', function () { | |
| if (!_docScroll.subscribed) { | |
| // MUST USE DOM0. attachEvent doesn't work | |
| doc[scrollEl].onscroll = updateDocScroll; | |
| _docScroll.subscribed = true; | |
| } | |
| }, 'body'); | |
| } else { | |
| // MUST USE DOM0. attachEvent doesn't work | |
| doc[scrollEl].onscroll = updateDocScroll; | |
| _docScroll.subscribed = true; | |
| }; | |
| } | |
| } | |
| }, 'YMMV', { requires: ['event-dom-ie'] }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment