knowram Posted October 10, 2007 Share Posted October 10, 2007 With help from people on this form I am using the following script to Show or hid sections of my site depending on what links are hit simulating expanding folders in windows explorer. My problem is my site has gotten more complex and now has 20 some of these expanding areas and has become really slow in IE 6. Both firefox and Safari handle it as just like windows explorer. Is there anything I can do to make it work better in IE? Thanks for the help <script type="text/javascript"> document.getElementsByClassName = function(clsName){ var retVal = new Array(); var elements = document.getElementsByTagName("*"); for(var i = 0;i < elements.length;i++){ if(elements[i].className.indexOf(" ") >= 0){ var classes = elements[i].className.split(" "); for(var j = 0;j < classes.length;j++){ if(classes[j] == clsName) retVal.push(elements[i]); } } else if(elements[i].className == clsName) retVal.push(elements[i]); } return retVal; } function showHide(id, clName) { var classes = document.getElementsByClassName(clName); for(var i = 0;i<classes.length;i++){ if(classes[i].id == id){ classes[i].style.display = (classes[i].style.display == 'none')? 'block' : 'none'; } } } </script> Quote Link to comment Share on other sites More sharing options...
emehrkay Posted October 10, 2007 Share Posted October 10, 2007 Two things: A for loop evaluates the three expressions each iteration. So it will check i = 0, classes.length and i++. if classes.length never changes, why evaluate it every iteration? move it outside of the loop. var count = classes.length; for(var i = 0; i < count; .... or you could try a for in loop and remove the evaluations for(x in classes){ if(classes[x].id == id){ ... } } also based on your getElementsByClassName function, it gets all of the elements on the page, and it does it everytime you showHode(); my advice would be to wrap the showHide function in an object, call the getEleByCName once and refer to that var showHide = { eles: '', getEles: function(){ this.eles = document.getElementsByTagName("*"); return this; }, getElesByClass: function(class){ var ret_eles = []; for(x in this.eles){ if(this.eles[x].className === class) ret_eles.push(this.eles[x]); } return ret_eles; }, sh: function(id, class){ var classes = showHide.getElesByClass(class); for(i in classes){ if(classes[i].id === id) classes[i].style.display = (classes[i].style.display == 'none')? 'block' : 'none'; } } }; window.onload = showHide.getEles(); now i am assuming that you have click events for the show hide effect. just replace onclick="showHide(id, class)" with onclick="showHide.sh(id, class);" doing it this way you only run the document.getElementsByTagName("*"); once when the page loads and then when you need to find the elements with a certain class run the inner getbyclass function. now if you were to dynamically add elements to the page, they would not be included in the original array of elements that is made when the page loads. to fix that just run showHide.getEles() to rewrite that array. good luck Quote Link to comment Share on other sites More sharing options...
knowram Posted October 10, 2007 Author Share Posted October 10, 2007 Ok I must be missing something. Here is a test page I set up that isn't working. <html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript"> var showHide = { eles: '', getEles: function(){ this.eles = document.getElementsByTagName("*"); return this; }, getElesByClass: function(class){ var ret_eles = []; for(x in this.eles){ if(this.eles[x].className === class) ret_eles.push(this.eles[x]); } return ret_eles; }, sh: function(id, class){ var classes = showHide.getElesByClass(class); for(i in classes){ if(classes[i].id === id) classes[i].style.display = (classes[i].style.display == 'none')? 'block' : 'none'; } } }; window.onload = showHide.getEles(); </script> <?php echo '<body>'; for ($a = "0"; $a <= "50"; $a++){ echo '<table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="50" align="right"> <ul class="checklist1"> <li class="list"> <span class=label onClick="showHide.sh('.$a.', showHide)" > <div id="'.$a.'" class="showHide"> up </div> <div id="'.$a.'" class="showHide" style="display:none;"> down </div> </span> </li> </ul> </td> </tr> <tr> <td> <div id="'.$a.'" class="showHide" style="display:none;"> hello<br> hello<br> hello<br> hello<br> </div> </td> </tr> </table>'; } echo '</body>'; ?> Quote Link to comment Share on other sites More sharing options...
emehrkay Posted October 10, 2007 Share Posted October 10, 2007 you just have some errors in y our approach. spans cant encompass divs, place the action on the handler not the span, ids cannot start with numbers,etc. just use this as the base for your code <html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript"> var showHide = { eles: '', getEles: function(){ this.eles = document.getElementsByTagName("*"); return this; }, getElesByClass: function(class){ var ret_eles = []; for(x in this.eles){ if(this.eles[x].className === class) ret_eles.push(this.eles[x]); } return ret_eles; }, sh: function(id, class){ var classes = showHide.getElesByClass(class); for(i in classes){ if(classes[i].id === id) classes[i].style.display = (classes[i].style.display == 'none')? 'block' : 'none'; } } }; window.onload = showHide.getEles(); </script> <?php echo '<body>'; for ($a = 0; $a <= 5; $a++){ echo '<table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="50" align="right"> <ul class="checklist1"> <li class="list"> <span class=label style="border: 1px solid red;" > <a href="#" id="up:'.$a.'" class="showHide" style="cursor:pointer;" onClick="showHide.sh(\'div:'.$a.'\', \'showHide\')"> up </a> <a href="#" id="'.$a.'" class="showHide" style="display:none;"> down </a> </span> </li> </ul> </td> </tr> <tr> <td> <div id="div:'.$a.'" class="showHide" style="display:none;"> hello<br> hello<br> hello<br> hello<br> </div> </td> </tr> </table>'; } echo '</body>'; ?> Quote Link to comment Share on other sites More sharing options...
fenway Posted October 10, 2007 Share Posted October 10, 2007 ids cannot start with numbers Says who? Quote Link to comment Share on other sites More sharing options...
emehrkay Posted October 10, 2007 Share Posted October 10, 2007 I fixed the link text <html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript"> var showHide = { eles: '', getEles: function(){ this.eles = document.getElementsByTagName("*"); return this; }, getElesByClass: function(class){ var ret_eles = []; for(x in this.eles){ if(this.eles[x].className === class) ret_eles.push(this.eles[x]); } return ret_eles; }, sh: function(id, class){ var classes = showHide.getElesByClass(class); var disp_link = document.getElement var disp = 'none'; var txt = 'Up'; var eye_d = id.split(':'); for(i in classes){ if(classes[i].id === id){ if(classes[i].style.display == 'none'){ disp = 'block'; txt = 'Down' } console.log(eye_d[1]); classes[i].style.display = disp; document.getElementById('link:' + eye_d[1]).innerHTML = txt; } } } }; window.onload = showHide.getEles(); </script> <?php echo '<body>'; for ($a = 0; $a <= 5; $a++){ echo '<table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="50" align="right"> <ul class="checklist1"> <li class="list"> <span class=label style="border: 1px solid red;" > <a href="#" id="link:'.$a.'" class="showHide" style="cursor:pointer;" onClick="showHide.sh(\'div:'.$a.'\', \'showHide\')"> up </a> </span> </li> </ul> </td> </tr> <tr> <td> <div id="div:'.$a.'" class="showHide" style="display:none;"> hello<br> hello<br> hello<br> hello<br> </div> </td> </tr> </table>'; } echo '</body>'; ?> Quote Link to comment Share on other sites More sharing options...
emehrkay Posted October 10, 2007 Share Posted October 10, 2007 ids cannot start with numbers Says who? they can, but it will fail validation... Quote Link to comment Share on other sites More sharing options...
knowram Posted October 10, 2007 Author Share Posted October 10, 2007 emehrkay your first post post work in Firefox but not IE or safari. and you second didn't work at all. And i don't know javascript at all so i am lost. Thanks for the help Quote Link to comment Share on other sites More sharing options...
emehrkay Posted October 10, 2007 Share Posted October 10, 2007 It didnt work in ie because of some reserved keywords "class" and then IE doesnt have a console, so the console.log function doesnt work in ie. and for some reason the for in loop didnt work in safari. this should now work across the board try this <html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript"> var showHide = { eles: '', getEles: function(){ this.eles = document.getElementsByTagName("*"); return this; }, getElesByClass: function(sel_class){ var ret_eles = []; var len = this.eles.length; for(x = 0; x < len; x++){ if(this.eles[x].className == sel_class) ret_eles.push(this.eles[x]); } return ret_eles; }, sh: function(id, sel_class){ var sel_eles = showHide.getElesByClass(sel_class); var disp_link = document.getElement var disp = 'none'; var txt = 'Up'; var eye_d = id.split(':'); for(i in sel_eles){ if(sel_eles[i].id === id){ if(sel_eles[i].style.display == 'none' || sel_eles[i].style.display == ''){ disp = 'block'; txt = 'Down'; } sel_eles[i].style.display = disp; document.getElementById('link:' + eye_d[1]).innerHTML = txt; } } } }; window.onload = showHide.getEles(); </script> <?php echo '<body>'; for ($a = 0; $a <= 5; $a++){ echo '<table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="50" align="right"> <ul class="checklist1"> <li class="list"> <span class=label style="border: 1px solid red;" > <a href="#" id="link:'.$a.'" class="showHide" style="cursor:pointer;" onClick="showHide.sh(\'div:'.$a.'\', \'showHide\')"> up </a> </span> </li> </ul> </td> </tr> <tr> <td> <div id="div:'.$a.'" class="showHide" style="display:none;"> hello<br> hello<br> hello<br> hello<br> </div> </td> </tr> </table>'; } echo '</body>'; ?> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.