/*----------------------------------------------------------------------------*- Function: $event, $event.add Params: domEvent - Name of the event to attach to. source (optional) - Element to attach to, default 'document'. func - Function to call on the event. Return: - Notes: Attach a function to an event in a cross-browser way. Overrides the IE thing of passing 'this' as the window object instead of the object that fired the event. Unfortunately this breaks removeEvent. -*----------------------------------------------------------------------------*/ $event = function (domEvent, source, func) { if (window.addEventListener) { $event = $event._addEventListener; } else { /*if (window.attachEvent) { } else {*/ $event = $event._eventHandler; /*}*/ } return $event(domEvent, source, func); } $event.add = $event; /*----------------------------------------------------------------------------*- Function: $event._eventHandler Params: domEvent - Name of the event to attach to. source (optional) - Element to attach to, default 'document'. func - Function to call on the event. Return: - Notes: $event implementation in browsers with no addEventListener. Detects if an event has already been manually applied to an element using HTML based listeners (i.e. onevent='code') and preserves them, calling them first as with addEventListener. -*----------------------------------------------------------------------------*/ $event._eventHandler = function (domEvent, source, func) { if (!func) { if (!source) { return; } func = source; source = document; } // Check if an event has been applied to this already domEvent = domEvent.substring(0, 2) == 'on' ? domEvent : 'on' + domEvent; var ev = source[domEvent]; if (ev) { // Already has something registered if (!ev._has$event) { // Has a function, but not one of ours var old = ev; ev = function (event) { event = event || window.event; var c = ev._calls, i = -1, j = c.length, oldStop = event.stopPropagation, ret = false; event.cancelBubble = false; event.stopPropagation = function () { event.cancelBubble = true; } if (old.call(source, event)) { ret = true; } while (++i < j) { if (c[i]) { if (c[i].call(source, event)) { ret = true; } } } if (oldStop && event.cancelBubble) { oldStop(); } return ret; } ev._calls = []; } } else { // Nothing registered ev = function (event) { event = event || window.event; var c = ev._calls, i = -1, j = c.length, oldStop = event.stopPropagation, ret = false; event.cancelBubble = false; event.stopPropagation = function () { event.cancelBubble = true; } while (++i < j) { if (c[i]) { if (c[i].call(source, event)) { ret = true; } } } if (oldStop && event.cancelBubble) { oldStop(); } return ret; } ev._calls = []; } ev._calls[ev._calls.length] = func; ev._has$event = true; source[domEvent] = ev; } /*----------------------------------------------------------------------------*- Function: $event._addEventListener Params: domEvent - Name of the event to attach to. source (optional) - Element to attach to, default 'document'. func - Function to call on the event. Return: - Notes: $event implementation in browsers with addEventListener. -*----------------------------------------------------------------------------*/ $event._addEventListener = function (domEvent, source, func) { if (!func) { if (!source) { return; } func = source; source = document; } var nf; if (!func._$_event_$_handler_$_) { func._$_event_$_handler_$_ = []; } if (!func._$_event_$_handler_$_[domEvent]) { // Create an annonymous function to correctly pass the variables nf = function (event) { event = event || window.event; if (!func.call(source, event)) { // Add handling for returning false if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } return false; } return true; } func._$_event_$_handler_$_[domEvent] = nf; } else { nf = func._$_event_$_handler_$_[domEvent]; } // Strip 'on' domEvent = domEvent.substring(0, 2) == 'on' ? domEvent.substring(2) : domEvent; source.addEventListener(domEvent, nf, false); }