html - Javascript mouseover Element Flickers & Uncaught TypeError -
i trying use javascript mouseover , mousout function elements dom. sourced child elements event.target , add styling childnode matches specified class name.
issue occurring:
error: uncaught typeerror: cannot read property 'style' of undefined
displayed class flickers. when mouse moved in mouse on current dom element.
i've tried elements tag name , childnodes filtered through statemant apply css, still issue's
its easy fix baffled.
any assistance great.
the 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
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
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 = 0; < lb_child.length; i++){ lb_child[i].addeventlistener('mouseover',showlabel_icon, false); }// end 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 }// end if }//end function window.onload = function(){ add_dom_listeners(); }
suggested solution
i think that, unless there's other logic not described in question, entire javascript section can replaced following css declaration:
/* default icon not rendered: */ .lb-a-icon { display: none; } /* when <li> hovered, icon child displayed: */ .lb_li:hover .lb-a-icon { display: block; }
demo: http://jsfiddle.net/chtkm/
you can play around visibility: hidden;
, visibility: visible;
reason of typeerror
the event.target
references element cursor pointing to. suppose add event listener <li>
has following html structure...
<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 hover mouse on <li>
contents, event.target
point, example, <div class="lb-title">label list 1</div>
doesn't have elements lb-a-icon
class. attempting non-existing elements results in undefined
which, obviously, has no style
property , error thrown.
to solve issue can use this
(but not in ie6-8!), references element event listener added.
function showlabel_icon() { // in particular case "this" <li class="lb_li"> this.getelementsbyclassname('lb-a-icon')[0].style.display = 'block'; }
javascript advice
if want stick javascript, instead of:
window.onload = function () { add_dom_listeners(); }
it's better write:
window.addeventlistener('load', add_dom_listeners);
doing way, won't have overhead of creating additional function. avoid inadvertently overriding other onload
listener present on page.
also, add_dom_listeners
function can reduced following:
function add_dom_listeners() { var labellist = document.getelementbyid('label-list'), labelchildren = labellist.getelementsbyclassname('lb_li'), ii = labelchildren.length, i; (i = 0; < ii; += 1) { labelchildren[i].addeventlistener('mouseover', showlabel_icon); labelchildren[i].addeventlistener('mouseout', closelabel_icon); } }
compatibility
for ie6-8, of course, you'll need attachevent
, window.event.srcelement
.
Comments
Post a Comment