Topeka
Junior Member
Posts: 94
Topeka said 0 great things
|
Post by Topeka on Sept 12, 2010 10:14:54 GMT -8
Hey Wormo, You might remember me asking about this onmouseout function on proboards support. Well, I still have this issue with it.
On some boards, the onmouseout function will randomly not work. i dont get an error on the console, but it never stops, so i got the hint.
On most boards it works fine, But on others, the mouseout function doesnt work and messes up.
I've looked and i cant find why it wont work on some boards.
So, can you help find out why? and/or help find a way to make it work?
Heres the entire code.
<script type="text/javascript"> //Live Sig Changer var mysigs=new Array(); mysigs[0]="Sotf7.png"; mysigs[1]="HaloSigTops.png"; mysigs[2]="HaloR2.png"; s=0
function ChangeSig() { for(var divs=document.getElementsByTagName('div'), i=0;i<divs.length;i++){ if(divs[i].className.match(/user_signature/i) && divs[i].innerHTML.match(/musicgodguy/i)){ if(s>mysigs.length-1){ s=0 } divs[i].getElementsByTagName('img')[0].src='http://i285.photobucket.com/albums/ll47/musicgodguy/'+''+'brians/Sigs/'+mysigs[s]; s++; ChangeSig.sto=window.setTimeout("ChangeSig()",2500); } }
} ChangeSig.sto=0;
for(var divs=document.getElementsByTagName('div'), i=0;i<divs.length;i++){ if(divs[i].className.match(/user_signature/i) && divs[i].innerHTML.match(/musicgodguy/i)){ divs[i].getElementsByTagName('img')[0].onmouseover=function() {ChangeSig();} divs[i].getElementsByTagName('img')[0].onmouseout=function() {window.clearTimeout(ChangeSig.sto); } } } </script>
I can link you to the site if need be. Thanks if you can help
|
|
Bones
Code Helper
Posts: 131
Bones said 0 great things
|
Post by Bones on Sept 13, 2010 16:21:17 GMT -8
Perhaps you aren't aware of this but the onMouseOver event fires continually once the mouse is moving over the intended target. What that means is your code will setup multiple timers each time the mouse is moved over the target and when the mouse finally exits the boundaries of the target the onMouseOut cancels the last saved timer (the previously set timers will still be in effect).
This is the reason IE has an onMouseEnter event, unfortunately other browsers have not copied it like they've copied everything else from Redmond. You therefore need to get around that by checking if sto already contains a timer value before creating a new timer in the mouseover, then in the mouseout when that timer is canceled sto is set back to zero to prepare the way for the next mouseover.
|
|
Topeka
Junior Member
Posts: 94
Topeka said 0 great things
|
Post by Topeka on Sept 13, 2010 17:26:25 GMT -8
Perhaps you aren't aware of this but the onMouseOver event fires continually once the mouse is moving over the intended target. What that means is your code will setup multiple timers each time the mouse is moved over the target and when the mouse finally exits the boundaries of the target the onMouseOut cancels the last saved timer (the previously set timers will still be in effect). This is the reason IE has an onMouseEnter event, unfortunately other browsers have not copied it like they've copied everything else from Redmond. You therefore need to get around that by checking if sto already contains a timer value before creating a new timer in the mouseover, then in the mouseout when that timer is canceled sto is set back to zero to prepare the way for the next mouseover. But isnt the mouseover counted when it is first "moused over" the image(in this case) and only that 1 mouseover until it "mouses out". From what your saying, It sounds like everypixel that you move over the image will create a timer for each pixel until you mouseout, which will delete the last one. Is that True? If so wouldnt the fix only be if(ChangeSig.sto==0) { ChangeSig.sto=window.setTimeout("ChangeSig()",2500); }
|
|
Bones
Code Helper
Posts: 131
Bones said 0 great things
|
Post by Bones on Sept 13, 2010 18:38:16 GMT -8
Not pixel by pixel (that is onmousemove) but because the event honors event bubbling the transition to and from layers or child component of the intended target will fire off multiple events while still hovering over the target, which can seem counter-intuitive. Research the event and you'll see that it comes with other event attributes (fromElement, relatedTarget, etc.) to make sense of it all.
Yes checking for sto==0 is what I suggested (to ignore multiple fires) but also make sure sto is reset to zero once the timer is canceled or it will be ignored on subsequent mouseovers
|
|
Topeka
Junior Member
Posts: 94
Topeka said 0 great things
|
Post by Topeka on Sept 14, 2010 12:08:00 GMT -8
If i do what i did above, (the if(sto==0){} It will nolonger keep time. It will just change it once you mouseover it, and not change with setTimeout Once you mouseout and mouse back in, it will change once, then do nothing etc. How do you propose i get around this, cause it seems it wont change, cause the value is no longer 0 after you mouseover it. so if(){} is false, making it not change a 2nd time on the same mouseover.
|
|
|
Post by Wormopolis on Sept 14, 2010 18:50:31 GMT -8
put it in the first function call to the mouseover
divs.getElementsByTagName('img')[0].onmouseover=function() {if (ChangeSig.sto==0) ChangeSig();}
|
|
Bones
Code Helper
Posts: 131
Bones said 0 great things
|
Post by Bones on Sept 14, 2010 19:55:38 GMT -8
If i do what i did above, (the if(sto==0){} It will nolonger keep time. It will just change it once you mouseover it, and not change with setTimeout Once you mouseout and mouse back in, it will change once, then do nothing etc. How do you propose i get around this, cause it seems it wont change, cause the value is no longer 0 after you mouseover it. so if(){} is false, making it not change a 2nd time on the same mouseover. then in the mouseout when that timer is canceled sto is set back to zero to prepare the way for the next mouseover. but also make sure sto is reset to zero once the timer is canceled or it will be ignored on subsequent mouseovers The initial value will be 0, the act of setting a timer will set that to a non-zero value. With it being non-zero any other triggering of onmouseover will not be acknowledged. Finally once the onmouseout triggers that is where the timer is canceled and sto is set back to 0 to prepare the way for the next acknowledged onmouseover.
put it in the first function call to the mouseover divs .getElementsByTagName('img')[0].onmouseover=function() {if (ChangeSig.sto==0) ChangeSig();} Wouldn't that defeat the purpose if sto was set to 0 on every mouseover trigger, sto is being used as a flag to indicate a timer was already set in a previous mouseover trigger (to avoid setting multiple timers) Note that this is all for IE which has the bug I've encountered several times. Firefox for example will always pair a mouseover with a mouseout but IE has been known to fire off mouseovers in rapid succession with no accompanying mouseout between mouseover triggers.
|
|
|
Post by Wormopolis on Sept 14, 2010 21:28:21 GMT -8
I was going off the chain of events in my head. the first time the code runs, sto is 0. when the first image gets a mouseover, the function gets called (sto=0) and at the end of the function sto gets updated with each new timeout. if the mouseover event gets called again while still inside the image area, sto isnt 0 anymore so the mouseover doesnt call the function again. when the mouseout event is triggered, stop gets cleared and set back to 0. the image element, being the element that is having events added to it, wouldnt really have child elements that would fire mouseout/mouseover anyway would it? it should only get the single enter and exit ones when the cursor glides into them.
unless you are referring to sto being set to 0 at the end of the function, but it looked to me like ChangeSig.sto=0; was outside the function and only gets processed once.
|
|
Bones
Code Helper
Posts: 131
Bones said 0 great things
|
Post by Bones on Sept 16, 2010 1:06:21 GMT -8
For some reason I was seeing the events being bound to the div that was identified in the loop but since bound to an image it would not produce the scenario I described. Setting sto=0 in the mouseout however is the logical choice since it only targets browsers that have that rapid succession fire while working as intended on browsers that properly pairs the event fires. This however now appears to be a timing issue so chew on this scenario: - mouseover triggers and sets a self-perpetuating timer with interval 2.5 seconds
- if mouseout occurs ( for example at 2.53 seconds) while timer is looping through divs and cancels current timer (timer code already running so cancel is useless)...
- when event returns control to timer code the code continues its loop and finally sets a new timer which will continue to call itself every 2.5 seconds with no mouseout to stop it since that event has already occurred.
- any subsequent mouseover would then create an additional timer leaving the timer that slipped through the crack continuously running with no way to cancel since new timer overwrote its identifier.
Using setInterval instead of setTimout would avoid such a problem. onmouseover=function() {ChangeSig.sto = setInterval(ChangeSig,2500);} onmouseout=function() {clearInterval(ChangeSig.sto);} You would obviously also remove the self-perpetuating call to setTimeout from the ChangeSig function. Checkig for sto==0 should also be removed since the event is bound to an element that cannot contain children anyway (unless you plan on having having transparent absolute positioned elements layered above these images which would then bring the first scenario into play)
|
|
|
Post by Wormopolis on Sept 16, 2010 1:27:23 GMT -8
I was coming back to this to add that a check for sto==0 on the recursive setTimeout at the end of the function would eliminate any possible reloops from happening if the mouseout occured while running throught he function.
setInterval is a cleaner way of doing it though. That is why if Eton were a beer, he would be an MGD.
|
|
Topeka
Junior Member
Posts: 94
Topeka said 0 great things
|
Post by Topeka on Sept 27, 2010 12:22:17 GMT -8
Sorry for the Late Response, i've been busy. But I tried out setInterval/clearInterval and it seems to work great now! Thanks alot Eton and Wormo. I would of never thought of using setInterval on my own. Thanks again.
|
|