mootools 1.4.2 和 angular 1.3 在 ie8 中一起玩得很好
mootools 1.4.2 and angular 1.3 playing nicely together in ie8
我有一个 angularjs 1.3 的 shimmed 和 polyfilled 版本,可以在 ie8 上完美运行。不幸的是,当页面上包含 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
扩展本机类型被认为是非常不可靠的,因为原型只是部分公开并且某些东西没有从它继承/行为不当。
http://perfectionkills.com/whats-wrong-with-extending-the-dom/
在这种情况下,MooTools 所做的不是解决所有不遵守正确原型链的边缘案例的怪癖(并且因为 IE6/7 之前)是复制元素原型通过 $
选择器传递 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
等等时出错,你在哪里画线?
我有一个 angularjs 1.3 的 shimmed 和 polyfilled 版本,可以在 ie8 上完美运行。不幸的是,当页面上包含 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
扩展本机类型被认为是非常不可靠的,因为原型只是部分公开并且某些东西没有从它继承/行为不当。
http://perfectionkills.com/whats-wrong-with-extending-the-dom/
在这种情况下,MooTools 所做的不是解决所有不遵守正确原型链的边缘案例的怪癖(并且因为 IE6/7 之前)是复制元素原型通过 $
选择器传递 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
等等时出错,你在哪里画线?