News RSS feed widget

Adesso creeremo uno slider che visualizzare una news per volta automaticamente ricavando le stesse da un RSS feed

Prima di tutto scriviamo un po' di HTML:


<div id="sidebar">
<h3>Recent News</h3>
<div id="news-feed">
<a href=news/index.html>News Releases</a>
</div>
</div>

E' stato previsto un link alla pagina delle news, nel caso Javascript non sia abilatato.

Quindi ci serve del CSS:

#news-feed {
  position: relative;
  height: 200px;
  width: 17em;
  overflow: hidden;
}
.headline {
  position: absolute;
  height: 200px;
  top: 210px;
  overflow: hidden;
}

Cose importanti del CSS:

Javascript code:

$(document).ready(function() {
$('#news-feed').each(function() {
$(this).empty();
}); });

Al caricamento della pagina, svuoto il contenitore delle news dal link presente nel caso javascript sia abilitato

Ecco il mio bellissimo contenitore vuoto: News RSS feed widget step 1



Adesso carichiamo l'xml con una chiamata ad un feed RSS:

Javascript code:

$(document).ready(function() {
$('#news-feed').each(function() {
$(this).empty();
$.get('news/feed.xml', function(data) {
$(data).find('item').each(function() {//$('/rss//item', data)
var title = $('title', this).text();
//alert(title);
var linkText = $('link', this).text();
var $link = $('<a></a>')
.attr('href', linkText)
.text(title);
$link = $('<h3></h3>').html($link);
var pubDate = new Date($('pubDate', this).text());
var pubMonth = pubDate.getMonth() + 1;
var pubDay = pubDate.getDate();
var pubYear = pubDate.getFullYear();
var $pubDiv = $('<div></div>')
.addClass('publication-date')
.text(pubMonth + '/' + pubDay + '/' + pubYear);
var summaryText = $('description', this).text();
var $summary = $('<div></div>')
.addClass('summary')
.html(summaryText);
$('<div></div>')
.addClass('headline')
.append($link)
.append($pubDiv)
.append($summary)
.appendTo('#news-feed');
});
});
});
});

Analizziamo il codice:

Ecco il risultato: News RSS feed widget step 2

Come vedete ancora pagina bianca, ma in realtà se controllate il codice generato (Web developer toolbar > view source > view generated source), trovate tutto il nostro HTML generato, che non si vede a causa del CSS di cui sopra (provate a cambiare il valore top della classe .headline!



Ora facciamo apparire la prima news: per fare questo, al caricamento della pagina dovrò cambiare la proprietà CSS top della prima notizia:

Javascript code:

$(document).ready(function() {
$('#news-feed').each(function() {
var currentHeadline = 0; var oldHeadline = 0; var hiddenPosition = $('#news-feed').height() + 10; $(this).empty();
$.get('news/feed.xml', function(data) {
$(data).find('item').each(function() {//$('/rss//item', data)
var title = $('title', this).text();
//alert(title);
var linkText = $('link', this).text();
var $link = $('<a></a>')
.attr('href', linkText)
.text(title);
$link = $('<h3></h3>').html($link);
var pubDate = new Date($('pubDate', this).text());
var pubMonth = pubDate.getMonth() + 1;
var pubDay = pubDate.getDate();
var pubYear = pubDate.getFullYear();
var $pubDiv = $('<div></div>')
.addClass('publication-date')
.text(pubMonth + '/' + pubDay + '/' + pubYear);
var summaryText = $('description', this).text();
var $summary = $('<div></div>')
.addClass('summary')
.html(summaryText);
$('<div></div>')
.addClass('headline')
.append($link)
.append($pubDiv)
.append($summary)
.appendTo('#news-feed');
});
var headlineCount = $('div.headline').length; var headlineTimeout; $('div.headline:eq(' + currentHeadline + ')').css('top','0'); });
});
});

Analizziamo quello che abbiamo aggiunto:

Ecco il risultato: News RSS feed widget step 3



Adesso facciamole muovere:

Javascript code:

$('div.headline:eq(' + currentHeadline + ')').css('top','0');
var headlineRotate = function() {
currentHeadline = (oldHeadline + 1) % headlineCount;
$('div.headline:eq(' + oldHeadline + ')')
.animate({top: -hiddenPosition}, 'slow', function() {
$(this).css('top',hiddenPosition);
}); $('div.headline:eq(' + currentHeadline + ')')
.animate({top: 0},'slow', function() {
headlineTimeout = setTimeout(headlineRotate, 5000);
});
oldHeadline = currentHeadline;
};

headlineTimeout = setTimeout(headlineRotate,5000);

Quindi: abbiamo scritto una funzione headlineRotate che incrementa l'indice della news corrente e calcola a che indice siamo, poi muovo i relativi elementi:

Ecco il risultato: News RSS feed widget step 4



Aggiungiamo un po' d'interattività: quando un utente va con il mouse su una delle news, l'effetto di rotazione si deve fermare mentre sul mouseover deve ripartire (la funzione .hover() di JQuery accetta i due parametri)

Javascript code:

$('#news-feed').hover(function() {
	clearTimeout(headlineTimeout);
}, function() {
	headlineTimeout = setTimeout(headlineRotate, 250);
});

Ecco il risultato: News RSS feed widget step 5



Stiamo caricando un file esterno che sta sul nostro server. Ma in uno scenario reale? Ajax non consente chiamate crossdomain, per problemi di sicurezza. Però possiamo passare da un file php che apra i contenuti di un feed:

PHP code:

<?php 
header('Content-Type: text/xml');
print $feed = file_get_contents('http://jquery.com/blog/feed');
?>

Adesso mi basta sostituire il file php al file xml nella chiamata $.get()

Aggiungiamo inoltre, poichè adesso ci sarà un minimo di tempo di caricamento, un loader:

Javascript code:

$(document).ready(function() {
$('#news-feed').each(function() {
var currentHeadline = 0;
var oldHeadline = 0;
var hiddenPosition = $('#news-feed').height() + 10;


$(this).empty();

var $newsLoading = $('<img/>')
.attr({
'src': 'news/loading.gif',
'alt': 'loading. please wait'
})
.addClass('news-wait');
$(this).ajaxStart(function() {
$(this).append($newsLoading);
})
.ajaxStop(function() {
$newsLoading.remove();
});


$.get('news/feed.php', function(data) { [...]

Ecco il risultato: News RSS feed widget step 6



Tocco finale: aggiungiamo un effetto di fade

Javascript code:

var $this = $(this);
var totalheight = $this.height();
var fadeHeight = totalheight / 4;
for (var i = 0; i < fadeHeight; i+=2) {
$('<div></div>')
.css({
opacity: i / fadeHeight,
top: totalheight - fadeHeight + i
})
.addClass('fade-slice')
.appendTo($this);
}

In pratica creiamo 25 div alti 2px e li posizionamo uno dietro l'altro infondo al box delle news con un valore di opacità sempre crescente

Ed ecoo il nostro widget: News RSS feed widget step 7