Stamani mi sono imbattuto in questo interessante tutorial che mostra come realizzare un aggregatore di tweet per Twitter con effetto di scorrimento. In realtà il titolo è alquanto fuorviante, nel senso che lo scorrimento dei tweet non è automatico ma manuale e realizzato con l'ausilio del plugin jQuery jScrollPane. Mi sono altresi reso conto che alcuni dettagli dell'implementazione non sono del tutto chiari. Vediamoli insieme.
Aggregare tweet da diverse fonti
Per aggregare tre fonti diverse di tweet viene usato il seguente codice:
var tweetUsers = ['tutorialzine','TechCrunch','smashingmag','mashable'];
var buildString = "";
$(document).ready(function(){
$('#twitter-ticker').slideDown('slow');
for(var i=0;i<tweetUsers.length;i++)
{
if(i!=0) buildString+='+OR+';
buildString+='from:'+tweetUsers[i];
}
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", "http://search.twitter.com/search.json?q="+buildString+"&callback=TweetTick&rpp=50");
document.getElementsByTagName("head")[0].appendChild(fileref);
});
Viene usato un file JSONP remoto (ottenuto tramite un elemento script
generato dinamicamente) a cui vengono passati due parametri definiti nell'esempio:
buildString
: stringa avente come delimitatore un operatore booleano (OR
) e come valorifrom:
i nomi degli utenti contenuti nell'arraytweetUsers
callback
: una funzione eseguita in locale operante sull'oggetto JSON restituito (in questo caso la funzione èTweetTick(object)
)
Usare una funzione di callback sull'oggetto JSON
La funzione usata come callback è la seguente:
function TweetTick(ob)
{
var container=$('#tweet-container');
container.html('');
$(ob.results).each(function(el){
var str = ' <div class="tweet">\
<div class="avatar">
<a href="http://twitter.com/'+this.from_user+'" target="_blank">
<img src="'+this.profile_image_url+'" alt="'+this.from_user+'" /></a>
</div>\
<div class="user">
<a href="http://twitter.com/'+this.from_user+'" target="_blank">'
+this.from_user+'</a></div>\
<div class="time">'+relativeTime(this.created_at)+'</div>\
<div class="txt">'+formatTwitString(this.text)+'</div>\
</div>';
container.append(str);
});
container.jScrollPane();
}
Questa funzione opera sull'oggetto JSON che contiene i dati relativi agli utenti selezionati. Infatti il suo parametro è appunto l'oggetto JSON. La funzione si limita ad eseguire un ciclo sull'oggetto results
assemblando una stringa HTML contenente l'URL dell'utente, l'immagine del profilo, la data del tweet e il contenuto del tweet stesso.
Il plugin jScrollPane viene quindi invocato all'interno di questa funzione, poichè solo nel momento della creazione della nuova struttura DOM esso può operare.
Funzioni ausiliarie
La funzione principale esegue al suo interno anche due funzioni ausiliarie:
relativeTime(timestamp)
formatTwitString(text)
La prima calcola il tempo trascorso dall'ultimo tweet, mentre la seconda formatta i link testuali trasformandoli in link HTML:
function formatTwitString(str)
{
str= ' '+str;
str = str.replace(/((ftp|https?):\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?)/gm,'<a href="$1" target="_blank">$1</a>');
str = str.replace(/([^\w])\@([\w\-]+)/gm,'$1@<a href="http://twitter.com/$2" target="_blank">$2</a>');
str = str.replace(/([^\w])\#([\w\-]+)/gm,'$1<a href="http://twitter.com/search?q=%23$2" target="_blank">#$2</a>');
return str;
}
function relativeTime(pastTime)
{
var origStamp = Date.parse(pastTime);
var curDate = new Date();
var currentStamp = curDate.getTime();
var difference = parseInt((currentStamp - origStamp)/1000);
if(difference < 0) return false;
if(difference <= 5) return "Just now";
if(difference <= 20) return "Seconds ago";
if(difference <= 60) return "A minute ago";
if(difference < 3600) return parseInt(difference/60)+" minutes ago";
if(difference <= 1.5*3600) return "One hour ago";
if(difference < 23.5*3600) return Math.round(difference/3600)+" hours ago";
if(difference < 1.5*24*3600) return "One day ago";
var dateArr = pastTime.split(' ');
return dateArr[4].replace(/\:\d+$/,'')+' '
+dateArr[2]+' '+dateArr[1]+(dateArr[3]!=curDate.getFullYear()?' '+dateArr[3]:'');
}
Le stringhe vengono manipolate tramite il metodo replace()
e le espressioni regolari, ove $1
, $2
, $n
si riferiscono ai gruppi di corrispondenze trovate dal pattern nella stringa passata come parametro.
Il tempo viene invece calcolato partendo dalla stringa temporale del tweet, normalizzata tramite il metodo parse()
dell'oggetto Date
e sottratta alle coordinate temporali attuali, ottenute tramite il metodo getTime()
del medesimo oggetto Date
. Il risultato della sottrazione viene diviso per 1000 e approssimato ad un intero per ottenere i millisecondi corrispondenti. Tale risultato viene poi confrontato con delle costanti numeriche che ci permettono di calcolare secondi, minuti, ore e giorni trascorsi dall'ultimo tweet.
Vi rimando al demo originale per visionare l'esempio finale.