467,081 Members | 1,254 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,081 developers. It's quick & easy.

Smoth right scroll

Hi,

I would like to ask for your help.

Please look at the code below.

I would like to keep the location of the buttons while scrolling to
the right but I can't get a smoth scroll (without flickering of the
buttons).

BTW:
I need it for IE only.
Thanks,

Yaron
<html>
<head>
<title>Scrool Right</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">
<!--
function scrollBTN()
{
var scrollLeft = document.body.scrollLeft;
document.getElementById('BTN1').style.paddingLeft = scrollLeft;
}
//-->
</script>
</head>

<body bgcolor=#FFFFFF onscroll="scrollBTN()" >

<TABLE CELLPADDING="0" CELLSPACING="0" BORDER=0>

<TR>
<TD width="1900">1111111111111111111111111111111111111 11111111111111111111122222222222222222222222222222 22222222222222222333333333333333333333333333333333 33333333444444444444444444444444444444444444444445 55555555555555555555555</td>
<TD>&nbsp;Right</td>
</TR>

<tr><td colspan="2">
<div id="BTN1">
<input type="BUTTON" value="Get">&nbsp;<input type="BUTTON"
value="Clear">
</div>
</td></tr>

</TABLE>
</body>
</html>
Jul 23 '05 #1
  • viewed: 1780
Share:
8 Replies
Yaron C. wrote:
I would like to keep the location of the buttons while scrolling to
the right but I can't get a smoth scroll (without flickering of the
buttons).


Using onscroll could be used with advantage, but in your case you're
telling the UA to re-position the element as soon as possible - try to
handle the re-positioning more progressively.
<script type="text/javascript">
for(var ii=0,s="";ii++<100||document.write(s);s+=ii);

window.onload=function(evt){
if(document.getElementById && document.body) {
setTimeout(
function(){
var doc=document.compatMode &&
document.compatMode.indexOf("CSS")!=-1 &&
document.documentElement || document.body;
var div=document.getElementById("BTN1");
var left=0;

return function(){
if(left<doc.scrollLeft || left>doc.scrollLeft)
div.style.paddingLeft=
(left+=(doc.scrollLeft-left)>>2)+"px";

setTimeout(arguments.callee, 42);
}
}(),
42
);
}
}
</script>

<div id="BTN1">
<input type="button" value="Get">
<input type="button" value="Clear">
</div>
Jul 23 '05 #2
Thanks !!!

On 6-Jul-2004, Yann-Erwan Perio <y-*******@em-lyon.com> wrote:
Date: Tue, 06 Jul 2004 00:39:56 +0200
From: Yann-Erwan Perio <y-*******@em-lyon.com>
Reply-To: y-*******@em-lyon.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8a1)
Gecko/20040520
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: comp.lang.javascript
Subject: Re: Smoth right scroll
References: <93**************************@posting.google.com >
In-Reply-To: <93**************************@posting.google.com >
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 42
Message-ID: <40***********************@news.free.fr>
Organization: Guest of ProXad - France
NNTP-Posting-Date: 06 Jul 2004 00:40:05 MEST
NNTP-Posting-Host: 82.67.202.102
X-Trace: 1089067205 news2-e.free.fr 18109 82.67.202.102:4791
X-Complaints-To: ab***@proxad.net
Path:
news.012.net.il!seanews2.seabone.net!skynet.be!new s.csl-gmbh.net!feed.news.tiscali.de!newsfeed.icl.net!pro xad.net!feeder2-1.proxad.net!news2-e.free.fr!not-for-mail
Xref: news.012.net.il comp.lang.javascript:306100

Yaron C. wrote:
I would like to keep the location of the buttons while scrolling to
the right but I can't get a smoth scroll (without flickering of the
buttons).


Using onscroll could be used with advantage, but in your case you're
telling the UA to re-position the element as soon as possible - try to
handle the re-positioning more progressively.
<script type="text/javascript">
for(var ii=0,s="";ii++<100||document.write(s);s+=ii);

window.onload=function(evt){
if(document.getElementById && document.body) {
setTimeout(
function(){
var doc=document.compatMode &&
document.compatMode.indexOf("CSS")!=-1 &&
document.documentElement || document.body;
var div=document.getElementById("BTN1");
var left=0;

return function(){
if(left<doc.scrollLeft || left>doc.scrollLeft)
div.style.paddingLeft=
(left+=(doc.scrollLeft-left)>>2)+"px";

setTimeout(arguments.callee, 42);
}
}(),
42
);
}
}
</script>

<div id="BTN1">
<input type="button" value="Get">
<input type="button" value="Clear">
</div>

Jul 23 '05 #3
rh
Yann-Erwan Perio wrote:
Yaron C. wrote:
I would like to keep the location of the buttons while scrolling to
the right but I can't get a smoth scroll (without flickering of the
buttons).
Using onscroll could be used with advantage, but in your case you're
telling the UA to re-position the element as soon as possible - try to
handle the re-positioning more progressively.


The following is a conversion of your exemplary code to use onscroll,
which as you noted would be preferential to the continuous timeout
poll to detect scroll operations. Setting parameters to:

hideDuringScroll = false;
skidDistance = Infinity;

should provide operation that is close to your original, seemingly
with less jitter when oscillating direction of the scroll.

<script type="text/javascript">
for(var ii=0,s="";ii++<100||document.write(s);s+=ii);

window.onload=function(evt){
doc=document.compatMode &&
document.compatMode.indexOf("CSS")!=-1 &&
document.documentElement || document.body;
if(document.getElementById && document.body) {
div=document.getElementById("BTN1");

window.onscroll = function(){
var hideDuringScroll = true;
var skidDistance = 32;
// hideDuringScroll = false;
// skidDistance = Infinity;
var redRate = reductionRate = 2;

var left = lastScrollLeft = 0;
var delayBase = 42;
var delayFactor = 3;

var onscroll = function() {
if (lastScrollLeft != doc.scrollLeft) {
if (hideDuringScroll) div.style.visibility = "hidden";
window.onscroll = null;
redRate = reductionRate;
setTimeout(arguments.callee, delayFactor*delayBase);
}
else {
if (hideDuringScroll) {
div.style.visibility = "visible";
if ( Math.abs(doc.scrollLeft-left) > skidDistance)
left = Math.abs(doc.scrollLeft-skidDistance);
}
if (doc.scrollLeft-left < 1 << redRate) redRate >> 1;
div.style.paddingLeft=
(left+=(doc.scrollLeft-left) >> redRate)+"px";
if (redRate) setTimeout(arguments.callee, delayBase);
else {
div.style.paddingLeft= doc.scrollLeft+"px";
window.onscroll = onscroll;
redRate = reductionRate;
}
}
lastScrollLeft = doc.scrollLeft;
}
return onscroll;
}();
}
}
</script>

<div id="BTN1">
<input type="button" value="Get">
<input type="button" value="Clear">
</div>


../rh
Jul 23 '05 #4
Yep
rh wrote :

Hi,
The following is a conversion of your exemplary code to use onscroll,
which as you noted would be preferential to the continuous timeout
poll to detect scroll operations.
Using onscroll would indeed be beneficial since this would permit an
accurate resources' management; your script is a good start, but there
are still things which seem strange to me.
should provide operation that is close to your original
Well yes, but maybe because that same original, you seem to have
adopted a mixed conception, not fully taking advantage of the onscroll
perspective; for instance some style properties are unnecessarily
re-set at times.

Using a "scrolling" flag, adding a logical layer upon the positioning
analysis and eventually using another 'recursive closure' for the
after-scroll positioning, should offer a reasonable implementation for
the "full" conception.
doc=document.compatMode &&
Defining "doc" and "div" as this make them global variables, which
cannot really be wanted; it's better to include them into the wrapper.
var redRate = reductionRate = 2;
Quite a dangerous construct, since the scope for the two variables
isn't the same, as per the ECMA algorithms; here "reductionRate" is
global.
(left+=(doc.scrollLeft-left) >> redRate)+"px";


This was a sad error in the original script, my bad, the left property
isn't always updated when the shift is too big, this means that the
logic flow can be broken.
Cheers,
Yep.
Jul 23 '05 #5
rh
y-*******@em-lyon.com (Yep) wrote:
... Using onscroll would indeed be beneficial since this would permit an
accurate resources' management; your script is a good start, but there
are still things which seem strange to me.
should provide operation that is close to your original


Well yes, but maybe because that same original, you seem to have
adopted a mixed conception, not fully taking advantage of the onscroll
perspective; for instance some style properties are unnecessarily
re-set at times.

Using a "scrolling" flag, adding a logical layer upon the positioning
analysis and eventually using another 'recursive closure' for the
after-scroll positioning, should offer a reasonable implementation for
the "full" conception.


That's one of those questions of cost vs. complexity of the code. I
believe the frequency and the costs of the resets in this case
wouldn't justify the additional complexity of the code, even when the
original form of operation was in effect. But you can tell me if I'm
wrong here.

If it's really a problem, I'd be inclined to simply test (style and/or
computedStyle) prior to setting.

I can also understand the argument for coding for generality and the
desire for structural aesthetics.
doc=document.compatMode &&


Defining "doc" and "div" as this make them global variables, which
cannot really be wanted; it's better to include them into the wrapper.


During some experimentation I'd moved those declarations out, and
failed to restore them correctly. The intention was to leave that part
of your code completely unaltered.
var redRate = reductionRate = 2;


Quite a dangerous construct, since the scope for the two variables
isn't the same, as per the ECMA algorithms; here "reductionRate" is
global.


Thanks for the wake-up. It's a shortcut that should be used when
initializing globals only (if then?!). That line would perhaps better
read:

var reductionRate = 2, redRate = reductionRate;
(left+=(doc.scrollLeft-left) >> redRate)+"px";


This was a sad error in the original script, my bad, the left property
isn't always updated when the shift is too big, this means that the
logic flow can be broken.


Convergence failures were easier to detect with an "onscroll"
implementation. :)

A couple of further notes:

I probably should have replaced "arguments.callee" with "onscroll" in
the calls to setTimeout, just to help clarify the code, now that the
function is no longer anonymous.

It seems the line:

div.style.paddingLeft= doc.scrollLeft+"px";

is redundant and should be deleted (possibly one of the "strange"
things you were wondering about).

Regards,

../rh
Jul 23 '05 #6
rh
co********@yahoo.ca (rh) wrote in message news:<29**************************@posting.google. com>...
y-*******@em-lyon.com (Yep) wrote:
...

Using onscroll would indeed be beneficial since this would permit an
accurate resources' management; your script is a good start, but there
are still things which seem strange to me.


The following has a some fixes that, amongst other things, remove some
of the things that may have seemed strange (OK, were strange ;)). This
should be a little closer to the mark:

window.onload=function(evt){
var doc=document.compatMode &&
document.compatMode.indexOf("CSS")!=-1 &&
document.documentElement || document.body;
if(document.getElementById && document.body) {
var div=document.getElementById("BTN1");

var onScrollInit = function(){
var hideDuringScroll = true ;
var skidDistance = 48;
var reductionRate = 2;
var left = doc.scrollLeft, lastScrollLeft = left;
var delayBase = 42;
var delayFactor = 5;
var setVis = true;

var onscroll = function() {
if (lastScrollLeft != doc.scrollLeft) {
window.onscroll = null;
if (hideDuringScroll) {
div.style.visibility = "hidden";
setVis = true;
}
setTimeout(onscroll, delayFactor*delayBase);
}
else {
if (hideDuringScroll && setVis) {
div.style.visibility = "visible";
setVis = false;
if ( Math.abs(doc.scrollLeft-left) > skidDistance)
left = Math.abs(doc.scrollLeft-skidDistance);
}
if (Math.abs(doc.scrollLeft-left) < 1 << reductionRate)
reductionRate >>= 1;
div.style.paddingLeft=
(left+=(doc.scrollLeft-left) >> reductionRate)+"px";
if (reductionRate) setTimeout(onscroll, delayBase*1);
else window.onscroll = onScrollInit();
}
lastScrollLeft = doc.scrollLeft;
}
return onscroll;
}
window.onscroll = onScrollInit();
}
}

../rh
Jul 23 '05 #7
Yep
rh wrote :

(sorry for the delayed answer, rh)
The following has a some fixes that, amongst other things, remove some
of the things that may have seemed strange (OK, were strange ;)). This
should be a little closer to the mark:
Your script was already very good, it's even better now:-)
[About code complexity]
if (lastScrollLeft != doc.scrollLeft) {


There comes the discussion about code complexity and cost that you
were mentioning before; there's no definite solution of course and
this can be a difficult choice, especially when the original
conception is strong; personally I tend to prefer code complexity over
cost of doing so, especially in environments as unstable as browsers,
but that's my way of coding.

To me, a good program can be defined as fulfilling the customer needs,
efficiently, flexibly and solidly (strong error-catching system).
However, this makes the program good, not more, that's just the basics
you could say. The real thing, to me, is aesthetic, when a program can
expose a beautiful flow to the reader. Striving for aesthetic is one
of the biggest quality for a programmer IMHO (with the ability to take
one's time in imagining the program, and of course common qualities
like analytical and logical skills, good memory and curiosity).

However in the current script there shouldn't be any hesitation,
testing window.onscroll would probably be a good thing:-)

I also think that you could remove the hideDuringScroll and setVis
parameters and hide automatically; there's no real added value in not
hiding during the scroll if you just move the object when the scroll
has stopped.
[About var a=b="foo"]

As you've said, this should be used only in global context; however in
most conceptions using too many global variables just keeps polluting
the global namespace, so such constructs are very unlikely to appear
in advanced scripts. Now, "a=b='foo'" can be used effectively, if the
variables have been defined on the correct scope beforehand.
BTW, IIRC it's the first time I've seen you using a closure-based
style with your scripts; what are your impressions on this matter?
Regards,
Yep.
Jul 23 '05 #8
rh
y-*******@em-lyon.com (Yep) wrote:
rh wrote :

(sorry for the delayed answer, rh) (as if I'm always timely :)) Your script was already very good, it's even better now:-)

Thanks for the positive feedback!

[About code complexity]
if (lastScrollLeft != doc.scrollLeft) {
There comes the discussion about code complexity and cost that you
were mentioning before; there's no definite solution of course and
this can be a difficult choice, especially when the original
conception is strong; personally I tend to prefer code complexity over
cost of doing so, especially in environments as unstable as browsers,
but that's my way of coding.

To me, a good program can be defined as fulfilling the customer needs,
efficiently, flexibly and solidly (strong error-catching system).
However, this makes the program good, not more, that's just the basics
you could say. The real thing, to me, is aesthetic, when a program can
expose a beautiful flow to the reader. Striving for aesthetic is one
of the biggest quality for a programmer IMHO (with the ability to take
one's time in imagining the program, and of course common qualities
like analytical and logical skills, good memory and curiosity).


Yes, there can be endless debate about this aspect of programming (and
there has been a certain amount recently in this forum). Fully
understanding a problem, and the tools that are available to solve it,
will often lead to the most elegant solution. There are also times,
through this virtue, when the most elegant solution may be the most
difficult for others, perhaps not as well versed, to understand.

Regardless, I think we all aspire to the "best solution" using the
"best practises" that can be acheived within the time that can be
allotted to the process. There's no question that your way is to be
admired.
However in the current script there shouldn't be any hesitation,
testing window.onscroll would probably be a good thing:-)

I also think that you could remove the hideDuringScroll and setVis
parameters and hide automatically; there's no real added value in not
hiding during the scroll if you just move the object when the scroll
has stopped.

Agreed, the ability to set hideDuringScroll was included for no
purpose other than to emulate the behaviour of your original.

I tend not to use switches if they can be avoided. However,
eliminating setVis relates to whether you wish to tolerate unecessary
settings of the style visibility, since the value of window.onscroll
is insufficient to make the determination (i.e., it's desirable to set
the visibility once when beginning to show the motion, even though the
onscroll setting remains null throughout the animation).

(I found that setting the visibility is highly efficient in some
prominent browsers and highly inefficient in others. What else would
we expect?)

See below (if you're not getting too bored by now :)) for a final
version that minimizes setting of visibility, and allows both
horizontal and vertical scroll placement of a div with absolute (0,0)
positioning.

[About var a=b="foo"]

As you've said, this should be used only in global context; however in
most conceptions using too many global variables just keeps polluting
the global namespace, so such constructs are very unlikely to appear
in advanced scripts. Now, "a=b='foo'" can be used effectively, if the
variables have been defined on the correct scope beforehand.

That relates to some extent to my "(if ever?!)" comment, regarding
use. I too am a general anti-globalist (and often cringe a bit when I
see suggestions like "what you have to is set a global variable." in
clj), and share your concern regarding overuse of this namespace.

BTW, IIRC it's the first time I've seen you using a closure-based
style with your scripts; what are your impressions on this matter?


If one is writing relatively small snippets of code, it doesn't all
that often lend itself to introducing closures. However, the use
setTimeout almost always seems to be a natural lead-in to creation of
a closure.

I'm highly impressed with closures, and try to make use of them
whenever it seems appropriate to do so.

Regards,
../rh

window.onload=function(evt){
var doc=document.compatMode &&
document.compatMode.indexOf("CSS")!=-1 &&
document.documentElement || document.body;
if(document.getElementById && document.body) {
var div=document.getElementById("BTN1");

var onScrollInit = function(){
var skidDistance = 75;
var leftReductionRate = 2, topReductionRate = leftReductionRate;
var left = doc.scrollLeft, lastScrollLeft = left;
var top = doc.scrollTop, lastScrollTop = top;
var delayBase = 42;
var delayFactor = 3;
var setVis = false;

var setPos = function(axis, pos, red) {
var scrollPos = doc["scroll"+axis.substr(0,1).toUpperCase()
+axis.substr(1)];
if ( Math.abs(scrollPos - pos) > skidDistance)
pos = Math.abs(scrollPos-skidDistance);
if ( Math.abs(scrollPos - pos) < 1 << red) red >>= 1;
div.style[axis] = ( pos +=(scrollPos - pos) >> red)+"px";
if (axis == "top") { top = pos; topReductionRate = red; }
else { left = pos; leftReductionRate = red; }
}

var onscroll = function() {
if (lastScrollLeft != doc.scrollLeft
|| lastScrollTop != doc.scrollTop) {
if (! setVis && (setVis = true))
div.style.visibility = "hidden";
if (window.onscroll) window.onscroll = null;
setTimeout(onscroll, delayFactor*delayBase);
}
else {
if (setVis && ! (setVis = false))
div.style.visibility = "visible";
setPos("top", top, topReductionRate); // conditional call?
setPos("left", left, leftReductionRate); // " "
if (leftReductionRate
|| topReductionRate) setTimeout(onscroll, delayBase);
else window.onscroll = onScrollInit();
}
lastScrollLeft = doc.scrollLeft;
lastScrollTop = doc.scrollTop;
}
return onscroll;
}
window.onscroll = onScrollInit();
}
}
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

By using this site, you agree to our Privacy Policy and Terms of Use.