Scroll Up Headline Reader
A couple weeks ago someone on the jQuery discussion list asked if someone could reproduce a rotating headline box in which the headlines, in succession, scroll up into the box, pause, and then scroll up out of the box. Since I already had some code for rotating images on a page, I decided to recycle it and take the challenge.
Here is the finished product. (Please note that if you are looking at this in a feed reader, you won't be able to see the effect. )
Headline number 2 was a little arrogant. He thought he'd be here forever. But he was obviously wrong. Nothing lasts forever. Not even me, Headline number 3. This is a link to nowhere.
Get Started with the HTML and CSS
The first thing I did was throw a simple page together using a single container DIV with an id of "scrollup" and four or five DIVs with a class of "headline" to hold each headline.
-
<div id="scrollup">
-
<div class="headline"> ... </div>
-
<div class="headline"> ... </div>
-
<div class="headline"> ... </div>
-
<div class="headline"> ... </div>
-
</div>
I then added this simple CSS to the scrollup ID and the headline class:
-
#scrollup {
-
position: relative;
-
overflow: hidden;
-
border: 1px solid #000;
-
height: 200px;
-
width: 200px
-
}
-
.headline {
-
position: absolute;
-
top: 210px;
-
left: 5px;
-
height: 195px;
-
width:190px;
-
}
That made all of the headlines absolutely positioned in relation to their containing box, which got a height and width of 200px. Notice that the top of all of those headlines is 210px, and the overflow property of the container is set to hidden, so none of the headlines would be showing — until they were ready.
Set Up the jQuery
At the top of the jQuery file I defined variables for the total number of headlines, the interval between headlines, the current headline, and the "old" headline:
-
var headline_count;
-
var headline_interval;
-
var current_headline = 0;
-
var old_headline = 0;
Then I set the headline_count variable to be the number of div elements that have a class of "headline." But that number can't be computed until the DOM is loaded, so I wrapped the variable in jQuery's $(document).ready() function. I also wanted to set the first headline's "top" property so that it would be immediately visible, while the others would remain hidden — at least initially — below the box (as set in the CSS):
.top() method, which, as of jQuery 1.1, no longer works. You will need to use .css('top', 'Npx') instead.Before we move on, I'd like to point out a few things about the above code:
- jQuery has a
.size()function that is similar to JavaScript'slengthproperty in that it returns the number of jQuery objects defined by the$()that comes before it. - The second line is only fired once, when the DOM is first loaded. Instead of setting every headline's top to 5px, it uses a special jQuery DOM selector,
:eq(), to set only the current headline's top. Typically,:eq()would take a number, like so:$("div.headline:eq(0)"). - I chose to pass in the "current_headline" variable instead of a number to allow for a little flexibility. If I later decide I want to start with the fourth headline, for example, I'd just have to change
var current_headline = 0up at the top of the script tovar current_headline = 3. In order to get the variable in there, though, I had to concatenate it with the rest of the selector before and after it.
Everybody Rotate!
Now that everything was in place, I could write my headline_rotate() function. I first needed to increment each headline by one until I reached the last one and then start over, creating a loop. To do so, I used what my friend Jonathan Chaffer told me is called "clock arithmetic." Here is what that looks like (at least, the way I did it):
-
function headline_rotate() {
-
current_headline = (old_headline + 1) % headline_count;
-
}
Line 2 sets a new value for current_headline by first adding 1 to old_headline and then using the modulus operator (%) to get the remainder of old_headline + 1 (our new headline) divided by headline_count (total number of headlines). Jonathan explained it this way: "the remainder will always equal old_headline + 1 until it reaches headline_count, at which point the remainder becomes zero." The only thing better than having a genius working next to me is having a genius who is great at explaining things to mere mortals like me.
Add the Animation
Next I added the animation into the headline_rotate() function — moving the old headline up and out of sight while moving the next headline (now called current_headline) into view.
The old headline movement actually has two parts: (a) scrolling up and out of sight and (b) moving instantly back down underneath the box so that it's ready to slide up into the box again the next time. This is where jQuery's "callbacks" come in very handy. I could queue the second effect by putting it in the callback of the first. Compare just the first effect...
...to the first, plus the second in the callback...
By the way, the -205 in .animate({top: -205}) means that the top of the headline moves to 205 pixels above the top of its containing element (because the containing element had its position set to relative) so that we're sure the entire headline clears the box.
For the current headline, I simply moved its top up to 5 pixels below the top of the scrollup box so that it would be visible. And after that, I made old_headline equal current_headline:
-
old_headline = current_headline;
-
}
To get the function to run when the page loaded, I simply dropped headline_rotate() inside my $(document).ready(). Unfortunately, that only made the animation fire once. I wanted it to repeat.
And Repeat
Remember that headline_interval variable I included way at the top? Here is how I used it:
Still inside $(document).ready(), I replaced headline_rotate() with headline_interval = setInterval(headline_rotate,5000);. That made JavaScript's setInterval() trigger my headline_rotate() function once every 5000 milliseconds (5 seconds).
Bonus – Pause on Hover!
I was fairly satisfied with the way the headline rotator worked, but I realized that for it to be really useful I'd want to make it pause when the mouse would hover over the box and start up again as soon as the mouse went back out. I'm not sure that I did it the best way, but it seems to have worked fairly well for me. I attached jQuery's hover() method to the "scrollup" div. The hover() takes two arguments, the first for mouseover and the second for mouseout. In the mouseover part, I stop the "interval," and in the mouseout part, I started it back up and called headline_rotate() again so the next headline would show up immediately:
-
clearInterval(headline_interval);
-
}, function() {
-
headline_interval = setInterval(headline_rotate,5000);
-
headline_rotate();
-
});
That hover stuff also went inside $(document).ready(), and then I was done!
The Full Code
I set up a demo page with the full code and CSS embedded in the <head>, so if you want to take a look and copy it for your own use, go ahead. Or, take a look at the full jQuery code below:
-
var headline_count;
-
var headline_interval;
-
var old_headline = 0;
-
var current_headline = 0;
-
-
-
headline_interval = setInterval(headline_rotate,5000);
-
clearInterval(headline_interval);
-
}, function() {
-
headline_interval = setInterval(headline_rotate,5000);
-
headline_rotate();
-
});
-
});
-
-
function headline_rotate() {
-
current_headline = (old_headline + 1) % headline_count;
-
$("div.headline:eq(" + old_headline + ")")
-
});
-
$("div.headline:eq(" + current_headline + ")")
-
old_headline = current_headline;
-
}
If you have any questions about the code or suggestions for improvement, please leave a comment.
UPDATE
Jonathan Chaffer and I wrote a much-improved version of this headline reader and discuss it in detail in the Learning jQuery book.You can see a demo of it on the companion site. Also, Mike Alsup has written the brilliant Cycle plugin that does the scroll-up effect and much, much more. Check it out!



October 16th, 2006 at 4:00 pm
I really like your tutorials! Wish there were more of them!
One observation: It seems inefficient to continuously create new jQuery objects:$("div.headline:eq(" + current_headline + ")") Can't you just create one and then somehow access the different headlines within it?
Here's a suggestion for future tutorials: I've been trying to understand the code behind some of the more popular plugins (at jquery.com) such as Accordion http://fmarcia.info/jquery/accordion.html and sometimes they are written at such a high level that there are parts I just don't understand. If you could take a pluggin and explain how it works (line by line) it would be great!
October 16th, 2006 at 5:15 pm
Hi Erin, thanks for the comment and the suggestions! You may be right about the inefficiency of creating the jQuery objects; I'll have to look into that.
I wish there were more of the tutorials, as well.
And there will be, as time goes on. The blog is still in its infancy, so stay tuned. Good idea about looking "behind the scenes" of popular plugns. I'll try to add that to the list of upcoming entries.
October 17th, 2006 at 11:02 am
How about this:
October 17th, 2006 at 3:10 pm
Erin, that looks good to me. Thanks again!
By the way, I dressed up your comment's code a bit and deleted the first two failed attempts for you.
October 17th, 2006 at 6:05 pm
Thanks Karl. The code was truncating at the "less than" in the for loop.
January 24th, 2007 at 5:53 am
Can you whip out a version which allows display of multiple headlines instead of 1-by-1.
such as
http://javascript.internet.com/text-effects/ajscroller.html
January 24th, 2007 at 9:41 am
Sure can, Kevin. It might take me a while to actually get to it, but look for a new entry sometime next week.
January 25th, 2007 at 12:22 am
Thanks Karl. Looking forward to it!
The ability to manipulate headlines directly in html instead of in the javscript really attracts. Gd job.
February 9th, 2007 at 11:53 am
hi karl, your single line scroller is pretty neat (i've integrated it with a project in cakephp). i'd also be interested in a means to scroll multiple headlines. will look out for an update soon
February 9th, 2007 at 12:01 pm
Thanks, Mike. Glad you like it. The multi-headline scroller is a bit trickier than I had thought at first, because of the headlines' varying heights. I will definitely post an entry on it, but it might be a while before I can get to it and give it some sustained thought.
February 23rd, 2007 at 5:10 pm
It was originally meant to be used on http://www.intuit.com. Unfortunately, I think they removed it after I left. I kept a copy here. Check the bottom right box.
It is a great widget. Well done!
March 21st, 2007 at 5:26 am
Oh, it's wonderful! I'm a JavaScript beginner and also a jQuery beginner, but I could really understand what you say, even though my mother language is Chinese, thank U!!!
May 6th, 2007 at 2:01 pm
Hi Karl,
Seems that your demo page example (http://test.learningjquery.com/scrollup.htm) doesn't work neither in Firefox nor in Opera (only in IE). At the same time an example at the beginning of this article works fine. Any explanation?
May 6th, 2007 at 5:58 pm
Hi Victor, thanks for notifying me of the problem with the demo page. I wrote the script last fall before version 1.1 and its API change. Before 1.1, we could use a shorthand method such as
.top()in place of.css('top'), but those shorthand methods have been removed.I updated the demo script on the test site, so it should be working just fine now. Thanks again for catching the problem.
May 14th, 2007 at 10:35 am
Nice script !
But it would be nice with a 'previous' and a 'next' button to skip the news
May 20th, 2007 at 11:31 pm
[...] product and public site this week. Uses a bunch of jQuery, Tabs Plugin, Validation Plugin and Scrolling Promo Effect. Design was done by Sean Zimmerman. HTML Production was done by NetKitchen and myself. [...]
June 6th, 2007 at 1:51 pm
We did a website based off this script except that our news has a counter:
1 of 10
a "pause" and "next" buttons. You can see it in action here:
http://www.crestwoodbaptist.org/
source code available from the site using "view source"
June 6th, 2007 at 4:17 pm
Hi,
i look for a script like this, thx.
But one question:
When a User has JS off in the Browser nothing will display. Is there e way with JS off that all News will display with a vertical scrollbar?
Sry for my poor english...
greetings Markus
June 7th, 2007 at 12:26 am
Markus, I'm really glad you asked that question. This script should definitely degrade better than it does. Here is one way you can make it look good without JavaScript:
1. make these changes (in bold) to the stylesheet
2. Then, to get it looking sharp again with JavaScript, replace this line:
with this:
Let me know how that works for you.
June 7th, 2007 at 12:28 am
Randy, Nice work on your variation of the script. I like your additions!
June 7th, 2007 at 12:45 pm
Hi Karl,
thx for help. I will try it later.
Now i found a littel "Bug". Using IE7 and move the mouse over the scroller he didn´t stop. When moved the mouse in the scroller to any direction it looks crazy...
mfg Markus
June 14th, 2007 at 1:16 pm
Is there a version of this that would use an unordered list instead of a stack of nested DIVs?
June 14th, 2007 at 1:37 pm
Hi Alex. I haven't written a version that would use an unordered list instead, but I don't think it would be hard to modify this one. If you used
<ul id="scrollup">and<li class="headline">, then I think it would mostly be a matter of modifying the CSS a bit and changing references to "div.headline" in the code to "li.headline"If you'd like to give that a whirl, feel free to contact me if you get stuck along the way.
July 28th, 2007 at 5:56 pm
Hi Karl, thanks alot for your tutorial...
i ve modified your code a bit, i ve changed divs to unordered list and vertical scrolling to horizontal scrolling.
here is the modified version:
http://www.emrecamdere.com/news_scroller_jquery.html
i hope it ll be useful for someone
July 30th, 2007 at 4:36 am
it not works on IE7
September 5th, 2007 at 9:18 pm
I am looking for a code that scrolls up, pauses, then scrolls news to the left or right, then with the next news story it scrolls up, pauses, then scrolls news to the left or right again. Can the two codes mentioned be combined in someway to accomplish this action? Thanks for the tutorial!
September 13th, 2007 at 6:34 am
Hi!
First of all, thanks for this very useful script.
I've got a problem with Flash. Have you ever tried to include an swf object in one of the headlines? While it works in IE7, the flash animation gets stuck in the bottom of #scrollup in Firefox and doesn't scroll. I imagine that your script is not to blame but the way Firefox interpret the object tag but if by any chance, you've encountered the problem...
Once again, thanks for your work and have a nice day
September 13th, 2007 at 10:23 am
Hi Laurent,
I'm sorry, but I have very little experience with Flash. You might have better luck with Mike Alsup's Cycle plugin. It's very solid with tons of features.
September 21st, 2007 at 4:38 pm
thank you for your straightforward and functional tutorial
October 5th, 2007 at 7:23 pm
[...] Learning jQuery » Scroll Up Headline Reader (tags: jquery scroller) [...]
October 11th, 2007 at 5:52 pm
Hi Karl,
Thanks a LOT for this. I never knew about jQuery! but this really is like magic!! Cant wait to go home and get my hands dirty with this. Also, do you know if the dzone scroll functionality where more headlines are loaded as the user is about to reach the end of the page is also done in jQuery?
If you have some code that would kind of show how to achieve that it would be wonderfull!!
Thanks for this!!
November 5th, 2007 at 10:25 am
Hi Karl,
Thank you for the script, it's very nice. But I have a problem.
I use the toggle() function to display and hide the headline div. When I click on the link (which hides the headline div), and click again (displays the headline div again), it starts rolling again, but it looks like this: picture
November 20th, 2007 at 2:13 pm
Hi all. i´m Miguelito ( newbe in jQuery from Spain)
I have to do a continuos scroll function to a div with html structure like this:
div-class listaScroll) ul li li li li /ul /div
each li has html inside ( news to scroll)
it works, but surelly you can hep me with some 'bugs'
1.- Rest-of-the-page-links does not work if i do not 'stop' the timer properly
2.- multiple divs in same page scrolling: scrolls at same time, stops in same time
any ideas ?
URL: my site (i´m modifiyng it)
Thanks for your time!.
( I´m using jquey.timer.js for timers, but maybe innecesary, or maybe it´s the problem. I´m new with jquery timer events
)
CODE:
jQuery(document).ready(function(){
initScroll();
jQuery(".listaScroll ul li a").hover( stopScroll, initScroll);
function initScroll(){
jQuery(".listaScroll").everyTime(3000, 'miTimer', scrollUp);
}
function scrollUp() {
var elemParent=jQuery(this).find("ul:eq(0)").get();
jQuery(elemParent).find("li:eq(0)").hide(2000, function(){
jQuery(this).appendTo(elemParent).show(); //mode element to the end
});
}
function stopScroll(){
jQuery(".listaScroll").stopTime("miTimer");
}
jQuery("a").click( function(){ // ehem... it stops the scroll, so the links work again...
stopScroll();
return true;
});
});
December 9th, 2007 at 2:47 pm
How I can make script to work with an external scrollup div inserted in document with Ajax?
December 9th, 2007 at 2:57 pm
How I can make script to work with a scrollup div that contain an external html file inserted in document (div) with Ajax?
January 21st, 2008 at 7:11 am
if we put dynamic content...how we handle height thing...
mean how height should be auto fitted to each loading....because in my case that viewing area should be changed with it loaded no of items...so..how can we handle that kind of thing...pls tell me thanks
February 11th, 2008 at 3:23 am
This is what's I looking for, I have a question.
How to integrated this code with this effect
http://www.malsup.com/jquery/cycle/begin.html
Please Help me and thanks
April 24th, 2008 at 9:18 am
very good tut, it really help me, thanks!
August 14th, 2008 at 10:56 am
i have used the headline scroller on a couple of pages with good success. However, on 2 of my pages, when the page is visited, all of the headlines show up at first and after the first interval they scroll correctly. you can see what i mean here at
www.axessnetwork.com and;
www.buckstoparchery.com
also, on the buckstop archery site, i have a flash element in the scroller. When opened with Mozilla Firefox, the flash element shows up constantly just below the div area. Can anyone advise? Thanks.
August 14th, 2008 at 11:43 am
Hi Josh,
on the axessnetwork site, you can probably fix the problem by changing this:
to this:
I don't see the problem with the Flash element in FF3 Mac, but one thing you might want to try is to set the Flash object's "wmode" property/attribute to "transparent."
August 17th, 2008 at 7:44 pm
Thanks for the help. That made all the difference. I am not sure why it loaded all the info into the DIV at once. I have used this script on numerous sites and those are the only 2 that i had problems with. The .siblings rule cleared it up. Thanks.
Josh