0

Here is a script that looks at the links that exist on a page and binds a mousedown event listener to each link. When a mousedown event is triggered it calls a function that creates an alert with the link's href. In IE9+, this works fine, but in IE8, this is undefined.

<html>
<body>
<a href="http://www.example.com">test</a>
<script>
var c=function(){alert(this.href)};
var a=document.getElementsByTagName("a");
for(var b=0; b<a.length; b++) {
    if (a[b].addEventListener) {
        a[b].addEventListener("mousedown",c,false);
    } else {
        a[b].attachEvent("onmousedown",c);
    }
}
</script>
</body>
</html>

I've tried adding this and this.href as arguments to the function, but it doesn't look like those functions accept arguments. Anyone know how I would get this to work?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Evan Appleby
  • 284
  • 4
  • 17
  • Most people would use JQuery indeed like `$("a").on("mousedown",c)` but you probably looking for raw JavaScript solution... Would [closure](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) work for your case? – Alexei Levenkov Sep 04 '14 at 05:01

2 Answers2

3

Try this:

var c = function (e) {
    e = e || event; // if e is not available, use global event object
    var target = e.target || e.srcElement; // some browsers use target to refer to event target, and some srcElement
    alert(target.href);
};

I think IE8 uses a global event object, instead of sending parameter in callback function.

coder
  • 4,458
  • 2
  • 17
  • 23
  • `e.target`/`e.srcElement` is not necessarily the same element as *this* within the listener. – RobG Sep 04 '14 at 06:18
  • @Rob: sorry not clear, but the target will contain href, wouldnt it ? – coder Sep 04 '14 at 07:40
  • 1
    @coder—within the listener, *this* will be the element that has the listener, the *event.target* or *event.srcElement* is the element that initiated the event. So where the element with the listener has child elements, *this* may not be the same as *event.target*. E.g., if the listener is on the A element and it has a child span element, then for a click on the span *this* will reference the A element and *event.target* / *event.srcElement* will reference the span. – RobG Sep 04 '14 at 13:31
1

Unfortunately, in the IE event model, listeners attached using attachEvent do not have their this set to the calling element so it defaults to window (i.e. the global object).

So instead of:

  a[b].attachEvent("onmousedown",c);

you can ensure this is set to the element using:

  a[b].attachEvent("onmousedown",(function(fn, el) {
    return function() {fn.call(el, event)};
  }(c, a[b]));

Look for examples of "addEvent" function, there are many around that fix this issue.

RobG
  • 142,382
  • 31
  • 172
  • 209