Thématiques :

Réalisez un bandeau de news en jQuery, comme sur iTélé

Posé ici le mardi 22 septembre 2009 à 13:35 par Jay Salvat

Un bandeau de news en jQuery, comme à la TV.

Je ne sais pas pour vous, mais moi, dès que je regarde une chaine d'information, je suis hypnotisé par les barres de news qui défilent en bas de l'écran. Je n'arrive pas à en détacher les yeux. Personnellement, je trouve celles de iTélé particulèrement réussies.

Je me suis dit que ce traitement des brèves infos pouvait être une belle manière d'annoncer les mises à jour d'un site web. Bien évidement en tant qu'obsédé de jQuery, je me suis amusé à réaliser un effet similaire. Le voici.

NOTE : Si vous êtes lié à iTélé et que vous pensez que l'utilisation du logo iTélé afin d'illustrer l'article est abusive, contactez-moi. Je le supprimerai aussitôt.

Voir la Démo

Ce que je veux

Je veux que mon plugin soit le plus inobstrusif possible et puisse s'appliquer à du code HTML sémantique. Les listes de définitions DL, DT et DD sont lesplus adaptées à la présentation de news : Propre et facile à mettre à jour.

<dl id="iTvScroller">
    <dt>Corse</dt>
    <dd>Un jeune touriste tué par balle par un videur de discotheque a Olmeto Plage</dd>
    
    <dt>Faits divers</dt>
    <dd>Accident d'ULM dans le Doubs : deux blessés</dd>
    
    <dt>Formule 1</dt>
    <dd>Le Français Sébastien Bourdais écarté de l'écurie Toro Rosso</dd>
    
    <dt>Inflation</dt>
    <dd>Nouvelle baisse des prix sur un an (-0,5%) en juin</dd>
    
    <dt>Honduras</dt>
    <dd>Le gouvernement rétablit un couvre-feu</dd>
</dl>

Une fois notre liste mis en place, il faut la faire ressembler à ça :
Liste après CSS

Mise en forme

Une fois n'est pas coutume, je vais commencer à me présenter la feuille de styles. Il est à noter que la liste porte l'id #iTvScroller. Toutes les news seront masquées, sauf la première. Le premier DT portera la classe .first, le deuxième la classe .second. Ces modifications seront effectuées par le script lui-même.

Classes

Quatre fonds d'images sont utilisées pour les titres. Elles se nomment selon leurs couleurs, respectivement red.png pour le premier titre, red-black.png pour le second titre, black-black.png pour tous les autres boutons et black.png pour la barre de titre.

Maintenant vous devriez y voir plus clair dans la feuille de style qui suit. J'y ai ajouté quelques annotations.

#iTvScroller {
    background:#000 url('images/black.png') repeat-x top left;
    font:14px "Trebuchet MS", Tahoma, sans-serif;
    margin:0;
    width:100%; height:80px;
    /* Position en bas de l'écran */
    position:fixed; left:0; bottom:0; 
}
#iTvScroller dt {
    color:#999;
    font-weight:bold;
    line-height:30px;
    height:30px;
    padding:0 20px 0 30px;
    /* Les titres ont un fond noir */
    background:#000 url('images/black-black.png') center left;  
    /* Les titres sont mis côte-à-côte */
    float:left;  
}
#iTvScroller dd {
    color:#FFF;
    font-size:150%;
    font-weight:bold;
    height:50px; line-height:50px;
    margin:0;
    padding:0 30px;
    position:absolute; bottom:0; left:0;
    /* Les textes sont masqués par défaut */
    display:none;
}
#iTvScroller dt.first {
    color:#FFF;
    /* Le 1er titre aura un fond rouge */
    background:#FF0000 url('images/red.png');
}
#iTvScroller dt.second {
    /* Le 2ème titre aura un fond rouge et une partie noire */
    background:#FF0000 url('images/red-black.png') center left;
}

Le plugin en question

Tapons directement dans le vif du sujet avec la totalité du plugin, agrémenté de quelques commentaires. Je reviens en détail par la suite sur les points clés.

/**
 * Un bandeau de news en jQuery, comme sur iTélé
 * par Jay Salvat - http://blog.jaysalvat.com/
 */
(function($) {
$.fn.iTvScroller = function(settings) {
    // Options
    var options =  {
        delay: 5000
    };
    $.extend(options, settings);
        
    return this.each(function(){
        var $$ = $(this);
        
        // Applique les classes au 1er et 2ème DT
        $('dt', $$)
            .eq(1).addClass('second').end()
            .eq(0).addClass('first');

        // Fait apparaitre doucement la première news
        $('dd', $$).eq(0).fadeIn('slow');
        
        // Appelle la méthode scrollTitles() toutes les x secondes
        setInterval(scrollTitles, options.delay);
        
        function scrollTitles() {
            // Traitement des DD
            $('dd', $$)
                // On les masque tous
                .hide()
                // On réaffiche celui qui nous intéresse : le suivant
                .eq(1).fadeIn('slow');

            // Traitement des DT
            $('dt', $$)
                // On réinitialise les classes de tous les titres
                .removeClass('first')
                .removeClass('second')
                // On réapplique les classes au 1er, 2ème et 3ème titre
                .eq(2).addClass('second').end()
                .eq(1).addClass('first').end()
                .eq(0).addClass('first')
                // Puis on déplace les titres vers la gauche
                .animate( { marginLeft : '-150px'}, 1000, function() {

                    // Lorsque le déplacement est termine le 1er DT ne nous intéresse plus
                    var dt = $('dt', $$).eq(0)
                        // On réinitialise la marge à gauche
                        .css('marginLeft', 0)
                        // On supprime la classe
                        .removeClass('first')
                        // On le supprime
                        .remove();

                    // On supprime également le DD
                    var dd = $('dd', $$).eq(0).remove();

                    // On repose le DT et DD à la suite des autres titres
                    $$.append( dt.hide().fadeIn('slow'), dd );
                }
            )
        }    
    });
};
})(jQuery);

Dissection

Bon, maintenant que vous êtes experts en plugin jQuery, je ne reviens plus sur le B-A BA.

$('dt', $$)
    .eq(1).addClass('second').end()
    .eq(0).addClass('first');

On commence par appliquer les classes .first et .second aux titres.

$('dd', $$).eq(0).fadeIn('slow');

Puis on affiche la première news en fadeIn.

setInterval(scrollTitles, options.delay);

La fonction setInterval lance scrollTitles() à intervalle régulier. Cet intervalle est défini par l'utilisateur dans les options. Par défaut 5000, soit 5 secondes. Intéressons-nous maintennat à la fonction scrollTitles() qui se charge du roulement des news.

$('dd', $$)
    .hide()
    .eq(1).fadeIn('slow');

Toutes les news sont masquées. On affiche la suivante dans un joli fadeIn.

$('dt', $$)
    .removeClass('first')
    .removeClass('second')

Les classes .first et .second sont enlevés des titres pour repartir à zéro.

$('dt', $$)
    // ...
    .eq(2).addClass('second').end()
    .eq(1).addClass('first').end()
    .eq(0).addClass('first')

Le déplacement vers la gauche ne s'est pas encore produit. On applique les classes .first aux deux premiers titres et .second au troisième.

$('dt', $$)
    // ...
    .animate( { marginLeft : '-150px'}, 1000, function() { }

La rangée de titres est maintenant déplacée vers la gauche de 150px en 1 seconde (1000). Une fois l'animation terminée, la fonction anonyme passée en paramètre est lancée. Regardons ce qui s'y passe.

var dt = $('dt', $$).eq(0)
   .css('marginLeft', 0)
   .removeClass('first')
   .remove();

Le titre maintenant disparu hors écran est réinitialisé, on supprime la classe .first et on remet la marge gauche à zéro puis on le supprime complétement de la page.
Remarquez que ce titre est stocké au préalable dans la variable dt.

var dd = $('dd', $$).eq(0).remove();

Même chose pour le news en cours. Elle est supprimée mais stockée dans la variable dd.

$$.append( dt.hide().fadeIn('slow'), dd );

Le titre et la news précédemment stockés sont ajoutés à la fin de la liste afin qu'ils réapparaissent en boucle.

Télécharger le code

Usage

Organisez vos news dans une liste type définition DL, DT, DD. Appliquez-y par exemple l'id #iTvScroller.

<dl id="iTvScroller">
    <dt>Titre 1</dt>
    <dd>New 1</dd>
    
    <dt>Titre 2</dt>
    <dd>News 2</dd>
</dl>

Ensuite vous connaissez la rengaine. Il faut inclure jQuery et appliquer le plugin à votre liste.

<script type="text/javascript" >
$(function() {
    $('#iTvScroller').iTvScroller();
});
</script>

Le tour est joué.

Trackbacks

0 trackback

Commentaires

39 commentaires

et dire que je l'ai demandé à quelqu'un depuis un bout de temps, bravo , merci !

1. Par Weetabix le mardi 22 septembre 2009 à 14:04

Excellent !

Je constate juste un bug "visuel" lorsqu'il y a moins de 3 news.

Et merci de faire partager ton code :)

2. Par Devzonefr le mardi 22 septembre 2009 à 14:13

Drôlement chouette :)
Et en plus tu utilises jQuery de façon à apprendre deux trois trucs à u débutant qui regardera le code d'un peu près :)

3. Par Stan le mardi 22 septembre 2009 à 14:31

Superbe article comme d'habitude... Preuve que je t'ai lu jusqu'au bout... manque un e à appliquEr

" Ensuite vos connaissez la rangaine. Il faut inclure jQuery et appliqur le plugin à votre liste."

4. Par Lester le mardi 22 septembre 2009 à 15:28

L'article doit être truffé de fautes. Difficile de trouver du temps. Merci Lester.

5. Par Jay Salvat le mardi 22 septembre 2009 à 15:58

Lester : tant qu'à faire tu aurais pu dire, à propos de cette phrase : il manque un "u" à "vous" et "rangaine" s'écrit "rengaine".
Il n'en reste pas moins que l'article est très intéressant :)

6. Par Stan le mardi 22 septembre 2009 à 16:04

@Stan, LOL c'est corrigé, au suivant.

7. Par Jay Salvat le mardi 22 septembre 2009 à 17:23

A la rigueur les fautes d'orthographe, je m'en fous un peu, on en fait tous. C'était juste pour suivre Lester qui avait trouvé une petite coquille mais qui en avait loupé plein dans la même phrase :)
En revanche j'ai une vraie question (AAAAAhhhhh) de débutant (OOOOhhhhh) sans doute idiote (BOUUUUhhhh).
J'ai remarqué ceci dans ton code :
$('dd', $$)
J'ai un peu regardé à quoi ça correspondait et j'ai vu que c'était un contexte de sélection.

Voici mes questions :
- à part le fait que c'est plus court à écrire quelle est la différence entre $$ et $(this) ou this ?
- plus important : qu'est ce qui est mieux entre $("tbody tr") et $("tr", monObjetTbody). Je sais que c'est pas très juste car l'un des sélecteurs est plus large que l'autre. Mais en fait ma question en français est : vaut il mieux utiliser un sélecteur le plus restreint possible sans avoir à utiliser le contexte ou bien un sélecteur un peu plus large dont on restreint la sélection au moyen du contexte. Je suis pas hyper clair je crois ... :)

8. Par Stan le mardi 22 septembre 2009 à 18:59

Bonjour Stan,

1 - J'ai pris pour habitude de, d'entrée de jeu, ajouter var $$ = $(this); à mes plugins. Ainsi $$ représentera l'élément jQuery sur lequel pointe le plugin (DL ici)., et ce dans tous le plugin, même dans des méthodes qui changent de contextes.

Selon les endroits, $(this) n'aura plus la même valeur puisque le contexte aura changé. Par exemple, dans animate(... , function() { } ); this sera l'élément en cours d'animation (donc DT) et non plus l'élément sur lequel le plugin a été appliqué (DL).

This seul n'est pas toujours un objet jQuery, donc il est préférable de la passer par $(this).

Pour finir $('dd', $$) permet de taper sur les DD de la liste DL du plugin et non sur tous les DD qui pourraient exister ailleurs sur la page.

2 - Il vaut mieux utliser $("tr", monObjetTbody) que $("tbody tr"). $("tbody tr") demandera à jQuery de parser le sélecteur pour comprendre que tu veux les TR dans le TBODY. Ensuite il parsera tout le DOM pour trouver les TBODY et ensuite en chercher les TR.

Avec $("tr", monObjetTbody), il n'a pas à parser la chaine et surtout n'a pas à se taper tout le DOM pour trouver et construire l'objet TBODY, vu que tu lui donnes déjà.

Donc quand tu travailles plusieurs fois avec le même sélecteur, caches-dans une variables. Tu évites à jQuery de refaire le travail à chaque fois.

En espérant avoir répondu. :)

9. Par Jay Salvat le mercredi 23 septembre 2009 à 14:12

Nickel, merci beaucoup :)

10. Par Stan le mercredi 23 septembre 2009 à 14:38

Super article.
Seul problème : je dois être très fatigué, ou alors une grosse buse, mais j'ai pas compris comment on l'utilise.
C'est un plugin qu'on installe dans WP, ou il faut faire des manip à la main dans les pages du blog?
C'est surement très con comme question, j'en suis désolé, mais j'aimerais l'installer sur mon blog.

Merci d'avance.

11. Par Dominique le mercredi 23 septembre 2009 à 15:31

Bonsoir Dominique,

C'est un plugin indépendant pour la librairie jQuery. Ce n'est pas un plugin spécialement destiné à Worpress.

Si tu veux l'intégrer à Wordpress, il faut certainement modifier tes templates. Je ne suis pas expert.

Bon courage.

12. Par Jay Salvat le mercredi 23 septembre 2009 à 16:56

C'est un plug-in jQuery, réfère toi aux articles précédents de Jay pour tout connaître :)
Mais basiquement il faut suivre ce qui est marqué dans "Usage" de cet article.

13. Par Stan le mercredi 23 septembre 2009 à 16:58

Merci beaucoup pour vos réponses.

14. Par Dominique le jeudi 24 septembre 2009 à 22:48

Génial ! Très bon blog que je découvre et ne manquerais pas de revenir !

Merci !

15. Par Patrick le vendredi 25 septembre 2009 à 16:29

Merci pour ton script et bonne continuation

16. Par Djb le vendredi 25 septembre 2009 à 22:20

Je suis allé voir lyonmag.com ... dis donc ça a l'air drôlement homogène au niveau des couleurs !
Ca sent l'embrouille :)
Est-ce eux qui t'ont demandé le bandeau aux couleurs du site, le site qui s'est mis au couleur, ou un pur fruit du hasard (qui fait bien les choses, tout le monde le sait :) ).

17. Par Stan le samedi 26 septembre 2009 à 13:36

Bonjour Stan,
Quelle embrouille ?

J'ai fait le bandeau sur le modèle iTélé. Il se trouve que leur site est rouge (et pas le même).

Le webmaster a pris le script et l'a intégré tel quel.

18. Par Jay Salvat le lundi 28 septembre 2009 à 13:43

Quand je disais "embrouille", ce n'était pas méchant, hein :)
C'était une sorte de compliment caché qui disait en substance : "Ton plugin iTele est suffisamment bien fait pour être repris tel quel par les 'créateurs' même de l'idée" :)

En tout cas, c'est vrai que ça rend bien et que c'est une sympathique façon de présenter les news rapidement.

Je songeais d'ailleurs qu'il pourrait être intéressant d'augmenter ce plugin d'une partie Ajax où l'on pourrait paramétrer un intervalle et une adresse qui irait consulter régulièrement les news à afficher.

Je crois que ça va me faire un cas d'école intéressant à tester car en pratique ça "ne sert à rien" étant donné que les news arrivent en général moins vite que la fréquence à laquelle on change de page.

19. Par Stan le lundi 28 septembre 2009 à 15:24

Très beau script, propre er rapide ! Mr Salvat, vos explications sont soignées et limpides, comme le script.. Merci et bravo

20. Par Webmaster G38 le jeudi 01 octobre 2009 à 10:37

voilà qui est trèèèèèèèèès interessant! mille merci pour ce tuto qui me sera très utile!
peace!

21. Par Mobteam le samedi 03 octobre 2009 à 12:57

Merci pour l'article bien détaillé et le plugin bien réalisé.

Intégration prévue rapidement :)

22. Par Nicolas Chevallier le lundi 05 octobre 2009 à 17:36

Je n'arrive pas à afficher les dd sur la page.

23. Par DIGEON le jeudi 08 octobre 2009 à 12:42

Merci beaucoup pour ce code. Géniale. J'ai trouvé d'où venait le problème et maintenant c'est bon. j'ai modifié le code css , pas seulement le display: none mais aussi la position.

24. Par DIGEON le jeudi 08 octobre 2009 à 12:49

C'est vraiment top ce que tu fais;
Certes j'utilise jQuery, qui est une formidable bibliothèque, même pour les amateurs,;mais toi t'es un fan et un expert.

Bravo pour ton blog !

25. Par Olivier Lafanechère le mardi 03 novembre 2009 à 18:58

Merci Olivier,

Je passe mes journées sur des Intranets / Extranets / Webservices / Applications grands-comptes complexes.

Je blog sur un peu de jQuery pour me détendre... :)

26. Par Jay Salvat le mardi 03 novembre 2009 à 21:29

Bonjour désolé d'être un noob en jquery, mais je bloque à cette étape :
Ensuite vous connaissez la rengaine. Il faut inclure jQuery et appliquer le plugin à votre liste.

j'ai mis dans ma page html la feuille css et le jquery fonction comme ce si :
<link href="jquery.itvscroller.css" rel="stylesheet" type="text/css" />
<script src="jquery.itvscroller.js" type="text/javascript"></script>
<script type="text/javascript" >
$(function() {
$('#iTvScroller').iTvScroller();
});
</script>
entre les balises head et /head mais ça ne fonctionne pas pouvez_vous m'expliquer s'il vous plait merci

27. Par Yadid le mardi 10 novembre 2009 à 11:04

Bonjour Yadid,
Ce script est un plugin jQuery. Il faut inclure télécharger et inclure la librairie jQuery.

Tu peux la télécharger sur le site officiel :
Jquery.com

28. Par Jay Salvat le mardi 10 novembre 2009 à 11:15

Oui c'est ce que j'ai fait
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans nom</title>
<link href="jquery.itvscroller.css" rel="stylesheet" type="text/css" />
<SCRIPT LANGUAGE=Javascript src="jquery-1.3.2.min.js"> </SCRIPT>
<SCRIPT LANGUAGE=Javascript src="jquery.itvscroller.js"> </SCRIPT>
<script type="text/javascript" >
$(function() {
$('#iTvScroller').iTvScroller();
});
</script>

</head>
et j'ai téléchargé le code source...
Mais j'ai du loupé une étape ...

En tous cas, merci beaucoup de m'avoir répondu, car ce plugin jquery me plait beaucoup

29. Par Yadid le mardi 10 novembre 2009 à 11:47

SI ça ne marche encore pas, comme ça je vais avoir du mal.
Vérifie :
1 - Bien inclure jQuery (bon chemin ?)
2 - Bien inclure le plugin (bon chemin ?)
3 - Bien utilisé le bon HTML avec le bon id ?

30. Par Jay Salvat le mardi 10 novembre 2009 à 12:14

Merci beaucoup ça fonctionne en prennat le jquery = jquery-1.3.1.min.js au lieu du 1.3.2

31. Par Yadid le mardi 10 novembre 2009 à 12:24

Content que ça marche.
Tu avais dû simplement te tromper de chemin pour jQuery car ce script marche en 1.3.2 (La démo utilise 1.3.2).

P.S pas de soucis pour le "flood", ça arrive fréquement avec cet hébergement :)

32. Par Jay Salvat le mardi 10 novembre 2009 à 12:56

bravo et merci pour le partage.
Drôlement efficace en termes de gain de place et de lisibilité.
De la télé sur le web 2.0

33. Par Walter le samedi 14 novembre 2009 à 08:35

Bonjour a tous,

magnifique ce script... je vais vous paraitre bête mais je suis bloqué je n'arrive pas à le faire fonctionner. si quelqu'un peut m'aider voici le lien sur le site sur lequel je souhaite le tester.
Via-design.fr/v2

Par avance merci et bravo Jay!

Jim

34. Par Jimmy le mardi 05 janvier 2010 à 11:03

Bonjour Jimmy.
Le script fonctionne très bien sur le site que tu donnes (Firefox).
Quel est ton problème ?

35. Par Jay Salvat le mardi 05 janvier 2010 à 12:28

Bonjour et merci a toi pour ce magnifique script j'ai juste une question, comment je pourrai faire pour masquer les titres qui dépasse si il y en a plus que la résolution de l'écran.
Par avance merci

36. Par Boby le jeudi 07 janvier 2010 à 18:03

Bonsoir Boby,

Je ne me suis pas penché dessus mais avec un peu de Css et un overflow:hidden, ça devrait faire l'affaire.

37. Par Jay Salvat le jeudi 07 janvier 2010 à 18:11

Merci de ta réponse rapide ouai la actuellement j'ai reduis les image et calé le padding mais c'est vrai que si je peux les cachés ça serai top je vais testé merci a toi

38. Par Boby le jeudi 07 janvier 2010 à 18:24

Merci c'est bon cela fonctionne :) par contre sur IE 5 et 6, le script ne fonctionne pas la barre reste coller en haut...

39. Par Jimmy le lundi 18 janvier 2010 à 15:41

Obligatoire. Vrai nom apprécié.

Il ne sera ni affiché, ni spammé.

Votre blog ou votre site web.

Constructif, courtois et correctement écrit. SMS proscrit. Merci.