bronzemonkey Posted January 10, 2008 Share Posted January 10, 2008 I need some help adding some additional functionality to my code which is targeting items in a list. On mouseover a class is assigned to the list item and persists on mouseout. What I'd like to do is also have the list items (5 of them) automatically cycled through at a specific rate (assigning the "showme" class for a few seconds before passing the class on to the next list item) when the document has loaded. Therefore, when a user mousesover a list item, this automatic cycling has to pause and only restart 10 seconds after the user mousesout from that list item. But I'm not getting anyway with my attempts. Any help or pointers would be great. Thanks // I'm using mootools window.addEvent('domready', function() { var getEls = $('mylist').getElementsByTagName('li'); var whatever = getEls; for (var i = 0; i < 5; i++) { getEls[i].onmouseover=function() { for (var j = 0; j < 5; j++) { whatever [j].className=whatever [j].className.replace("showme", ""); } this.className+=" showme"; } } }); Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 10, 2008 Share Posted January 10, 2008 so you have five unordered lists and you want to go through each li assigning a classname and removing it? Quote Link to comment Share on other sites More sharing options...
bronzemonkey Posted January 11, 2008 Author Share Posted January 11, 2008 I've got an ordered list with 6 list items but only want to work on the first 5 items. Here is the code: HTML <div id="top-recipes"> <h2>Heading</h2> <ol> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">First Recipe</a></h3> <p>Description.</p> </div> <img src="img1.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">First Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Second Recipe</a></h3> <p>Description.</p> </div> <img src="img2.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Second Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Third Recipe</a></h3> <p>Description.</p> </div> <img src="img3.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Third Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Fourth Recipe</a></h3> <p>Description.</p> </div> <img src="img4.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Fourth Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Fifth Recipe</a></h3> <p>Description.</p> </div> <img src="img5.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Fifth Recipe</a> </li> <li class="last"><a href="#">See All Top Recipes</a></li> </ol> </div><!-- end #top-recipies --> JS // I'm using mootools window.addEvent('domready', function() { var getEls = $('top-recipes').getElementsByTagName('li'); var whatever = getEls; for (var i = 0; i < 5; i++) { getEls[i].onmouseover=function() { for (var j = 0; j < 5; j++) { whatever [j].className=whatever [j].className.replace("showme", ""); } this.className+=" showme"; } } }); I use a li:hover state for each list item that reveals the summary div. To progressively enhance the experience for javascript users I assign a class - "showme" - to the list item on mouseover that has the same styles and consequences as the li:hover state...but the class stays there even on mouseout (unless they mouseover a different list item). What I'd like to do is have this class automatically assigned to each list item in turn...as if the user were hovering over each of the 5 list items, in order, at a regular rate. When the user actually puts their mouse over a list item, the cycling is "paused" on that list item (even when they mouse out...unless they mouseover a different list item) for a fixed time before resuming. If it is possible to have a short transition effect (rapid fade in/out) that would also be useful. Hopefully that explanation makes sense! Thanks Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 11, 2008 Share Posted January 11, 2008 I'd say use a class to do this. It shouldnt be too difficult though. Ill take a look at it some more. Post your js that shows the summary div Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 11, 2008 Share Posted January 11, 2008 Here is what I did. I hope it can help you find a way to make it work. I had to make some changes to how the summary is displayed. YOu wanted a gradual growing effect, i did that my making the height zero and overflow hidden of the .summary element. However, when you mouse over it and the summary grows, the li changes, so you're mousing over it again and again, the li grows and shrinks kinda causing an loop and the code cant catch up with the mouse's actions. I changed your summary div to a popup just by making it have an absolute position. It works, but you can definitely tweak it for the better to suit your needs. recipie_list.js var RecipieList = new Class({ summaries: [], index: 0, initialize: function(){ this.list = $('top-recipes').getElements('.recipe'); var sum = $('top-recipes').getElements('.summary'); sum.each(function(summary, x){ var obj = { element: summary, fx: new Fx.Styles(summary, {duration: 0}) }; this.summaries.push(obj); }.bind(this)); this.list.each(function(li, i){ li.addEvent('mouseover', function(){ this.index = i; this.hideOpenSummaries().showSummary(); }.bind(this)); }.bind(this)); }, showSummary: function(){ console.log('showing '+ this.index); var size = this.summaries[this.index].element.getSize(); var li_cord = this.summaries[this.index].element.getParent().getCoordinates(); this.summaries[this.index].fx.start({ height: size.scrollSize.y + 'px', top: li_cord.top + 'px', left: li_cord.left + 'px' }); }, hideSummary: function(){ console.log('mouseout'); this.summaries[this.index].fx.start({ height: '0px' }); }, hideOpenSummaries: function(){ this.summaries.each(function(sum, i){ //this.index = i; // if(this.summaries[i].element.style.height > 0){ console.log(i +' is open'); //this.hideSummary(); this.summaries[i].element.style.height = '0px'; //} }.bind(this)); return this; } }); list.php <html> <head> <style type="text/css"> .summary{ height: 0px; overflow: hidden; position: absolute; top: 0; left: 0; background: red; } li{ border: 1px solid #000; } </style> <script type="text/javascript" src="mootools.js" ></script> <script type="text/javascript" src="recipie_list.js" ></script> <script type="text/javascript"> window.addEvent('domready', function(){ new RecipieList(); }); </script> </head> <body> <div id="top-recipes"> <h2>Heading</h2> <ol> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">First Recipe</a></h3> <p>Description.</p> </div> <img src="img1.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">First Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Second Recipe</a></h3> <p>Description.</p> </div> <img src="img2.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Second Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Third Recipe</a></h3> <p>Description.</p> </div> <img src="img3.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Third Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Fourth Recipe</a></h3> <p>Description.</p> </div> <img src="img4.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Fourth Recipe</a> </li> <li class="recipe"> <div class="summary"> <div> <h3><a href="#">Fifth Recipe</a></h3> <p>Description.</p> </div> <img src="img5.jpg" alt="" width="400" height="220"> </div> <a class="recipe-link" href="#">Fifth Recipe</a> </li> <li class="last"><a href="#">See All Top Recipes</a></li> </ol> </div><!-- end #top-recipies --> </body> </html> [code] [/code] Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 11, 2008 Share Posted January 11, 2008 oh yeah, and you can easily create a loop that is interrupted when a list item is moused over by using the showSummary and hideSummary methods. just add a periodical() on it to set the time between showing the summaries Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 11, 2008 Share Posted January 11, 2008 Alright, I cleaned up the js a lil bit, gave you some offset options, used mouseenter and mouseleave instead mouseover and off, and took out the unnecessary code var RecipieList = new Class({ summaries: [], index: 0, options: { offset_x: 20, offset_y: 10 }, initialize: function(options){ this.setOptions(options); this.list = $('top-recipes').getElements('.recipe'); var sum = $('top-recipes').getElements('.summary'); sum.each(function(summary, x){ var obj = { element: summary, fx: new Fx.Styles(summary, {duration: 0}) }; this.summaries.push(obj); }.bind(this)); this.list.each(function(li, i){ li.addEvent('mouseenter', function(){ this.index = i; this.hideOpenSummaries().showSummary(); }.bind(this)); li.addEvent('mouseleave', function(){ this.hideSummary(); }.bind(this)); }.bind(this)); }, showSummary: function(){ var size = this.summaries[this.index].element.getSize(); var li_cord = this.summaries[this.index].element.getParent().getCoordinates(); this.summaries[this.index].fx.start({ height: size.scrollSize.y + 'px', top: li_cord.top + this.options.offset_y + 'px', left: li_cord.left + this.options.offset_x + 'px' }); }, hideSummary: function(){ this.summaries[this.index].fx.start({ height: '0px' }); }, hideOpenSummaries: function(){ this.summaries.each(function(sum, i){ this.summaries[i].element.style.height = '0px'; }.bind(this)); return this; } }); RecipieList.implement(new Options); Quote Link to comment Share on other sites More sharing options...
bronzemonkey Posted January 12, 2008 Author Share Posted January 12, 2008 I had to make some changes to how the summary is displayed. You wanted a gradual growing effect... I must not have not explained properly, because what I am looking for is something that I hoped was just a simple enhancement of something that works without javascript. I already have the summaries displaying as I want. I use only css to reveal the summary when the relevant list item is hovered over. Then I have some javascript (see first post) that works just to add a class to the li that has the same css as the li:hover state...just to make the :hover appearance persist. Everything works perfectly. What I was hoping to do was add a few enhancements for js users by expanding that little snippet of js into is something that also moves this class from li to li automatically, in a repeating cycle, that is only interrupted momentarily when a user manually triggers my css-based li:hover state my hovering over a list item. So the js puts the class "showme" in the first li element, then 10 seconds later it moves it to the second li element, etc. But if I hover on the first li element during this endless cycle, it willl shift the "showme" class back to the first li element...and then 10 seconds later restart the automatic cycling of the "showme" class. I could be wrong, but I had imagined emulating a simple fade in/out transition by using javascript just to add a variable opacity layer over the region when the summaries get shown. Just a very quick shift from 100% black to 0% (or transparent) in order to give the impression of a rapid fade-in from black (not a dimensional change) and not an instantaneous switch of content which can look bizarre. Does that make sense? thanks again Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 12, 2008 Share Posted January 12, 2008 Lets see the css that does the displaying/hiding of the summary div. The answer is that you can add a fading effect to it, I just need to know which direction to go in. The looping should be easy to do with periodical() Quote Link to comment Share on other sites More sharing options...
bronzemonkey Posted January 13, 2008 Author Share Posted January 13, 2008 Lets see the css that does the displaying/hiding of the summary div. The answer is that you can add a fading effect to it, I just need to know which direction to go in. The looping should be easy to do with periodical() I'd rather not post the css. It's copyrighted material that I want to avoid posting in a public forum. But the specifics of the css shouldn't make any difference to what kind of js is needed to loop a class through several elements. Unfortunately, although my css knowledge is very good...my js knowledge is quite limited! The looping is the key thing I am trying to achieve (including pausing when a user hovers and break the cycle etc). Quote Link to comment Share on other sites More sharing options...
emehrkay Posted January 13, 2008 Share Posted January 13, 2008 Lets see the css that does the displaying/hiding of the summary div. The answer is that you can add a fading effect to it, I just need to know which direction to go in. The looping should be easy to do with periodical() I'd rather not post the css. It's copyrighted material that I want to avoid posting in a public forum. But the specifics of the css shouldn't make any difference to what kind of js is needed to loop a class through several elements. Unfortunately, although my css knowledge is very good...my js knowledge is quite limited! The looping is the key thing I am trying to achieve (including pausing when a user hovers and break the cycle etc). Oh ok. Well you should be able to reverse-engineer the code that I provided and reread my other suggestions. You can get it to work. Good luck 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.