Oscar Godson
Oscar Godson

Reputation: 32716

addEvent giving null event object

I'm trying to get IE8 support in a project of mine and having a tough time converting addEventListener to addEvent (from: http://ejohn.org/projects/flexible-javascript-events/)

So, with his code I have an event setup like (source here):

_addEvent(eventableIframes[i], 'mousemove', function (e) {
  utilBarHandler(e);
});

However, when it gets to utilBarHandler, "e" is null and IE8 gives me an "object required" error here on line 783. I'm assuming the object required is the event object since its literally just null when I log out e at the top of the function.

Also, this happens for every event in that loop that requires the event object such as shortcutHandler and shortcutUpHandler.

Update: just in case people are missing it, this post has a bunch of links that highlight specific lines.

Upvotes: 1

Views: 3089

Answers (2)

Oscar Godson
Oscar Godson

Reputation: 32716

The quick and dirty fix that @jfriend00 suggested, e = e || window.event, was 99% the way there but I was still having issues. After more fiddling I found the answer. I didn't want window.event because it was an iframe. Instead I wanted iframeElement.contentWindow. Adding it into my callbacks like this did the trick:

_addEvent(eventableIframes[i], 'mousemove', function (e) {
  // self.iframeElement == <iframe>
  e = e || self.iframeElement.contentWindow;
  utilBarHandler(e);
});

Upvotes: 0

jfriend00
jfriend00

Reputation: 707258

Not all versions of IE pass the event as an argument. It's in window.event. You can add this to your _addEvent shim or to your event handler:

 e = e || window.event

as in:

_addEvent(eventableIframes[i], 'mousemove', function (e) {
      e = e || window.event;
      utilBarHandler(e);
});

which will work in either IE or others.

Here's two flavors of a cross browser event handling that makes sure both the event and the this pointer are set appropriately in IE:

// add event cross browser
function addEvent(elem, event, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
    } else {
        elem.attachEvent("on" + event, function() {
            // set the this pointer same as addEventListener when fn is called
            return(fn.call(elem, window.event));   
        });
    }
}


// refined add event cross browser
function addEvent(elem, event, fn) {
    // avoid memory overhead of new anonymous functions for every event handler that's installed
    // by using local functions
    function listenHandler(e) {
        var ret = fn.apply(this, arguments);
        if (ret === false) {
            e.stopPropagation();
            e.preventDefault();
        }
        return(ret);
    }

    function attachHandler() {
        // set the this pointer same as addEventListener when fn is called
        // and make sure the event is passed to the fn also so that works the same too
        var ret = fn.call(elem, window.event);   
        if (ret === false) {
            window.event.returnValue = false;
            window.event.cancelBubble = true;
        }
        return(ret);
    }

    if (elem.addEventListener) {
        elem.addEventListener(event, listenHandler, false);
    } else {
        elem.attachEvent("on" + event, attachHandler);
    }
}

Upvotes: 2

Related Questions