javascript - mootools 1.4.2 和 angular 1.3 在 ie8 中一起玩得很好

标签 javascript angularjs internet-explorer-8 mootools

我有一个在 ie8 上完美运行的 angularjs 1.3 的 shimmed 和 polyfilled 版本。不幸的是,当页面上包含 mootools 时,会出现很多冲突。除了一个,我已经设法处理了所有的问题,其中添加/删除 EventListener 和 dispatchEvent 到 Window.prototype、HTMLDocument.prototype 和 Element.prototype。它检查是否加载了 mootools,如果加载了,则以不同方式添加它们。

!window.addEventListener && (function (WindowPrototype, DocumentPrototype, ElementPrototype, addEventListener, removeEventListener, dispatchEvent, registry) {
        var addEventListenerFn = function(type, listener) {
            var target = this;
            registry.unshift([target, type, listener,
                function (event) {
                    event.currentTarget = target;
                    event.preventDefault = function () {
                        event.returnValue = false;
                    };
                    event.stopPropagation = function () {
                        event.cancelBubble = true;
                    };
                    event.target = event.srcElement || target;
                    listener.call(target, event);
                }]);

            // http://msdn.microsoft.com/en-us/library/ie/hh180173%28v=vs.85%29.aspx
            if (type === 'load' && this.tagName && this.tagName === 'SCRIPT') {
                var reg = registry[0][3];
                this.onreadystatechange = function (event) {
                    if (this.readyState === "loaded" || this.readyState === "complete") {
                        reg.call(this, {
                            type: "load"
                        });
                    }
                }
            } else {
                this.attachEvent('on' + type, registry[0][3]);
            }
        };

        var removeEventListenerFn = function(type, listener) {
            for (var index = 0, register; register = registry[index]; ++index) {
                if (register[0] == this && register[1] == type && register[2] == listener) {
                    if (type === 'load' && this.tagName && this.tagName === 'SCRIPT') {
                        this.onreadystatechange = null;
                    }

                    return this.detachEvent('on' + type, registry.splice(index, 1)[0][3]);
                }
            }
        };

        var dispatchEventFn = function(eventObject) {
            return this.fireEvent('on' + eventObject.type, eventObject);
        };

        if(Element.prototype.$constructor && typeof Element.prototype.$constructor === 'function') {
            Element.implement(addEventListener, addEventListenerFn);
            Element.implement(removeEventListener, removeEventListenerFn);
            Element.implement(dispatchEvent, dispatchEventFn);
            Window.implement(addEventListener, addEventListenerFn);
            Window.implement(removeEventListener, removeEventListenerFn);
            Window.implement(dispatchEvent, dispatchEventFn);
        } else {
            WindowPrototype[addEventListener] = ElementPrototype[addEventListener] = addEventListenerFn;
            WindowPrototype[removeEventListener] = ElementPrototype[removeEventListener] = removeEventListenerFn;
            WindowPrototype[dispatchEvent] = ElementPrototype[dispatchEvent] = dispatchEventFn;
        }
        DocumentPrototype[addEventListener] = addEventListenerFn;
        DocumentPrototype[removeEventListener] = removeEventListenerFn;
        DocumentPrototype[dispatchEvent] = dispatchEventFn;
    })(Window.prototype, HTMLDocument.prototype, Element.prototype, 'addEventListener', 'removeEventListener', 'dispatchEvent', []);

这已经解决了我所有的错误,除了一个。当在 Angular 中调用此函数时,当页面上有 mootools 且元素是表单时,addEventListener 未定义。

addEventListenerFn = function(element, type, fn) {
      element.addEventListener(type, fn, false);
    }

具体来说,这个函数是像这样从 angulars formDirective 调用的

addEventListenerFn(formElement[0], 'submit', handleFormSubmission);

知道为什么表单元素仍然没有可用的 addEventListener 函数吗?

最佳答案

在 IE8 中通过 Element.prototype 扩展 native 类型被认为是非常不可靠的,因为原型(prototype)只是部分公开并且某些东西不是从它继承的/行为不端。

http://perfectionkills.com/whats-wrong-with-extending-the-dom/

在这种情况下,MooTools 所做的不是解决所有不遵守正确原型(prototype)链的边缘案例的怪癖(并且因为在此之前的 IE6/7),而是在对象上复制元素原型(prototype)通过 $ 选择器传递 DOM 节点。

这并不理想,因为。

var foo = document.id('foo'); 
// all known methods from Element.prototype are copied on foo, which now hasOwnProperty for them
Element.prototype.bar = function(){};
foo.bar(); // no own property bar, going up the chain may fail dependent on nodeType

无论如何,除此之外 - 您可以通过将您的方法从 Element.prototype 复制到特殊的 HTMLFormElement.prototype 来解决您的特定问题 - 您可以使用任何其他元素构造函数可能会发现不同。

它不可扩展,然后您可能会在说 HTMLInputElement 等时遇到错误,您在哪里画线?

关于javascript - mootools 1.4.2 和 angular 1.3 在 ie8 中一起玩得很好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29276627/

相关文章:

javascript - 如何在 Angular JS Factory 中定义多个函数并在另一个函数中调用一个函数

javascript - $http post 调用 OPTIONS 未发布?

javascript - event.returnvalue=false 在 Firefox 中不起作用?

javascript - this 指向 IE8 中的窗口

javascript - AJAX 调用后无法禁用 javascript 中的按钮

javascript - 30 秒后显示 Jquery UI 对话框

javascript - 如何通过 FileReader 检查上传图片的类型?

javascript - 为什么这段代码会产生无限循环?

javascript - 传输两个带 Angular 数组

javascript - SVG 鼠标事件在 Firefox4 中有效,但在 IE8 中无效