سؤال

I have a WebForms page which is including MicrosoftAjax.debug.js (4.1.7.123) as a script resource:

// Name:        MicrosoftAjax.debug.js
// Assembly:    AjaxControlToolkit
// Version:     4.1.7.123
// FileVersion: 4.1.7.0123
// (c) 2010 CodePlex Foundation

On load this script self invokes, eventually calling this function:

var attachEvent = !!document.attachEvent;

...

function listenOnce(target, name, ieName, callback, isReadyState, isScript) {
    function onEvent() {
        if (!attachEvent || !isReadyState || /loaded|complete/.test(target.readyState)) {
            if (attachEvent) {
                target.detachEvent(ieName || ("on" + name), onEvent);
            }
            else {
                target.removeEventListener(name, onEvent, false);
                if (isScript) {
                    target.removeEventListener("error", onEvent, false);
                }
            }
            callback.apply(target);
            target = null;
        }
    }
    if (attachEvent) {
        target.attachEvent(ieName || ("on" + name), onEvent);
    }
    else {
        if (target.addEventListener) {
        target.addEventListener(name, onEvent, false);
        }
        if (isScript) {
            target.addEventListener("error", onEvent, false);
        }
    }
}

The problem is that in Chrome I'm getting the following Javascript error:

Uncaught TypeError: Object [object global] has no method 'attachEvent'

On the following line:

target.attachEvent(ieName || ("on" + name), onEvent);

Attaching the debugger, target is the window object, which as you'd expect does not have the attachEvent() method in Chrome.

document.attachEvent() is the following function:

function (sType, fHandler) {
        var shortTypeName = sType.replace(/on/, "");
        fHandler._ieEmuEventHandler = function (e) {
            window.event = e;
            return fHandler();
        };
        this.addEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
    }

Is this a bug in the Microsoft Ajax script? Chrome? Or is it being caused by some condition on the page?

Either way, how can I resolve it?

هل كانت مفيدة؟

المحلول

You shouldn't reassign document.attachEvent to begin with, so you may want to get rid of that. attachEvent is true because of that. That doesn't mean that target.attachEvent exists, though. It seems like you should check if (!!target.attachEvent) before calling it on target instead of just looking at your attachEvent variable.

نصائح أخرى

I'll leave this question up in case anyone else runs into the same problem. However the error was being caused by a legacy Javascript library reassigning the document.attachEvent() method.

This was the offending code:

function emulateAttachEvent() {
    HTMLDocument.prototype.attachEvent = 
    HTMLElement.prototype.attachEvent = function (sType, fHandler) {
        var shortTypeName = sType.replace(/on/, "");
        fHandler._ieEmuEventHandler = function (e) {
            window.event = e;
            return fHandler();
        };
        this.addEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
    };
    HTMLDocument.prototype.detachEvent = 
    HTMLElement.prototype.detachEvent = function (sType, fHandler) {
        var shortTypeName = sType.replace(/on/, "");
        if (typeof fHandler._ieEmuEventHandler == "function")
            this.removeEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
        else
            this.removeEventListener(shortTypeName, fHandler, true);
    };
}

Fortunately, I was able to remove the legacy library. However this won't help if you have a genuine case for reassigning the document.attachEvent() method, in which case you will need to come up with an alternative solution.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top