In this article we will build an RSS / Twitter news-feed-reader-ticker. Yeah, that’s a mouth full, but you know what I’m talking about, right? This news/RSS/Twitter ticker will query web services using jQuery and return JSON results which we will then display in a scrolling ticker. Oh, hell just click the example below and see for yourself.
Click here to view scrolling ticker
There’s probably a handful of plugins that will achieve the same result, but as you will see there’s not much code needed to do it yourself. Let’s look at the code now.
- var feedItems = [];
- var twitterUser = "scottgu";
- //http://developer.yahoo.com/yql/console/
- var feed1 = {
- url: 'http://query.yahooapis.com/v1/public/yql?q=select%20title%2Clink%2CpubDate%20from%20rss%20where%20url%3D%22http%3A%2F%2Fweblogs.asp.net%2Fscottgu%2Frss.aspx%22&format=json&diagnostics=true&callback=?',
- type: 'rss'
- };
- var feed2 = {
- url: 'http://search.twitter.com/search.json?callback=?&rpp=15&since_id=0&q=from:' + twitterUser,
- type: 'twitter'
- };
The first thing we do is create two feed objects. These objects consist of a url and a type. The url points to an external service (Twitter or YQL) that returns the JSON we will use for each item in our feed ticker. The Yahoo Query Language (YQL) service is a really handy tool that allows you to give it an RSS feed url and it then returns JSON. So I’m giving it Scott Guthrie’s RSS feed link. And it now gives me JSON.
I am also using the Twitter service to get tweets from Scott Gu as well. Twitter is nice enough to give us JSON back from their API.
- //RSS
- var request1 = $.getJSON(feed1.url, function (data) {
- $.each(data.query.results.item, function (i, value) {
- // Before we continue we check that we got data
- if (value.title !== undefined) {
- var sub2 = value.pubDate.substring(0, 16);
- var item = {
- url: value.link,
- message: value.title,
- from: feed1.type,
- date: sub2
- };
- feedItems.push(item);
- }
- });
- });
- //Twitter
- var request2 = $.getJSON(feed2.url, function (data) {
- $.each(data.results, function (i, value) {
- // Before we continue we check that we got data
- if (value.text !== undefined) {
- // Calculate how many hours ago was the tweet posted
- var dateOf = new Date(value.created_at);
- var dateNow = new Date();
- var dateDiff = dateNow - dateOf;
- var hours = Math.round(dateDiff / (1000 * 60 * 60));
- var item = {
- url: "http://twitter.com/#!/" + twitterUser + '/status/' + value.id_str,
- message: value.text,
- from: feed2.type,
- date: hours + " hours ago"
- };
- feedItems.push(item);
- }
- });
- });
- $.when(request1, request2).then(function () {
- BuildFeedReader();
- });
The next thing to do is use jQuery’s jQuery.getJSON() to call the YQL and Twitter services. These services return JSON arrays, which we then loop through. With each iteration we build an item object and add it to our feedItems array. When we are done our feedItems array will hold all the items for each line in our feed ticker.
The jQuery.when() method is perfect here, because it provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. Which is exactly what we have here. So when BOTH asynchronous events are complete we call the BuildFeedReader method.
- function BuildFeedReader() {
- $.shuffle(feedItems);
- var strBuilder = "";
- $.each(feedItems, function (index, value) {
- strBuilder += '<dd class="feed-' + value.from + '"><a href="' + value.url + '" target="_blank" ><div>' + value.date + '</div>' + value.message + '</a></dd>';
- });
- var ticker = $("#ticker");
- ticker.html(strBuilder);
- //animator function
- function animator(currentItem) {
- //work out new anim duration
- var distance = currentItem.height();
- duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.02;
- //animate the first child of the ticker
- currentItem.animate({ marginTop: -distance }, duration, "linear", function () {
- //move current item to the bottom
- currentItem.appendTo(currentItem.parent()).css("marginTop", 0);
- //recurse
- animator(currentItem.parent().children(":first"));
- });
- };
- //start the ticker
- animator(ticker.children(":first"));
- //set mouseenter
- ticker.mouseenter(function () {
- //stop current animation
- ticker.children().stop();
- }).mouseleave(function () {
- //resume animation
- animator(ticker.children(":first"));
- });
- }
Within the BuildFeedReader function we call $.shuffle(). As the name implies this takes and array and shuffles up its items. This takes our RSS items and our Twitter items and shuffles them up. You can skip this if you don’t want random results.
Next we iterate through our feedItems array building our html string. When done we add the html string to our ticker DOM element.
The last thing we do is add the mouseenter and mouseleave event handlers. On mouseenter we stop the ticker and re-animate it on mouseleave.
- //Shuffle Array Up
- $.fn.shuffle = function () {
- return this.each(function () {
- var items = $(this).children();
- return (items.length) ? $(this).html($.shuffle(items)) : this;
- });
- }
- $.shuffle = function (arr) {
- for (
- var j, x, i = arr.length; i;
- j = parseInt(Math.random() * i),
- x = arr[--i], arr[i] = arr[j], arr[j] = x
- );
- return arr;
- }
The last bit of code was our shuffle function used to random up the results of an array.
You are done. Hope your enjoy your RSS feed / Twitter feed ticker.
October 8th, 2012 at 9:47 pm
I want to use this on a website I’m building and want a certain users tweets…twitter states that search.twitter is not a good way to pull user tweets. Anyway you can make the above using twitters API integrated with Json?
January 23rd, 2013 at 8:36 pm
We’re having our web person implement this. Thanks for sharing!