News box avec une image, un texte et un timing simples

Eléphant du PHP | 82 Messages

12 mai 2010, 10:16

Bonjour,

je cherche (en parallèle à mon problème sur le sujet pas loin...) un moyen d'afficher une sorte de news box qui se présenterait de la sorte :

Imaginez un tableau avec une ligne et deux colonnes. Première colonne avec une image (genre 200 pixels) et seconde colonne avec du texte.
Il faudrait que simplement, après un timing donné, l'image et le texte laissent place à une autre image et un autre texte (l'image et le texte sont liés, ils correspondent entre eux hein). En gros, une news composée d'une image et d'un texte, laissant place à une autre news après un timing donné, puis une autre news, etc, en boucle.

Il faut aussi l'intégrer à Drupal, donc il y a parfois certains inconvénients...

Il y a le flash, et tout... mais je voulais savoir si c'était pas mieux en php, enfin déjà plus abordable pour moi.

Si certains savent comment faire, merci d'avance =)

ViPHP
ViPHP | 1136 Messages

12 mai 2010, 18:25

Salut ,

Et bien grace au javascript , il est tout à fait possible de faire ce genre de chose ,

Par exemple , prototype propose une fonction nommé

periodicalAjaxUpdater

qui te permet donc toutes les X secondes , de changer le contenu d'une zone précise , et ce de façon automatique évidemment ..

Je ne sais pas si durpal utilise prototype , certainement que oui

Voilà .. null besoin de flash .. ouf :)

Good luck ,
ch.

ViPHP
AB
ViPHP | 5818 Messages

12 mai 2010, 19:59

Sinon tu peux le coder aussi uniquement en javascript (je veux dire sans ajax) si tu n'affiche par exemple que les dix dernière news.

Ex : tu génère un tableau bi dimensionnel en php :

$new[1]['image'] = 'chemin_image1.jpg';
$new[1]['texte'] = 'text1';

$new[2]['image'] = 'chemin_image2.jpg';
$new[2]['texte'] = 'text2';

etc.

Tu passe ensuite ton tableau à javascript avec json
Et avec un setTimeout en javascript tu fait changer le contenu de tes blocs en incrémentant le tableau toutes les x secondes.

Très simple à mettre en place.

La seule limitation est qu'il ne faudrait pas qu'il y ait beaucoup de news à afficher sinon cela prendrait pas mal de ressources en mémoire pour le navigateur. Auquel cas Ajax serait recommandé, mais en contre partie cela te fera faire une requête par news.

Mais bon un nombre limité de "dernières" news semble adapté - si j'ai bien compris ce que tu veux faire - car il me paraît peu probable que le visiteur reste sur la page en attendant comme un benêt le défilement d'un grand nombre de news :-k

Eléphant du PHP | 82 Messages

13 mai 2010, 19:22

J'ai lu, j'ai essayé mais... j'ai pas réussi à comprendre #-o

ViPHP
AB
ViPHP | 5818 Messages

14 mai 2010, 00:12

Tu peux faire quelque chose comme ça
<?php
header('Content-type: text/html; charset=UTF-8');

$tab_news[0]['text'] = 'Avatar AB';
$tab_news[0]['image'] = 'http://www.laquadrature.net/wiki/images/4/48/Quadrature_black-out_HADOPI_50x50px_fixed_texte.png';

$tab_news[1]['text'] = 'Avatar Stopher';
$tab_news[1]['image'] = 'http://lindev.fr/public/images/bt-agents-color.jpg';

$tab_news[2]['text'] = 'Avatar Albat';
$tab_news[2]['image'] = 'http://albat.fr.free.fr/phpfrance/coccinelle_v3.png';

shuffle($tab_news);

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document sans nom</title>

<script type="text/javascript">

function Message(id_message,id_photo)
{

	var id_mes = document.getElementById(id_message);
	var id_pho = document.getElementById(id_photo);

	
	var tab_news_js = <?php  echo (isset($tab_news) && is_array($tab_news))? json_encode($tab_news) : 'new Array' ?>;
	
	// nombre d'éléments du tableau
	var nb_tab_news_js = tab_news_js.length;
	

	// Si les éléments cibles existent et le tableau a plus d'un élément
	if (id_mes && id_pho && nb_tab_news_js > 1)
		{
			
			var Img_preload_src = new Array();
			
			// préchargement des images
			for (var i=0; i < nb_tab_news_js; i++)
				{
					if (typeof tab_news_js[i]['image'] != 'undefined')
					{
						Img_preload_src[tab_news_js[i]['image']] = new Image();
						Img_preload_src[tab_news_js[i]['image']].src = tab_news_js[i]['image'];
					}
				}
				
			
			function Boucle(inc)
				{
					//je défini l'indice en focntion de la position dans le tableau
					var inc = inc < nb_tab_news_js ? inc : 0;
					
					// Je nettoie l'élément cible du texte
					var noeuds = id_mes.childNodes.length;
					for (var i = 0; i < noeuds; i++) 	   
						{				   
							id_mes.removeChild(id_mes.firstChild);
						}
				
										
					// Je prend l'adresse de la photo enregistrée dans le tableau; il faudrait remplacer adresse_image_vide.jpg par l'adresse d'une imaage transparente (au cas ou l'image ne serait pas renseignée dans le tableau php)
					var image = typeof tab_news_js[inc]['image'] != 'undefined' ? tab_news_js[inc]['image'] : 'adresse_image_vide.jpg' ;
					
					// Je cherche le texte enregistré dans le tableau
					var texte = typeof tab_news_js[inc]['text'] != 'undefined' ? tab_news_js[inc]['text'] : '';
					// je crée un noeud texte avec le texte  récupéré
					texte = document.createTextNode(texte);
	
					// J'insère la photo dans l'élément cible
					id_pho.src = image;
					
					// J'insère le noeud texte dans l'élément cible
					id_mes.appendChild(texte);
					
					//j'incrémente
					inc++;
					
					//J'appelle la fonction Boucle toutes les cinq secondes
					setTimeout(function(){Boucle(inc)},'5000');   
	
				}
			

		Boucle(0);
		
		}			
}


// Fonction de chargement onload 
function AddLoad_JS(func) {

                if (window.addEventListener)
                {
                        window.addEventListener("load", func, false);
                }
       else if (document.addEventListener)
                {
                        document.addEventListener("load", func, false);
                }
       else if (window.attachEvent)
                {
                        window.attachEvent("onload", func);
                }
}


// Chargement onload de la fonction Message avec ses paramètres id texte et id image
AddLoad_JS(function(){Message('news_texte','news_photo')});


</script>
<style type="text/css">
#conteneur td {
	width : 200px;
}
#conteneur {
	height : 100px;
	width : 400px;
	border : 3px solid black;
}
</style>
</head>
<body>

<table id = "conteneur">
<tr>
<td id = "news_texte">

      <?php if (isset($tab_news[0]['text'])) echo $tab_news[0]['text'];?>

</td>

<td>

	<img id = "news_photo" src="<?php if (isset($tab_news[0]['image'])) echo $tab_news[0]['image']; else echo 'adresse_image_vide.jpg'?>" />
    
</td>

</tr>
</table>

</body>
</html>
Simplement en remplissant ton tableau php tu augmente le nombre d'élément qui apparaîtra dans le tableau html. Ici toutes les cinq secondes mais tu peux bien entendu changer cette valeur.
En copiant collant ce code dans une page vierge tu devrais pouvoir visualiser l'exemple.

A noter qu'avec shuffle($tab_news); à la fin du code php on mélange l'ordre des éléments du tableau pour qu'ils s'affichent de manière aléatoire à chaque chargement de la page :) Enlèves cette ligne si nécessaire.
Modifié en dernier par AB le 14 mai 2010, 04:49, modifié 4 fois.

ViPHP
ViPHP | 5462 Messages

14 mai 2010, 01:28

tu t'embêtes un peu pour le JavaScript quand même
var tab_news_js = <?php echo json_encode($tab_news) ?>;
var temp_array  = tab_news_js.slice(0, tab_news_js.length);
var texte = null;
var image = null;    

var timer = function ()
{    
    var current = temp_array.shift();
        
    texte.innerHTML = current.text;
    image.src = current.image;

    if (!temp_array.length)
    {
        temp_array = tab_news_js.slice(0, tab_news_js.length);
    }

    window.setTimeout(timer, '1000');        
}; 

var addOnLoad = function ()
{
    texte = document.getElementById('news_texte');
    image = document.getElementById('news_photo');
    
    timer();
}; 

if (window.addEventListener)
{
    window.addEventListener('load', addOnLoad, false);
}
else if (window.attachEvent)
{
    window.attachEvent('onload', addOnLoad);
}

ViPHP
AB
ViPHP | 5818 Messages

14 mai 2010, 03:41

tu t'embêtes un peu pour le JavaScript quand même
var tab_news_js = <?php echo json_encode($tab_news) ?>;
var temp_array  = tab_news_js.slice(0, tab_news_js.length);
var texte = null;
var image = null;    

var timer = function ()
{    
    var current = temp_array.shift();
        
    texte.innerHTML = current.text;
    image.src = current.image;

    if (!temp_array.length)
    {C
        temp_array = tab_news_js.slice(0, tab_news_js.length);
    }

    window.setTimeout(timer, '1000');        
}; 

var addOnLoad = function ()
{
    texte = document.getElementById('news_texte');
    image = document.getElementById('news_photo');
    
    timer();
}; 

if (window.addEventListener)
{
    window.addEventListener('load', addOnLoad, false);
}
else if (window.attachEvent)
{
    window.attachEvent('onload', addOnLoad);
}
C'est vrai que tu t'embête beaucoup moins :wink:

- Mais tu as plusieurs variables globales et quand on peut les éviter c'est toujours mieux pour éviter d'éventuels conflits avec d'autres scripts.

- Tu ne vérifie pas non plus l'existence les éléments du tableau (il pourrait y avoir le text de défini mais pas l'image, soit par volonté soit par erreur)

- Tu ne fais pas le préchargement des images, les images suivantes ne s'afficheront pas instantanément si elles ne sont pas dans le cache du navigateur...

- Tu économise aussi en lignes de code car tu utilise innerHTML mais cette méthode ne fait pas partie du DOM W3C (j'avoue que c'est bien dommage, mais donc quand je peux l'éviter facilement, je ne l'emploie pas).

Bien vu le coup du array.shift() pour décompiler le tableau, une méthode à priori séduisante...

- Mais pour ce faire tu fais une copie du tableau donc cette solution sera plus gourmande en ressource mémoire pour le navigateur surtout si le tableau de news/images est volumineux.

Donc niveau compacité du code, c'est vrai qu'il doit être difficile de faire plus court que ta proposition.

Mais si mon code est plus verbeux, il est aussi plus sécurisé (pas de variables globales et vérification des variables du tableau), plus optimisé pour l'affichage des images qui s'afficheront instantanément, plus respectueux du DOM W3C, et plus optimisé car utilisant moins de mémoire pour le navigateur en cas d'un tableau de news/images un peu volumineux :P

Et puis pour une meilleure compréhension, mon code est documenté... ce qui est quand même le but initial de ce forum.

Le plus de ton code (que tu as changé dernièrement) c'est qu'il intègre maintenant une fonction de preload; ça m'a donné l'idée d'éditer le miens pour faire de même :)

Eléphant du PHP | 82 Messages

14 mai 2010, 10:36

Waw... ça c'est du support... merci à vous ! Je teste ça dès cet après midi (voire ce matin si j'y arrive)

Franchement voir tout ce code... c'est dingue (je reviens de la communauté flash qui est... hum souvent morte :mrgreen: -même en anglais !)

ViPHP
ViPHP | 5462 Messages

14 mai 2010, 14:39

Mais si mon code est plus verbeux, il est aussi plus sécurisé (pas de variables globales et vérification des variables du tableau), plus optimisé pour l'affichage des images qui s'afficheront instantanément, plus respectueux du DOM W3C, et plus optimisé car utilisant moins de mémoire pour le navigateur en cas d'un tableau de news/images un peu volumineux :P
sauf qu'il prendra beaucoup plus niveau proc, et pour la mémoire c'est pas la peine sauf si tu veux que la personne reste 1h sur ta page et regarde le bandeau défilé, surtout qu'on parle d'à peine quelque ko, et si on suis ta logique du W3C personne ne ferait d'ajax puisque XMLHttpRequest n'est pas a l'état actuelle valid W3C (bientôt surement :wink: ), le innerHTML ne fait pas la même chose que le createTextNode, ce dernier va échappé toutes les entités html, si c'est qu'on veux c'est nickel, par contre si on veux afficher du HTML la c'est la galère total :?

Eléphant du PHP | 82 Messages

14 mai 2010, 17:06

Alors... je prends quel code ? J'ai fait dans l'ordre des réponses, j'ai commencé avec le code d'AB et ya quelque chose qui marche pas.

J'ai mis :

Code PHP avant le doctype :

Code : Tout sélectionner

<?php header('Content-type: text/html; charset=UTF-8'); $tab_temoignages[0]['image'] = 'sites/all/images/empty_tem.jpg'; $tab_temoignages[0]['text'] = 'Avatar AB'; $tab_temoignages[1]['image'] = 'sites/all/images/empty_tem_b.jpg'; $tab_temoignages[1]['text'] = 'Avatar Stopher'; $tab_temoignages[2]['image'] = 'sites/all/images/empty_tem.jpg'; $tab_temoignages[2]['text'] = 'Jérôme Lissargue 32 ans, contrôleur de gestion chez Airbus (Toulouse) "Ils m’ont bluffé ! Ultrarapide sans transiger avec la qualité, Stéphane le technicien est allé droit au but. Désormais, au moindre pépin, je sais que je pourrai constamment compter sur eux."'; shuffle($tab_temoignages); ?>
Code du HEAD, le script :

Code : Tout sélectionner

<script language="Javascript"> function Message(id_message,id_photo) { var id_mes = document.getElementById(id_message); var id_pho = document.getElementById(id_photo); var tab_temoignages_js = <?php echo (isset($tab_temoignages) && is_array($tab_temoignages))? json_encode($tab_temoignages) : 'new Array' ?>; // Nombre d'éléments du tableau var nb_tab_temoignages_js = tab_temoignages_js.length; // Si les éléments cibles existent et le tableau a plus d'un élément if (id_mes && id_pho && nb_tab_temoignages_js > 1) { var Img_preload_src = new Array(); // Préchargement des images for (var i=0; i < nb_tab_temoignages_js; i++) { if (typeof tab_temoignages_js[i]['image'] != 'undefined') { Img_preload_src[tab_temoignages_js[i]['image']] = new Image(); Img_preload_src[tab_temoignages_js[i]['image']].src = tab_temoignages_js[i]['image']; } } function Boucle(inc) { // Je définie l'indice en focntion de la position dans le tableau var inc = inc < nb_tab_temoignages_js ? inc : 0; // Je nettoie l'élément cible du texte var noeuds = id_mes.childNodes.length; for (var i = 0; i < noeuds; i++) { id_mes.removeChild(id_mes.firstChild); } // Je prend l'adresse de la photo enregistrée dans le tableau; il faudrait remplacer adresse_image_vide.jpg par l'adresse d'une imaage transparente (au cas ou l'image ne serait pas renseignée dans le tableau php) var image = typeof tab_temoignages_js[inc]['image'] != 'undefined' ? tab_temoignages_js[inc]['image'] : 'sites/all/images/empty_tem.jpg' ; // Je cherche le texte enregistré dans le tableau var texte = typeof tab_temoignages_js[inc]['text'] != 'undefined' ? tab_temoignages_js[inc]['text'] : ''; // je crée un noeud texte avec le texte récupéré texte = document.createTextNode(texte); // J'insère la photo dans l'élément cible id_pho.src = image; // J'insère le noeud texte dans l'élément cible id_mes.appendChild(texte); // J'incrémente inc++; // J'appelle la fonction Boucle toutes les sept secondes setTimeout(function(){Boucle(inc)},'7000'); } Boucle(0); } } // Fonction de chargement onload function AddLoad_JS(func) { if (window.addEventListener) { window.addEventListener("load", func, false); } else if (document.addEventListener) { document.addEventListener("load", func, false); } else if (window.attachEvent) { window.attachEvent("onload", func); } } // Chargement onload de la fonction Message avec ses paramètres id texte et id image AddLoad_JS(function(){Message('news_texte','news_photo')}); </script>
Code CSS :

Code : Tout sélectionner

/* Témoignages */ #conteneur td { width : 75px; } #conteneur { height : 175px; width : 100%; border : 0px solid black; }
Code dans le BODY :

Code : Tout sélectionner

<table id = "conteneur"> <tr> <td> <img id = "news_photo" src= "<?php if (isset($tab_temoignages[0]['image'])) echo $tab_temoignages[0]['image']; else echo 'sites/all/images/empty_tem.jpg' ?>" /> </td> <td id = "news_texte"> <?php if (isset($tab_temoignages[0]['text'])) echo $tab_temoignages[0]['text']; ?> </td> </tr> </table id = "conteneur">
Et ça affiche dans la page web un extrait du dernier bout de code de BODY, :
" />
<?php if (isset($tab_temoignages[0]['text'])) echo $tab_temoignages[0]['text']; ?>
Vous pouvez voir ça ici, en bas, pour témoignages : (j'enlèverai l'url si besoin après :) ) http://www.i-mediaservices.com/

Après je ne suis pas assez fort pour savoir si chez l'un prend trop de mémoire ou si l'autre ne respecte pas assez la sécurité et les standards HTML, je vous laisse me donner vos points de vue finaux sur vos deux codes et sur mon essai :D Merci à vous

ViPHP
AB
ViPHP | 5818 Messages

14 mai 2010, 17:59

Le code php n'est pas être interprété en bas de page puisque par exemple les balises d'ouvertures sont remplacées par les entités html ( < est remplacé par < ). Il faudrait remédier à ce problème.
Alternativement tu peux ne rien faire afficher en php (et supprimer le code php) à cet endroit (dans le body) mais dans ce cas les navigateurs n'interprétant pas php n'auront rien d'afficher.

Par ailleurs les paramètres passés à la fonction sont l'id du bloc qui reçoit le texte et l'id de l'image (correspondant dans le code html). Dans mon exemple la fonction est appelée et les paramètres sont passés à cette ligne :

Code : Tout sélectionner

AddLoad_JS(function(){Message('news_texte','news_photo')});
Ces id se nomment donc respectivement "news_texte" et "news_photo" (tu pourrais les changer si besoin) mais je ne les vois nulle part dans ton code source html :!:

ViPHP
AB
ViPHP | 5818 Messages

14 mai 2010, 18:56

Mais si mon code est plus verbeux, il est aussi plus sécurisé (pas de variables globales et vérification des variables du tableau), plus optimisé pour l'affichage des images qui s'afficheront instantanément, plus respectueux du DOM W3C, et plus optimisé car utilisant moins de mémoire pour le navigateur en cas d'un tableau de news/images un peu volumineux :P
... sauf qu'il prendra beaucoup plus niveau proc...
ça c'est pas gagné d'avance : adresser directement les éléments d'un tableau est plus rapide que d'employer une fonction pour décompiler une copie du tableau... ton tableau temporaire est reconstruit à chaque passage dans la boucle, en contre partie j'incrémente juste une variable.

Là ou tu va plus vite c'est d'employer innerHTML. Simplement en évitant de l'utiliser, j'essaie de montrer comment manipuler les éléments du DOM, c'est plus didactique. Mais là dessus je n'ai pas une position arrêtée (ça serait difficile :) ). Outre sa facilité d'utilisation, innerHTML est très pratique surtout, comme tu le dis, si l'on veut formater du texte :wink:

@LightBen Enfin bon c'est juste pour discuter sinon les deux codes emploient le même principe, c'est simplement sa mise en place qui diffère un peu avec les méthodes employées pour lire le tableau et pour afficher le texte. Après, reste le préchargement ou non des images... Pour un affichage des images sans retard ça serait mieux de l'utiliser.

ViPHP
ViPHP | 5462 Messages

14 mai 2010, 19:24

Là ou tu va plus vite c'est d'employer innerHTML. Simplement en évitant de l'utiliser, j'essaie de montrer comment manipuler les éléments du DOM, c'est plus didactique. Mais là dessus je n'ai pas une position arrêtée (ça serait difficile :) ). Outre sa facilité d'utilisation, innerHTML est très pratique surtout, comme tu le dis, si l'on veut formater du texte :wink:
ouai si tu veux insérer du HTML c'est galère en gros faut presque recréer tout un parsé DOM et la ... :? , apres pour juste insere du texte ou changer un attribut, la ca roule :wink:

Eléphant du PHP | 82 Messages

16 mai 2010, 18:42

Erf, alors si j'ai bien compris j'suis embêté là ? Il faut que je trouve un moyen pour que Drupal m'exécute de code php correctement c'est ça ?

ViPHP
AB
ViPHP | 5818 Messages

16 mai 2010, 19:19

Relis ce que j'ai déjà écrit. Encore une fois le code php dans le body n'est pas absolument indispensable pour le fonctionnement.

donc à la place de

Code : Tout sélectionner

<table id = "conteneur"> <tr> <td> <img id = "news_photo" src= "<?php if (isset($tab_temoignages[0]['image'])) echo $tab_temoignages[0]['image']; else echo 'sites/all/images/empty_tem.jpg' ?>" /> </td> <td id = "news_texte"> <?php if (isset($tab_temoignages[0]['text'])) echo $tab_temoignages[0]['text']; ?> </td> </tr> </table id = "conteneur">
tu peux faire :

Code : Tout sélectionner

<table id = "conteneur"> <tr> <td> <img id = "news_photo" src= "" /> </td> <td id = "news_texte"> </td> </tr> </table id = "conteneur">