Javascript鼠标悬停元素闪烁;未捕获的类型错误

Javascript mouseover Element Flickers & Uncaught TypeError

本文关键字:类型 错误 鼠标 悬停 元素 闪烁 Javascript      更新时间:2023-09-26

我正在尝试使用javaScript mouseover和mouseout函数从DOM中获取元素。源于该事件的子元素。target,并将样式添加到与指定类名匹配的childNode。

正在发生的问题:

错误:未捕获类型错误:无法读取未定义的属性"style">

显示的类闪烁。当鼠标移动时(即使在鼠标中(Over current DOM元素。

我已经尝试过通过标记名和子节点过滤statemant的元素来应用css,但仍然存在问题的

这可能是一个简单的解决方案,但我感到困惑。

任何帮助都将是伟大的。

HTML

<!doctype HTML>
<html>
<head>
    <title>Gmail Label List</title>
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="func.js"></script>
</head>
<body>
    <div id="sideBar-left">
        <div class="SbInner-body">
            <ul id="label-list">
                <li class="lb_li">
                    <div class="lb-title">Label List 1</div>
                    <div class="lb-a-icon">
                        <img src="chevron_expand.png">
                    </div>
                </li>
                <li class="lb_li">
                    <div class="lb-title">Label List 1</div>
                    <div class="lb-a-icon">
                        <img src="chevron_expand.png">
                    </div>
                </li>
                <li class="lb_li">
                    <div class="lb-title">Label List 1</div>
                    <div class="lb-a-icon">
                        <img src="chevron_expand.png">
                    </div>
                </li>
                <li class="lb_li">
                    <div class="lb-title">Label List 1</div>
                    <div class="lb-a-icon">
                        <img src="chevron_expand.png">
                    </div>
                </li>
            </ul>
        </div>
    </div>
</body>
</html>

CSS

body
{
    background-color: #f0f0f0;
}
div#sideBar-left{
    position:relative;
    float:left;
    width:180px;
}
div.SbInner-body{}
 ul#label-list{
    background-color: #898989;
    width:auto;
    height:auto;
    overflow: hidden;
}
ul#label-list li {
    list-style: none;
    cursor:pointer;
    background-color: #989898;
    width:100%;
    height:auto;
    overflow: hidden;
}
div.lb-title{
    position:relative;
    float:left;
    height:auto;
    width:auto;
    padding:5px;
}
div.lb-a-icon{
    position:relative;
    float:right;
    height:15px;
    padding:10px;
    width:16px;
    border:1px solid black;
    display: none;
}

JS

function showLabel_icon(element)
{
        element.target.getElementsByClassName('lb-a-icon')[0].style.display="block";
}
function closeLabel_icon(element)
{
        element.target.getElementsByClassName('lb-a-icon')[0].style.display="none";
}
//[ Listeners]
function Add_DOM_listeners(){
    if(window.addEventListener){
        var lb = document.getElementById('label-list')
        var lb_child = lb.getElementsByClassName('lb_li');
        for(var i = 0; i < lb_child.length; i++){
            lb_child[i].addEventListener('mouseover',showLabel_icon, false);
        }// end for

        var lc = document.getElementById('label-list')
        var lc_child = lc.getElementsByClassName('lb_li');
        for(var j = 0; j < lc_child.length; j++){
            lc_child[j].addEventListener('mouseout',closeLabel_icon, false);
        }// end for
    }// end if 
}//end function

window.onload = function(){
    Add_DOM_listeners();
}

建议的解决方案

我认为,除非问题中没有描述其他逻辑,否则整个JavaScript部分可以用以下CSS声明代替:

/* By default the icon is not rendered: */
.lb-a-icon {
    display: none;
}
/* When <li> is hovered, its icon child is displayed: */
.lb_li:hover .lb-a-icon {
    display: block;
}

演示:http://jsfiddle.net/CHTKM/

您也可以玩visibility: hidden;visibility: visible;

TypeError的原因

event.target引用了光标所指向的元素。假设您将事件侦听器添加到具有以下HTML结构的<li>中。。。

<li class="lb_li">
    <div class="lb-title">Label List 1</div>
    <div class="lb-a-icon">
        <img src="chevron_expand.png">
    </div>
</li>

现在,当您将鼠标悬停在<li>内容上时,event.target可以指向(例如(<div class="lb-title">Label List 1</div>,它没有任何lb-a-icon类的元素。尝试获取那些不存在的元素会导致undefined,很明显,它没有style属性,因此会引发错误。

要解决此问题,可以使用this(但不能在IE6-8中使用!(,它引用了添加事件侦听器的元素。

function showLabel_icon() {
    // In this particular case "this" is <li class="lb_li">
    this.getElementsByClassName('lb-a-icon')[0].style.display = 'block';
}

JavaScript建议

如果你想坚持使用JavaScript,而不是:

window.onload = function () {
    Add_DOM_listeners();
}

写要好得多

window.addEventListener('load', add_DOM_listeners);

这样做,您就不会有创建额外函数的开销。您还可以避免无意中覆盖页面上的任何其他onload侦听器。

此外,您的Add_DOM_listeners功能可以简化为以下内容:

function Add_DOM_listeners() {
    var labelList = document.getElementById('label-list'),
        labelChildren = labelList.getElementsByClassName('lb_li'),
        ii = labelChildren.length,
        i;
    for (i = 0; i < ii; i += 1) {
        labelChildren[i].addEventListener('mouseover', showLabel_icon);
        labelChildren[i].addEventListener('mouseout', closeLabel_icon);
    }
}

兼容性

当然,对于IE6-8,您需要attachEventwindow.event.srcElement