Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS li tag onclick not working on IE8

Am using Below JS,but li onclick is not working on IE8 browser.

jsfiddle link :

http://jsfiddle.net/sudheera/DUZ3B/14/

HTML

<div class="primaryNav fl">
<ul id="hd_vertical" class="productNav">

<li id="hd_test" class="flight">
<span class="navIcon flightIcon hd_test">Test</span>
<a class="hd_test" href="http://validator.w3.org/">Flights</a>
</li>

<li id="hd_test1" class="bus">
<span class="navIcon busIcon hd_test1">Test</span>
<a class="hd_test1" href="http://www.w3schools.com/">Buses</a>
</li>

</ul>
</div>

JS

var changeLocation = function(id) {
  var _url = document.getElementsByClassName(id)[1].getAttribute('href');
  location.href = _url;   
}

document.getElementById("hd_vertical").addEventListener("click",function(e) {
        if(e.target.nodeName == "LI") { 
            var _anchor = e.target.id;
            changeLocation(_anchor);
        } else if(e.target.nodeName == "SPAN") {
            var span = e.target;
            var li = span.parentNode;
            var _anchor = li.id;   
            changeLocation(_anchor);
    }
});

please suggest

like image 746
Sudheera Avatar asked Mar 19 '23 13:03

Sudheera


1 Answers

IE8 and earlier don't have addEventListener, but they do have its non-standard predecessor, attachEvent. They're not quite the same.

Here's a "hook this event" function that uses what's available:

var hookEvent = (function() {
    var div;

    // The function we use on standard-compliant browsers
    function standardHookEvent(element, eventName, handler) {
        element.addEventListener(eventName, handler, false);
        return element;
    }

    // The function we use on browsers with the previous Microsoft-specific mechanism
    function oldIEHookEvent(element, eventName, handler) {
        element.attachEvent("on" + eventName, function(e) {
            e = e || window.event;
            e.preventDefault = oldIEPreventDefault;
            e.stopPropagation = oldIEStopPropagation;
            handler.call(element, e);
        });
        return element;
    }

    // Polyfill for preventDefault on old IE
    function oldIEPreventDefault() {
        this.returnValue = false;
    }

    // Polyfill for stopPropagation on old IE
    function oldIEStopPropagation() {
        this.cancelBubble = true;
    }

    // Return the appropriate function; we don't rely on document.body
    // here just in case someone wants to use this within the head
    div = document.createElement('div');
    if (div.addEventListener) {
        div = undefined;
        return standardHookEvent;
    }
    if (div.attachEvent) {
        div = undefined;
        return oldIEHookEvent;
    }
    throw "Neither modern event mechanism (addEventListener nor attachEvent) is supported by this browser.";
})();

Then you'd use it like this in your example:

hookEvent(document.getElementById("hd_vertical"), "click", function(e) {
    // ...
});

Note how it provides the missing preventDefault and stopPropagation functions on the event object on browsers using attachEvent and ensures that this within the handler call is what it would be if you were using addEventListener.

There are various aspects of event normalization that the above does not do:

  1. It doesn't guarantee the order in which the handlers will run (attachEvent does them in the opposite order to addEventListener)

  2. It doesn't handle issues around e.which vs. e.keyCode and such

...and of course, I haven't provided a detach event function. :-) For things like that, look at using a library like jQuery, YUI, Closure, or any of several others.


Side note: As adeneo pointed out in a comment on the question, IE8 also doesn't support getElementsByClassName. But it does support querySelectorAll and querySelector, so change:

var _url = document.getElementsByClassName(id)[1].getAttribute('href');

to

var _url = document.querySelectorAll("." + id)[1].getAttribute('href');

Note that that will try to get the second element matching the selector. [1] is the second entry in the list, not the first, which would be [0]. If you meant the first, you can use querySelector, which returns just the first match:

var _url = document.querySelector("." + id).getAttribute('href');
like image 68
5 revs Avatar answered Apr 01 '23 04:04

5 revs