JS li标签onclick不适用于IE8

Sud*_*era 3 javascript cross-browser addeventlistener internet-explorer-8

我正在使用下面的JS,但是li onclick不适用于IE8浏览器.

jsfiddle链接:

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>
Run Code Online (Sandbox Code Playgroud)

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

请建议

T.J*_*der 6

IE8和早期版本没有addEventListener,但它们确实有其非标准的前身,attachEvent.他们不太一样.

这是一个"钩子事件"功能,它使用了以下功能:

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.";
})();
Run Code Online (Sandbox Code Playgroud)

然后你在你的例子中使用它:

hookEvent(document.getElementById("hd_vertical"), "click", function(e) {
    // ...
});
Run Code Online (Sandbox Code Playgroud)

请注意它如何在浏览器上使用事件对象提供缺失preventDefaultstopPropagation函数,attachEvent并确保this在处理程序调用中使用它是什么样的addEventListener.

上面没有做的事件规范化的各个方面:

  1. 它不保证处理程序的运行attachEvent顺序(它们的顺序相反addEventListener)

  2. 它不会处理e.whiche.keyCode此类似的问题

......当然,我没有提供分离事件功能.:-)对于类似的东西,看看使用像jQuery,YUI,Closure其他几个库的库.


旁注:正如阿德内诺在评论中指出的那样,IE8也不支持getElementsByClassName.但它支持querySelectorAllquerySelector,所以更改:

var _url = document.getElementsByClassName(id)[1].getAttribute('href');
Run Code Online (Sandbox Code Playgroud)

var _url = document.querySelectorAll("." + id)[1].getAttribute('href');
Run Code Online (Sandbox Code Playgroud)

请注意,这将尝试获取与选择器匹配的第二个元素.[1]是列表中的第二个条目,而不是第一个条目[0].如果你的意思是第一个,你可以使用querySelector,它只返回第一个匹配:

var _url = document.querySelector("." + id).getAttribute('href');
Run Code Online (Sandbox Code Playgroud)