Wednesday, October 24, 2007

Notice

I've pretty much stopped updating this blog, but the plugin development is still on-going. You can find the link to the Github project page at the bottom of the article.

What does this plugin do ?

This plugin will animate a regular anchor navigation [1] [2].
It will allow your visitors to navigate your site with a smooth scrolling effect.

Each time a link is clicked, the element you decide(can be the whole screen), will gradually scroll to the targeted element, instead of "jumping" as it'd normally do.jQuery.ScrollTo is used for the animation.

How to implement it ?

That's easy! you need to set links and anchors, that means, set an id to all those elements you want to scroll to.
These are the anchors.
Then add links with the respective id in the href, like this:

<a href="#the_id">your_text</a>

Let's call these "local links".
Lastly, you must call jQuery.LocalScroll on elements that contain our local links, you must wait for the document to be ready.

So if (for example) you have a div with id "navigation" and the local links are inside. You add this inside a document.ready:

$('#navigation').localScroll();

If your links are all spread, you can use:

$.localScroll();

That gets all the local links in the page. Both calls to the plugin accept one optional argument, that is, a hash specifying the settings described below. None is required.

Settings

target

What to scroll (selector, DOMElement, or jQuery Object). If none is specified, the whole window will be scrolled.

filter

String or function filter to ignore some of the links.

event

On which event of the link to react (click by default)

lazy

If true, more links can be added to the matched elements ( by AJAX, jQuery, etc ) and the plugin will also react to them.

stop

If true (default), the plugin will stop any previous animations of the target, to avoid queuing.

lock

If true, the plugin will ignore events if already animating (alternative to 'stop').

hash

If true, the hash of the clicked link, will appear on the address bar once the animation ends.Note:This option isn't too cool when scrolling overflown elements, it's mostly recommended when scrolling the window.

onBefore

A function to be called before each scrolling. It receives the following arguments: event object, targeted element and target to be scrolled. The 'this' will point to the set of settings.

reset

Only for $.localScroll.hash(), if true (default) elements' scroll is reset before actual scrolling.

In addition to that, you can use jQuery.ScrollTo's settings!
Check its demo to see all of them.

The plugin also adds a function, $.localScroll.hash() , that checks the URL in the address bar, and if there's a hash(#an_id), it will scroll to the element. It accepts a hash of settings, just like $.localScroll. You will likely call it on document ready. Check the regular example to see it in action.

How do I use the settings ?

The most important setting is 'target', you might not want to navigate(scroll) the screen, but only an overflowed element(like the demo).
In that case, you specify the target, with a selector or the element itself.

$('#navigation').localScroll({
target:'#content'
});

Instead of the window, an element with id 'content' will be scrolled.

Finally, a more complex call to show some customization in action:
Let's say you need to scroll on both axes to uncover all the anchors, then we'll need the option 'axis'.
You want to do an horizontal scroll, and then vertical, the code would be:

$('ul.sections').localScroll({
target:'#content',
axis:'xy',
queue:true//one axis at a time
});

Note that 'axis' and 'queue' actually belong to jQuery.ScrollTo, not to jQuery.LocalScroll.

Dynamic content( AJAX, AHAH, or simply jQuery )

The plugin supports dynamically added/loaded anchors and local links. You need to set the option 'lazy' to true. Note that the matched elements (#navigation in the first example) must be preserved in the DOM. But any content inside it can be modified. You don't have this problem if you use the global call.

Troubleshooting

When using the browser's back button, the scroll isn't reverted

This is a known fact when scrolling overflown elements (as in not the window).

When clicking a link, it jumps directly to the target

That's the browser default behavior (no javascript). You either have a javascript error (check with Firebug) or something's wrong in the call to the plugin.

Strange things happen

Try removing the option 'hash' or set it to false. It can cause problems.

That's because the div#content, keeps the scrollTop value that had before, meaning..In Projects, the height of the content is, let's say, 200px. But the div is "scrolled" 800px. So you don't what's inside.You must set the scrollTop of #content to 0, every time you reload the content.

Also, I don't know how "exprimental" is the state of the page, but you keep those 5 anchors there, and they point to non-existing elements when you are not in "o mnie"...

I do it in this way:a onclick='$("#content").scrollTo(0);$.ajax({url: "projekty.php", success: function(response){$("#content").html(response);}, dataType: "html"});'but I don't know it is right or not

The problem is that when you click "Projekty", you are loading some new html inside the div #content, then you go back to o mnie, and you expect those anchor to keep scrolling. But those are not the same anchors you bound before. Meaning, there's no 'click' handler on them. Check this link, you will understand:http://docs.jquery.com/Frequently_Asked_Questions#Why_do_my_events_stop_working_after_an_Ajax_request.3F

One solution would be, instead of calling load on #content, to call the load on #o_mnie, and hide #navigation, this way you don't destruct the original anchors, then when you click projekty again, you show #navigation.

Dear Ariel,Thanks for Your great plugin!!!I'd like to ask You a question about the onAfterFirst function:Unfortunately it doesn't work in my homepage...I want to scroll the entire page and I did put the following script in the head of the html:

jQuery(function( $ ){ $.localScroll();});

Furthermore i did chance axis:'x' to axis:'xy' in localscroll.js (line 38) and did write settings.queue = true; in scrollto.js (line 62)...

Thanks for a great plugin, Ariel. I am having a problem when my divs contain scrollbars (because I've got overflow:auto declared on them in the CSS). The scrolling gets very shakey in that case. For example, imagine that the numbered boxes on your demos have overflow:auto declared on them, and a few paragraphs of text so that a vertical scrollbar appears in each numbered box. When you then scroll, it is not smooth... but rather very shaky. My only solution so far has been to also use the jScrollPane plugin, and when I do that there is no longer any shakiness when moving between divs. Any thoughts or suggestions?

@M&M It won't capture the links inside an Iframe, as jQuery doesn't include these natively. If you describe the situation a little more, maybe we can figure out some kind of workaround.

@sparkybarkalot I'm not sure how could we improve that, is it an MSIE thing ? or for every browser ?You could try to use a longer animation (thus slower), maybe you could try different easing functions to see if that fixes it more or less.If you wanna try the easing option, search for jQuery+easing in Google and try the plugin.

ariel, thanks for the quick reply. I just did more testing, and at the moment it ONLY happens in Firefox 2. The following show no problems in Windows XP: IE6, IE7, Opera, Safari 3, NS 7.2. Weird huh. Changing animation speeds doesn't help, but I may try your suggestion about easing... though my sense is that there is something else going on. Thanks!

Hi sparkybarkalot In my opinion, this lack of smoothness in the animation is caused by the browser. Firefox seems to be a bit deficient at animations, I read somewhere that it's specially bad when the animations have floating point number.I have one idea you could try, is not the best solution but well. You could hide the scrollbars while animating (only for FF?) like this:

That could actually work, I was doing it all with JS and got messed up.

The thing is there's a document.getElementById in the code. And I'm not sure which document will it point to. You could try in that direction. If you want, we can talk about this by IM.GTalk: aflesler(at)gmail(dot)comMsn: flesler(at)hotmail(dot)com

@setiawantheaHi, what problem arises when combining both plugins ?Could you make a simple demo ?

@PerlawsI actually changed that part of the code in the demo, to remove the calls to ScrollTo and make it "pure" LocalScroll. Could you re-check the source code of the demo ? then tell me if you have any problem.

Hi Nelson You surely can use anchors, I tried your code and discovered FF has a weird bug, it throws an error when accessing the 'hash' attribute of a named anchor..I added an extra check for this, please get version 1.2.3 from the project page, this should work now.Also a tip.. if you have all the navigation links inside that div#float, you can call $('#float').localScroll....That will be faster..

thanks so much for the fix!really appreciate it, although there is still one more problem: the scroll effect doesn't work in safari. Is there something wrong with my code, or is jquery.localscroll just incompatible with that browser?

I'm embarassed at how long it took me to realize I had to roll my own css to get scrolling to work within a box. I'm so spoiled by jquery plugins doing it all for me, I forgot I actually need to earn my paycheck.

Perhaps it's just me but I think a mention of the css involved would be helpful.

Hey Ariel, just wanted to say thanks for creating ScrollTo and LocalScroll - they really are a pair of awesome plugins! You might be interested to see the site I recently built with them in mind for my university: http://www.pittvilledegreeshow.org. Cheers!

thank you for sharing such a terrific plugin, i have a question to ask, i hope its not too stupid (needless to say i am a absolute novice with scripting)

before i start implementing your script into a page, i wanted to check if the scroll will work the same way with a horizontal layout web page, rather than the more typical vertical? ie. will the scroll slide across the page, rather than down?

Thank you for your response, i really appreciate it, but i think i am out of my depth here, i can't tell one piece of code from the next and have tried reading through it all quite a few times but i still dont understand.

I know you must be busy, so id just like to say thanks for your script and the help you have given.

Think ill just stick to my CSS and HTML, leave the javascript for another day.

It seems that while the hash does indeed update the URL, the history is not working quite right -- pressing back does not have an effect the first time, although the URL does change.

A usage scenario is a page that has a table of contents. Making the table of contents "localscroll" is nice for usability, but you can't then press the back button (or, more accurately, when you do, the URL changes, but the user is not taken back).

This is a really good plugin and precisely what I want for my site. It isn't the first time I'm using jQuery plugins or something but for reasons completely beyond me, I've been trying for two days but canNOT get scrollTo to work, neither when I try localScroll nor when I try the serialscroll.

I've checked your demos, scanned the code where others are using it, seen the documentation, I just don't seem able to start it up and I can't see what I'm doing wrong.

I've written up a very simple try at both localscroll and serialscroll.. do you think you could possibly have a look-see and let me know what I'm doing wrong?

Sorry to hear it is hard to implement for you. Maybe I should exemplify the plugin with a big customized call.

Just try this:jQuery(function( $ ){ $.localScroll();});

You have some errors:* You're including scrollTo twice.* Calling localScroll twice.* The href of the "Jump to red square" should be "#red".* The id of the anchors doesn't need to have # and you don't need to give them names, just id.

The problem is due to 2 things.One is that you need to reset the scroll position to void the native behavior of the browser.

Add something like this before the call to hash().window.scrollTo( 0, 0 );

The other problem is that the accordion is moving the element #enc.So it's possible that localScroll is scrolling to the former position of #enc.Try calling hash() with a setTimeout or something like that.

Thanks very much! Firstly, I really appreciate how you're offering prompt individual help to the plugin users!

I removed the silly errors I had put in the demo in my frustration - the the basic localscroll is working now. Queue is set to true. Hash is false.

But there are two issues:1. It works on one-axis only. It will scroll down as far as need be to reach the element, but it will not then scroll right, at best it will only jump right.2. When I set the target's overflow to hidden/scroll, it simply doesn't work.

Here is my little demo:http://www.smartlink.com.sa/test/scrollto/

I then got this very simple template from Snipplr, and you can see how it looks when I pasted and edited it:http://www.smartlink.com.sa/test/scrollto/template.html

Again, scroll only covers one axis, even though section06 and section07 require not just horizontal but vertical scrolling as well, and queue is set to true.

First and foremost, thanks for providing this great plugin and a forum to get help for newbies such as myself. I am a complete jQuery rookie and have decided, as a designer, it was time to expand my skill set. Unfortunately, if something doesn't work properly, I am clueless as to the steps to figure out what I am doing wrong.

Enough of my blabbing. On to my problem. I am revamping my website and am trying to implement local scroll on a particular page to no avail. The page is http://www.lucidmotives.com/v4/about. The links contained in div#studio_tour should allow the user to scroll directly to the content indicated in the href, but nothing happens. Also, when clicking on the top icon, the user's browser should return the the div#studio_tour. Am I doing something wrong or am I just an idiot as I am beginning to feel like?

My last question is regarding easing. I like the bounce effect in your demos. How exactly is that achieved? Do I need to use a separate plug in for that effect?

Thanks for writing a very useful set of plugins. I'm using your plugins on a new website and I'm having trouble figuring out how to use the onBefore event to to mark the clicked (or hovered over) link during an autoscroll event.

I've read your explanation at http://plugins.jquery.com/node/2024#comment-1254 but I still cannot figure it out.

I'm a programmer but my experience is with is BASH, Perl, VBS, VBA and PHP in the past 10 years. Even so I'm not an expert at any language. I find jquery a bit difficult to follow so far (I've spent 2 days learning so far).

Would you mind taking a look please? The website is at http://test2.jsdtechnology.co.uk/

It's my first commercial project as a website designer. If I get paid for it I will donate to you.

Thanks Ariel. I tried that but it does not seem to take effect. I mean that when the image scrolls to the next one, the relevant button along the bottom row of buttons does not get highlighted/marked (as if a mouse pointer was rolled over it).

Hi Ariel,First of all thank you for this nice script (LocalScroll). It really works always..if you understand how to implement it!Well, I've got it on the rails, but I don't know how to make the same refresh effect as in youre demo, i.e. I want the section C stay open no matter the page refresh. What should I do?Thank you for youre time and help!Felix.

@darrenIt's hard to tell by just that. That's obviously correct. Can you get this online so I can see ?

@felixI noticed some sort of difficulty to implement this. Maybe because it requires an implicit markup (which is described on the docs).Let me say that the demos are not THE way of using the plugins. Both demos I sort of improvised them.On the AJAX demo, if you want it to start with a certain section based on location.hash, then simply do that by changing init.js.

The whole loading thing is not something that actually belongs to the plugin, is just something I made as a demonstration.