简体   繁体   English

Javascript mouseover元素闪烁和未捕获的TypeError

[英]Javascript mouseover Element Flickers & Uncaught TypeError

I am trying to use javaScript mouseover and mousout function to get elements from the DOM. 我正在尝试使用javaScript mouseover和mousout函数从DOM中获取元素。 sourced child elements from that event.target and add styling to the childNode that matches the specified class name. 从该event.target中获取子元素,并向与指定类名匹配的childNode添加样式。

Issue that are occurring: 正在发生的问题:

Error: Uncaught TypeError: Cannot read property 'style' of undefined 错误: 未被捕获的TypeError:无法读取未定义的属性“样式”

Displayed class flickers. 显示的类闪烁。 when mouse is moved even with in the mouse Over current DOM element. 甚至在鼠标悬停在当前DOM元素上时移动鼠标时。

I've tried to get elements by tag name and childNodes filtered through for statemant to apply css, but still issue's 我试图通过标记名称和childNodes来过滤元素,以使statemant应用css,但是仍然发出

Its probably an easy fix but am baffled. 它可能是一个简单的解决方法,但令人困惑。

Any assistance would be great. 任何帮助都会很棒。

The HTML 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>

THE CSS 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;
}

THE JS 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();
}

Suggested solution 建议的解决方案

I think that, unless there's other logic not described in the question, the entire JavaScript section can be replaced by the following CSS declaration: 我认为,除非问题中没有描述其他逻辑,否则整个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;
}

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

You can also play around with visibility: hidden; 您还可以在visibility: hidden;玩转visibility: hidden; and visibility: visible; visibility: visible;

Reason of TypeError TypeError的原因

The event.target references an element the cursor is pointing to. event.target引用光标指向的元素。 Suppose you add the event listener to your <li> that has the following HTML structure... 假设您将事件侦听器添加到具有以下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>

Now when you hover the mouse over <li> contents, the event.target could point, for example, to <div class="lb-title">Label List 1</div> which doesn't have any elements with lb-a-icon class. 现在,当您将鼠标悬停在<li>内容上时, event.target可能指向例如<div class="lb-title">Label List 1</div> ,其中没有任何带有lb-a-icon类。 Attempting to get those non-existing elements results in undefined which, obviously, has no style property and thus an error is thrown. 尝试获取那些不存在的元素会导致undefined ,这显然不具有style属性,因此会引发错误。

To solve the issue you can use this (but not in IE6-8!), which references the element to which the event listener is added. 要解决此问题,可以使用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 advice JavaScript建议

If you want to stick with JavaScript, instead of: 如果您要坚持使用JavaScript,请改为:

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

It's much better to write: 最好写:

window.addEventListener('load', add_DOM_listeners);

Doing it this way, you won't have the overhead of creating an additional function. 这样,您将无需创建其他功能。 You will also avoid inadvertently overriding any other onload listener present on your page. 您还将避免无意中覆盖页面上存在的任何其他onload侦听器。

Also, your Add_DOM_listeners function can be reduced to the following: 另外,您的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);
    }
}

Compatibility 兼容性

For IE6-8, of course, you'll need attachEvent and window.event.srcElement . 当然,对于IE6-8,您将需要attachEventwindow.event.srcElement

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM