问题
I am trying to add listener event for mouse down on a list of elements. The code works for chrome, but not for IE
document.getElementsByClassName('select2-result-selectable').forEach(function(item){
item.addEventListener('mousedown', function(e) { console.log( "User clicked on 'foo.'" );
e.preventDefault();});
})
This works on chrome, but not on IE 11.
I tried the following code as well.
document.getElementsByClassName('select2-result-selectable').forEach(function(item){
if (item.addEventListener){
item.addEventListener('mousedown',function(e){ console.log(e); e.preventDefault();
console.log( "User clicked on 'foo.'" );})
} else if (item.attachEvent){
item.attachEvent('mousedown',function(e){ console.log(e); e.preventDefault();
console.log( "User clicked on 'foo.'" );})
}
})
But this was again futile, it works for chrome, but not on IE. Any suggestions?
回答1:
I suspect you'll find that it's not addEventListener
that's the problem, although your second code block would have needed onmousedown
rather than just mousedown
in the attachEvent
call (Microsoft used the "on" prefix on event names). But IE11 has addEventListener
anyway, it would only be missing if IE11 were hobbling itself (which you can fix by adding the X-UA-Compatible
header to your page in head
):
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
...and turning off "compatibility view" for Intranet sites if necessary.
But, I think the problem is that you're trying to use forEach
on an HTMLCollection
. The return value of getElementsByClassName
isn't an array, it's an HTMLCollection
. The spec doesn't require HTMLCollection
to have forEach
(Chrome adds it as an extension). forEach
is defined for NodeList
(the type returned by querySelectorAll
), but not HTMLCollection
, and that addition is relatively new and not supported in IE.
So to use forEach
, you'd do:
Array.prototype.forEach.call(document.getElementsByClassName('select2-result-selectable', function(item) {
// ...
});
Alternatively, you can polyfill forEach
on HTMLCollection
easily, though, as shown in my answer here. Here's a loop doing both NodeList
(if necessary) and HTMLCollection
(if necessary), and polyfilling forEach
(if necessary) and (for browsers that have it) Symbol.iterator
(IE11 doesn't, though, you may choose to leave that code off although it's harmless to leave it):
var ctors = [typeof NodeList !== "undefined" && NodeList, typeof HTMLCollection !== "undefined" && HTMLCollection];
for (var n = 0; n < ctors.length; ++n) {
var ctor = ctors[n];
if (ctor && ctor.prototype && !ctor.prototype.forEach) {
// (Yes, there's really no need for `Object.defineProperty` when doing the `forEach`)
ctor.prototype.forEach = Array.prototype.forEach;
if (typeof Symbol !== "undefined" && Symbol.iterator && !ctor.prototype[Symbol.iterator]) {
Object.defineProperty(ctor.prototype, Symbol.iterator, {
value: Array.prototype[Symbol.itereator],
writable: true,
configurable: true
});
}
}
}
Then your original code using forEach
on HTMLCollection
would work.
回答2:
Your problem is using .foreach. It isn't supported in IE11
Change it for a regular for loop.
var myclasses = document.getElementsByClassName('select2-result-selectable')
for (var i = 0; i < myclasses.length; i++) {
array[i].addEventListener('mousedown', function(e) { console.log( "User clicked on 'foo.'");
}
Or you can use other language processors like babel to fix it and build your sites, depending on what your stack looks like.
This is untested as I don't have access to ie11 at the moment
回答3:
you can have a utility like below
function addHandler (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
that can work on all browsers, In this case you should use like
addHandler(item, "mousedown", function() {....} )
来源:https://stackoverflow.com/questions/59088141/internet-explorer-11-issues-addeventlistener-not-working