From time to time while developing with script.aculo.us I needed smooth scrolling for an “overflow:auto” element:
finally I got it: http://dev.rubyonrails.org/ticket/5118
If you want to scroll to a specific element inside the container, follow this example:
function moveTo(container, element){
Position.prepare();
container_y = Position.cumulativeOffset($(container))[1]
element_y = Position.cumulativeOffset($(element))[1]
new Effect.Scroll(container, {x:0, y:(element_y-container_y)});
return false;
}
where Position.cumulativeOffset($('target-id')) gives you an array with the absolute position of that element.
UPDATE the Source: If you’re looking for the source code of Effect.Scroll just click here …effectively the diff file is not so easy to work with (thank you Paul).
UPDATE/2 an Example:
Here’s the EXAMPLE. (Thank you for the advice Andreas)
UPDATE/3 get Horizontal: (after Ronnie’s comment)
Some guys did a very good work and got something similar to the Panic’s Coda website.
Visit Glider.js website to download the source.


“Effect.Scroll is not a constructor” hrm?
effect.scroll can be found here: http://pastie.caboo.se/36461
Would be nice to see an example of this script being used.
Hi,
great work!
What would I have to change to make that thing work horizontal?
Thanks&Cheers
In this site http://familientagebuch.de/rainer/2007/26.html#i82 I tried to realize a “remote” scrolling. Links in one DIv should controll an other (overflow) DIV. My solution was to use the mootools-lib.
But if I include this, a part of prototype-liv doesnt work.
Now Im looking for a better solution with the patch.
Can I control the scrolling in an other DIV like:
Scroll(in:’divID’,to:’ID_in_DIV’); ??
Rainer
Updated version of your code below, which will take a to_element argument and scroll that element to the center of the div. If x and Y are also supplied it will use them as an offset
Effect.MoveTo = Class.create();
Object.extend(Object.extend(Effect.MoveTo.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
var options = Object.extend({
x: 0,
y: 0,
to_element: null,
mode: ‘absolute’
} , arguments[1] || {} );
this.start(options);
},
setup: function() {
if (this.options.continuous && !this.element._ext ) {
this.element.cleanWhitespace();
this.element._ext=true;
this.element.appendChild(this.element.firstChild);
}
this.originalLeft=this.element.scrollLeft;
this.originalTop=this.element.scrollTop;
if (this.options.to_element) {
toElement=$(this.options.to_element)
container_dims=this.element.getDimensions()
to_element_dims=toElement.getDimensions()
Position.prepare();
container_x = Position.cumulativeOffset(this.element)[0]
element_x = Position.cumulativeOffset(toElement)[0]
container_y = Position.cumulativeOffset(this.element)[1]
element_y = Position.cumulativeOffset(toElement)[1]
this.options.x=this.options.x+element_x-container_x-(container_dims.width/2 – to_element_dims.width/2)
this.options.y=this.options.y+element_y-container_y-(container_dims.height/2 – to_element_dims.height/2)
}
if(this.options.mode == ‘absolute’) {
this.options.x -= this.originalLeft;
this.options.y -= this.originalTop;
} else {
}
},
update: function(position) {
this.element.scrollLeft = this.options.x * position + this.originalLeft;
this.element.scrollTop = this.options.y * position + this.originalTop;
}
});
awesome!!!!
you saved me hours of work switching to mootools for the scrolling effect.
Thank you very much :)
hello all, i have a stupid question that i need to ask because i’m kind of newbie on javascript programming…
so i’d like to know where i can put the new effect scroll()
i’ve tried to place it inside the scriptaculous effect.js => no success
i’ve tried to place it inside a new js file inside the html header block => no succes
everytime i get :
Effect is not defined
moveTo(“listeTarifs”, “femme-coiffure”)main (line 186)
onclick(click clientX=0, clientY=0)main (line 1)
[Break on this error] new Effect.Scroll(container, {x:0, y:(element_y-container_y)});
thx in advance
forgot something :
the prototype lib and the scriptaculous lib are loader inside the html head block
and the call of the moveTo() function is inside the html body block
I didn’t used this library lately, so I don’t remeber how to fix that error… have you the page online somewhere?
look also at mdmsrl.it with firebug for an example…
for the error below, i think his effects.js is a custom file if i am not mistaken from reading this a while ago
no hada el scroll en mozilla firefox =\
Is it possible to control scroll speed? If yes, could you point to me where?
Thanks and regards :)
try passing a “duration” option
Thanks Elia,
I did this:
function moveTo(container, element){
Position.prepare();
container_y = Position.cumulativeOffset($(container))[1]
element_y = Position.cumulativeOffset($(element))[1]
new Effect.Scroll(container, {duration:1, x:0, y:(element_y-container_y)});
return false;
}
- duration is set to 1 – a faster scroll can be obtained if setting duration below 1 eg. 0.3
Below is code to add expand the Element.scrollTo to use ths effect directly.
e.g. $(‘container’).scrollTo(‘child’);
Element.addMethods({
scrollTo: function(element, child){
var element = $(element);
if(arguments.length == 1) {
var pos = element.cumulativeOffset();
window.scrollTo(pos[0], pos[1]);
} else {
Position.prepare();
container_y = Position.cumulativeOffset($(element))[1]
element_y = Position.cumulativeOffset($(child))[1]
new Effect.Scroll(element, {x:0, y:(element_y-container_y)});
return false;
}
return element;
}
});