jQuery.event.fix (v17)

Revision 17 of this benchmark created on


Preparation HTML

<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
// from http://bitovi.com/blog/2012/04/faster-$-event-fix.html
(function($, undefined) {
    
    if (!Object.defineProperties) return;
        
    function set(obj, prop, val) {
        if (val !== undefined) {
            Object.defineProperty(obj, prop, {
                value: val
            });
        }
        return val;
    };

    var special = {
        pageX: function(original) {
            debugger;
            var eventDoc = this.target.ownerDocument || document;
            var doc = eventDoc.documentElement;
            var body = eventDoc.body;
            return original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
        },
        pageY: function(original) {
            var eventDoc = this.target.ownerDocument || document;
            var doc = eventDoc.documentElement;
            var body = eventDoc.body;
            return original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
        },
        relatedTarget: function(original) {
            if (!original) return;
            return original.fromElement === this.target ? original.toElement : original.fromElement;
        },
        metaKey: function(originalEvent) {
            return originalEvent.ctrlKey;
        },
        which: function(original) {
            return original.charCode != null ? original.charCode : original.keyCode;
        }
    };
        
    $.each($.event.keyHooks.props.concat($.event.mouseHooks.props).concat($.event.props), function(i, prop) {
        if (prop !== "target") {
            Object.defineProperty($.Event.prototype, prop, {
                get: function() {
                    if (this['_' + prop] !== undefined) 
                        return this['_' + prop];
                    // get the original value, undefined when there is no original event
                    var originalValue = this.originalEvent && this.originalEvent[prop];
                    // if we have a special function and no value
                    var value = special[prop] && originalValue === undefined ?
                        // call the special function
                        special[prop].call(this, this.originalEvent) :
                        // use the original value
                        originalValue;
                    this[prop] = value;
                    return value;
                },
                set: function(newValue) {
                    this['_' + prop] = newValue;
                }
            });
        }
    });

    $.event.fastFix = function(event) {
        if (event[$.expando]) {
            return event;
        }
        // Create a $ event with at minimum a target and type set
        var originalEvent = event;

        event = $.Event(originalEvent);
        event.target = originalEvent.target;

        // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
        if (!event.target) {
            event.target = originalEvent.srcElement || (event.currentTarget && (event.currentTarget.ownerDocument || event.currentTarget)) || document;
        }

        // Target should not be a text node (#504, Safari)
        if (event.target.nodeType === 3) {
            event.target = event.target.parentNode;
        }

        return event;
    };

}(jQuery));

var makeClick = function(){

	
	var event;

	try {
		event = document.createEvent('MouseEvents');
		event.initMouseEvent("click", true, true, null, null, 100, 100, 100, 100, false, false, false, false, 0, null);
	} catch (e) {
		try {
			event = document.createEvent("Events");
		} catch (e2) {
			event = document.createEvent("UIEvents");
		} finally {
			event.initEvent("click", true, true);
		}
	}
	//element.dispatchEvent(event)
	return event;
}
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
existing fix
var ev = $.event.fix( makeClick() )
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ready
fast fix
var ev = $.event.fastFix( makeClick() )
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ev.pageX
ev.pageY
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.