jQuery: rotatore di tweet per Twitter

jQuery: rotatore di tweet per Twitter

Un rotatore di tweet per Twitter può essere realizzato con jQuery non solo ottenendo i tweet presenti in un feed JSON di Twitter, ma anche animandoli con un effetto di comparsa e scomparsa a rotazione. Inoltre vogliamo fornire agli utenti la possibilità di fermare la rotazione posando il mouse su ciascun tweet e di farla riprendere cliccandoci sopra. Qual'è il segreto dell'implementazione? Non sono i timer JavaScript nè gli eventi, ma lo scope del metodo $.getJSON(): infatti è al suo interno che vanno eseguite le animazioni e la gestione degli eventi. Questo è dovuto al fatto che tale metodo è un metodo AJAX, e quindi il codice eseguito al suo esterno non può avere accesso ai dati creati al suo interno. Vediamo insieme i dettagli dell'implementazione.

Creiamo subito un contenitore per i tweet:


<div id="twitter"></div>

Diamo alcune regole di stile ai tweet, fra cui quella importantissima ai fini dell'animazione, ossia display: none:


body {
	margin: 0;
	padding: 2em 0;
	font: 100% Arial, sans-serif;
}

#twitter {
	margin: 0 auto;
	padding: 1em;
    width: 30em;
}

div.tweet {
	background: #eee url(twitter.png) no-repeat 5px 5px;
	padding: 1em 1em 1em 75px;
	margin: 1em 0;
	border-radius: 10px;
	line-height: 1.4;
	display: none;
}

div.tweet a {
	color: #d34545;
}

div.tweet small {
	display: block;
}

Ora ci serve un oggetto, che chiameremo TwitterTicker, con i seguenti metodi:

  1. relativeTime(): Metodo helper privato per calcolare il tempo trascorso per ogni tweet. Non rilevante ai fini del nostro esempio.
  2. replaceURLs(): Metodo helper privato per trasformare URL testuali in link HTML. Anch'esso non rilevante.
  3. fetch(): Metodo privato che reperisce il feed JSON di Twitter, lo formatta in HTML e lo inserisce nel contenitore dei tweet. Questo metodo invoca anche il metodo run(), che gestisce le animazioni e gli eventi.
  4. run(): Metodo privato che crea un indice incrementale da usare con il metodo eq() all'interno di un timer JavaScript. Con questo indice viene selezionato il tweet corrente che viene animato con il metodo slideDown(), mentre tutti gli altri tweet vengono nascosti. A ciascun tweet vengono associati un evento mouseover e uno click. Con il primo, viene fermato il timer usando clearInterval(). Con il secondo, tutti i tweet vengono nascosti e viene invocato di nuovo il metodo run() per far riprendere la rotazione.
  5. init(): Metodo pubblico che invoca fetch().

Ecco il codice dell'oggetto:


var TwitterTicker = new function() {

  var options = {
    username: 'gabromanato',
    limit: 3
  };

  var url = 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=' + 
             options.username + '&count=' + options.limit + '&callback=?';
             
             
  var relativeTime = function(time_value) {
      var values = time_value.split(" ");
      time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
      var parsed_date = Date.parse(time_value);
      var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
      var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
      delta = delta + (relative_to.getTimezoneOffset() * 60);

      if (delta < 60) {
    	return 'less than a minute ago';
  	  } else if(delta < 120) {
        return 'about a minute ago';
      } else if(delta < (60*60)) {
        return (parseInt(delta / 60)).toString() + ' minutes ago';
      } else if(delta < (120*60)) {
        return 'about an hour ago';
      } else if(delta < (24*60*60)) {
        return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
      } else if(delta < (48*60*60)) {
        return '1 day ago';
      } else {
        return (parseInt(delta / 86400)).toString() + ' days ago';
      }
    };
    
    var replaceURLs = function(text) {
    
      var replaced = text.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, '<a href="$&">$&</a> ');
      
      return replaced;
    
    
    
    };

             
             
  var fetch = function() {
  
    
    
    $.getJSON(url, function(data) {
        
        var htmlString = '';
               
        $.each(data, function(i, item) {
        
          var tweet = replaceURLs(item.text);
          var time = relativeTime(item.created_at);
          
          htmlString += '<div class="tweet">' + tweet +
                        '<small>' + time + '</small>' +
                        '</div>';
        
        });
      
      
      $(htmlString).appendTo('#twitter'); 
      
      run();
      
    });
         
  };
  
  var run = function() {
  
  
    
    var tweets = $('div.tweet', '#twitter');
    var limit = tweets.length;
    var index = 0;
    
    var timer = setInterval(function() {
    
      var that = this;
    
      index++;
      
      if(index == limit) {
      
        index = 0;
      
      
      }
    
     tweets.eq(index).slideDown(2000).
     siblings().hide().end().mouseover(function() {
     
       clearInterval(timer)
     
     }).click(function() {
     
       tweets.hide();
     
       run();
     
     });
    
    }, 2000);
        
  
  
  
  };
  
  this.init = function() {
  
    fetch();
  
  };

}();

Questo oggetto viene usato in questo modo:


$(function() {

  TwitterTicker.init();

});

Potete visionare l'esempio finale in questa pagina.

Torna su