Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 415
  • Last Modified:

MouseOver scroll up/down script

I need a script which will scroll a frame up and down when the mouse is over the appropriate buttons in another frame.

I can make a frame scroll, using

     parent.frames.myframe.scroll(0,variable)

but there's obviously something about scrolling and timeouts that I don't understand, because I can't get it to *stop* scrolling.

Points for a script that works, bonus for an annotate script that I can *understand*!
0
johnny99
Asked:
johnny99
1 Solution
 
jbirkCommented:
I would just set a variable on mouseOut, and in the repaeting loop which calls setTimeout, check to be sure that variable hasn't been changed.  This way another setTimeout won't be called, and the scrolling will stop.  I don't have the time right now to work up a complete tested example, but here's some short code:

<A HREF="javascript:;" onClick="return false;" onMouseOver="upover=true; ScrollUp()" onMouseOut="upover=false">down</A>
<A HREF="javascript:;" onClick="return false;" onMouseOver="downover=true; ScrollDown()" onMouseOut="downover=false">down</A>


<SCRIPT language="JavaScript">
<!--
var downover=false,upover=false;
function ScrollUp()
{if (upover)
  {//scroll up code you are currently using
   setTimeout("ScrollUp",1000);
  }
}
function ScrollDown()
{if (downover)
  {//scroll down code you are currently using
   setTimeout("ScrollDown",1000);
  }
}
// -->
</SCRIPT>

I think that's about the simplest way to do it.

-Josh
0
 
kollegovCommented:
1. Use scrollBy() instead of scroll() have some advantage, in your case as you need to increment your variable. And thus someway trace it riched limit
(this isn't easy). Of course , browser will limit scroll itself,but not your variable, So if this happens your variable can goes far out of valid values limit, than when user will press scroll in other direction he would need to wait while this value will return back into range of valid values..

2. to interrupt recursive calls you can assign timers
someVar=setTimeout('some()',100);
and than use clearTimeout(someVar)
to interrupt timeout.

The rest is quite simple :-)



<script>
var uptimer
var downtimer
var step=10;


function ScrollUp(){
  parent.frames.myframe.scrollBy(0,step)
  uptimer=setTimeout('ScrollUp()');
}
function ScrollDown(){
  parent.frames.myframe.scrollBy(0,-step)
  downtimer=setTimeout('ScrollDown()');
}

function ScrollStop(){
 if(downtimer!=null) clearTimeout(downtimer);
 if(uptimer  !=null) clearTimeout(uptimer);
}
 
</script>

<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="ScrollDown();"
   onMouseOut="ScrollStop()">down</A>
<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="ScrollUp();"
   onMouseOut="ScrollStop()">up</A>


This Example was tested with NN4.6 / Win95
0
 
jbirkCommented:
kollegov, your code can introduce a time slicing problem.  If the user rolls off of the link when the code for ScrollUp or ScrollDown is being executed (before the timeout is set), then it will not clear the timeout and it will continue even though the mouse is no longer over the link.  It may not happen that often, but it's possible (and the time between each timeout will determine how likely this is to happen).  If you use a variable like I showed above, this will not be a problem.

The scroll issue you raised is an important one though.

-Josh
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
kollegovCommented:
Josh, this do not happens because normally event thread will be surved after executing of function call.
( Have you noticed that infinite loops in JS totally blocks events? )

But, script can be modified as following to avoid this 'theoretical'
problem...

<script>
var uptimer
var downtimer
var step=10;


function ScrollUp(){
  parent.frames.myframe.scrollBy(0,step)

}
function ScrollDown(){
  parent.frames.myframe.scrollBy(0,-step)
}

function ScrollStop(){
 if(downtimer!=null) clearInterval(downtimer);
 if(uptimer  !=null) clearInterval(uptimer);
}
 
</script>

<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="downtimer=setInterval('ScrollDown()',100);"
   onMouseOut="ScrollStop()">down</A>
<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="uptimer=setInterval('ScrollUp()',100);"
   onMouseOut="ScrollStop()">up</A>


//--------------------
setInterval will execute statement each
100 ms. It will be called only once from onlouse over, and onMouseOut interval will be cleared...
0
 
jbirkCommented:
I realize the chances of it occuring are slim, but they are still there.  Do you have proof that events always fall after function calls in all browsers?  I'd rather be safe...

Yes , you are right that setInterval will fix the (theoretical) problem:)  There's always more than one way to solve a problem!

-josh
0
 
bulletbulletCommented:
This feature is great. Thanks.

Is there any way to remove the scrollbar in NN4.5 and maintain the feature?   Works fine in IE5.0 with scrolling="no" in the frame but will not move in NN.

0
 
jbirkCommented:
Go and read this page:
http://webreference.com/dhtml/column17/syncNStwo.html
It has the reason behind the problem (semantics, nonetheless!), and the workaround (using layers)

-Josh
0
 
kollegovCommented:
Actually NO, In NN if you have no scrollbars, than you can't use scroll()
method.

So called 'workaround' with layers is possible, if you do not need to have scrollbars...than put all your content into wrapper (in myframe) like this

<body>
<DIV ID="wrapper" style="position:absolute;top:0;left:0">
all your scrolling document here
</div>
</body>

And use this script instead:

<script>
var uptimer
var downtimer
var step=10;


function moveDivBy(x,y)
 {var id='wrapper';
  if(document.layers)
    {d=parent.frames.myframe.document[id];
     if(d.left+x>=0) d.left+=x;
     if(d.top+y >=0) d.top+=y;
    }
  if(document.all)                
    {d=parent.frames.myframe.document.all[id].style;
     if(d.offsetLeft+x>=0)  d.pixelLeft=d.offsetLeft+x;
     if(d.offsetTop+y>=0)   d.pixelTop=d.offsetTop+y;
    }
 }


function ScrollStop(){
 if(downtimer!=null) clearTimeout(downtimer);
 if(uptimer  !=null) clearTimeout(uptimer);
}
 
</script>

<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="downtimer=setInterval('moveDivBy(0,step)',100);"
   onMouseOut="ScrollStop()">down</A>
<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="uptimer=setInterval('moveDivBy(0,-step)',100);"
   onMouseOut="ScrollStop()">up</A>
0
 
kollegovCommented:
Actually NO, In NN if you have no scrollbars, than you can't use scroll()
method.

So called 'workaround' with layers is possible, if you do not need to have scrollbars...than put all your content into wrapper (in myframe) like this

<body>
<DIV ID="wrapper" style="position:absolute;top:0;left:0">
all your scrolling document here
</div>
</body>

And use this script instead:

<script>
var uptimer
var downtimer
var step=10;


function moveDivBy(x,y)
 {var id='wrapper';
  if(document.layers)
    {d=parent.frames.myframe.document[id];
     if(d.left+x>=0) d.left+=x;
     if(d.top+y >=0) d.top+=y;
    }
  if(document.all)                
    {d=parent.frames.myframe.document.all[id].style;
     if(d.offsetLeft+x>=0)  d.pixelLeft=d.offsetLeft+x;
     if(d.offsetTop+y>=0)   d.pixelTop=d.offsetTop+y;
    }
 }


function ScrollStop(){
 if(downtimer!=null) clearTimeout(downtimer);
 if(uptimer  !=null) clearTimeout(uptimer);
}
 
</script>

<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="downtimer=setInterval('moveDivBy(0,step)',100);"
   onMouseOut="ScrollStop()">down</A>
<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="uptimer=setInterval('moveDivBy(0,-step)',100);"
   onMouseOut="ScrollStop()">up</A>
0
 
jbirkCommented:
kollegov, did you go to that link I provided?  It already stated all of that info with more explanation... and code for the workaround.

-Josh
0
 
kollegovCommented:
Oppppsss, fixed mistake in MIE branch.
Now script tested with both MIE5 and NN4.61

Josh, I first write my own implementation, and than looked into URL you posted, what I see is that function is made for solving only scrolling problem (nothing more)
When I'm writing something, I'm trying to make functions more general purpouse than just a narrow problem.
For example with the same function below you can place several divs
and move them independently to create
more dynamic effects ..


<script>
var uptimer
var downtimer
var step=10;


function moveDivBy(id,x,y)
 {
  if(document.layers)
    {d=parent.frames.myframe.document[id];
     if(d.left+x>=0) d.left+=x;
     if(d.top+y >=0) d.top+=y;
    }
  if(document.all)                
    {d=parent.frames.myframe.document.all[id].style;
     if(d.pixelLeft+x >= 0) d.pixelLeft=d.pixelLeft+x;
     if(d.pixelTop+y>=0) d.pixelTop=d.pixelTop+y;
    }
 }


function ScrollStop(){
 if(downtimer!=null) clearTimeout(downtimer);
 if(uptimer  !=null) clearTimeout(uptimer);
}
 
</script>

<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="downtimer=setInterval('moveDivBy(&quot;wrapper&quot;,0,step)',100);"
   onMouseOut="ScrollStop()">down</A>
<A HREF="javascript:void(0);" onClick="return false;"
   onMouseOver="uptimer=setInterval('moveDivBy(&quot;wrapper&quot;,0,-step)',100);"
   onMouseOut="ScrollStop()">up</A>
0
 
jbirkCommented:
This is true.  I have a series of these general purpose functions myself.  But more often than not, I end up using more specialized code for the circumstances...
0
 
johnny99Author Commented:
That seems to address the problem, not exactly the problem I started with, but the problem I turned out to have!

Thanks kollegov...
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now