11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Un bonjour particulier car si c'est la première fois que je poste sur le forum ça fait déjà quelques semaines que j'utilise ce site et ses tutos bien pratiques Smiley smile .

J'utilise une petite fonction javascript qui me permet d'afficher/cacher une zone sur ma page. Actuellement la fonction ouvre une zone cachée auparavant (et si on reclick ça referme...).

Je souhaite faire l'inverse Smiley biggol : la zone est affichée par défaut quand la page se charge et en 1 click on peut fermer la zone (et la réouvrir ensuite en un click...).

Actuellement ma fonction (qui marche) est comme ceci :
<script type="text/javascript">
function OpenClose(objectID) {
var object = document.getElementById(objectID);
if (object.style.display =='block') 
object.style.display='none';
else object.style.display='block';
return;
}
</script>
<a href="javascript:OpenClose('zone')">Fermer / Ouvrir</a>
<div id="zone">
</div>


J'ai essayé de bidouiller un peu la fonction pour quelle fasse l'inverse mais je n'ai pas réussi Smiley decu .
Pourriez-vous m'aider s'il vous plait ?
Modifié par Knop (12 Feb 2008 - 18:06)
Modérateur
Salut,

Tu peux faire comme suit :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	                  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
		<title>Exemple</title>
		<style type="text/css"><!--

@media screen, projection {
	.hidden { display:none; }
}

		--></style>
		<script type="text/javascript"><!--

// AFFICHAGE / MASQUAGE D'UN ELEMENT (AVEC INSERTION D'UN LIEN SI LE CONTROLEUR N'EST PAS FOCUSABLE)
function toggle(oCtrl, oToggle) {
	if(oCtrl.nodeName.toLowerCase() != 'a')
		oCtrl.innerHTML = '<a href="#">' + oCtrl.innerHTML + '</a>';
	return function(e) {
		oToggle.className = oToggle.className == 'hidden' ? '' : 'hidden';
		return stop(e);
	}
}

// SELECTION D'UN ELEMENT
function $() {
	var a = arguments;
	if(a.length > 1 && typeof a[1] == 'string') {
		return typeof a[0] == 'string' ?
			document.getElementById(a[0]).getElementsByTagName(a[1]):
			a[0].getElementsByTagName(a[1]);
	}
	else switch(typeof a[0]) {
		case 'string':
			return document.getElementById(a[0]);
		case 'object':
			return a[0];
	}
	return false;
}

// ANNULATION DE LA PROPAGATION ET DE L'ACTION NORMALE D'UN ELEMENT
function stop(e) {
	if(e && e.stopPropagation && e.preventDefault) {
		e.stopPropagation();
		e.preventDefault();
	}
	else if(e && window.event) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	}
	return false; // Indispensable pour Safari
}

// AJOUT D'UN GESTIONNAIRE D'EVENEMENT A UN ELEMENT LORS D'UN EVENEMENT DONNE
function connect() {
	var a = arguments;
	return document.addEventListener ?
			a[0].addEventListener(a[1], a[2], a[3] || false):
			a[0].attachEvent ?
				a[0].attachEvent('on' + a[1], a[2]):
				false;
}

// LANCEMENT DU SCRIPT AU CHARGEMENT DE LA PAGE
connect(window, 'load', function() {

	// Ajout de l'affichage / masquage du premier paragraphe au clic sur le titre
	var oCtrl = $(document, 'h1')[0];
	var oToggle = $(document, 'p')[0];
	connect(oCtrl, 'click', toggle(oCtrl, oToggle));
	
	// Ajout de l'affichage / masquage du second paragraphe au clic sur le sous-titre
	var oCtrl2 = $('sstitre');
	var oToggle2 = $(document, 'p')[1];
	connect(oCtrl2, 'click', toggle(oCtrl2, oToggle2));

});

		//--></script>
	</head>
<body>

<div>
	<h1>Titre</h1>
	<p>blabla de circonstance</p>
</div>
<div>
	<h2 id="sstitre">Sous-titre</h2>
	<p>second blabla de circonstance</p>
</div>

</body></html>


PS : Je pense que certaines choses te paraitront floues dans cet exemple... N'hésite pas à demander quelques explications... Je manque juste un peu de temps là tout de suite... Smiley cligne
Merci pour ta réponse koala Smiley smile .

Outch, c'est super long comme fonction pour un pti effet comme ça :o, non ? (je ne remets en rien tes compétences hein, je n'y connais pas grand chose en javascript...).

J'ai continué à bidouiller un peu de mon côté et je suis arrivé à ça :


<script type="text/javascript">
function OpenClose(objectID) {
var object = document.getElementById(objectID);
if (object.style.display =='') 
object.style.display='none';
else object.style.display='';
return;
}
</script>
<a href="javascript:OpenClose('zone')">Lien</a>
<div id="zone">blah blah blah
</div>


Ca semble marcher sous Firefox et IE 6 (pas testé avec le 7, je ne l'ai pas sur ce pc).

Edit : J'ai également trouvé ceci entre temps :

function ReverseContentDisplay(objectID) {
	if(document.getElementById(objectID).style.display == "none") { 
		document.getElementById(objectID).style.display = ""; 
	}
	else { 
		document.getElementById(objectID).style.display = "none"; 
	}
}


sur http://forums.digitalpoint.com/showthread.php?t=92710

Cela semble également marcher et j'ai un peu plus confiance dans celui-là que le mien (ayant bidouillé moi-même le mien et ne m'y connaissant pas trop en javascript)...

Est-il préférable d'utiliser l'un de ces scripts (dont le tien évidemment !) :- ?
Modifié par Knop (12 Feb 2008 - 14:29)
Modérateur
Re, Smiley smile

Tes scripts sont corrects et plus faciles à comprendre mais il y a, en effet, quelques différences avec ce que je t'ai montré :

- Tout d'abord, le lien qui contrôle l'ouverture / fermeture du bloc est en dur dans tes exemples, ce qui fait que si l'utilisateur ne dispose pas de JS, celui-ci se retrouve avec des liens inutiles. Pour ma part, j'évite de laisser tout contrôleur qui n'a d'utilité que lorsque JS est actif.

- Dans mon exemple, j'ai externalisé toutes les instructions JS afin de faciliter la maintenance du code. Ce n'est pas obligatoire mais plus une question d'habitude. A ces fins, j'ai créé une fonction connect qui permet d'attacher une fonction à un élément sur un événement donné. Entre autres, je m'en sers sur window au chargement ainsi que sur les titre et sous-titre lorsqu'on clique dessus. L'avantage par rapport à un onclick est que tu peux toujours, dans un autre script, ajouter une fonction sur l'élément lorsqu'on clique dessus. Ce n'est pas le cas avec un onclick qui, lui, s'approprie l'élément. Ca me permet de minimiser les contraintes pour de futurs scripts.

- Tes deux exemples te contraignent à mettre un id sur l'élément contrôlé. C'est pour cela que je sélectionne, via la fonction $, l'élément en dehors de la fonction toggle (ou OpenClose dans ton cas). Ainsi, id ou pas, je peux contrôler n'importe quel élement.

- Lorsque la fonction toggle s'initialise, je regarde si l'élément qui pilote est un lien. Si ce n'est pas le cas, je transforme son contenu en lien afin de conserver la navigation clavier.

- La fonction stop, quant à elle, est équivalente à un return false. C'est nécessaire dans mon cas car je passe par la gestion d'événement DOM2.
Modifié par koala64 (12 Feb 2008 - 15:25)
Oki Smiley smile .
Je ne comprends sans doute pas tout ce que cela implique techniquement mais tes explications me paraissent claires Smiley smile . Je vais donc garder le dernier code que j'ai posté car il est plus simple et il me faut quelque chose de simple et efficace pour faire une petite chose seulement (le lien étant fait sur un texte qui s'affiche de toute façon).
Merci encore pour ton script et tes explications qui me permettent de comprendre un peu mieux les enjeux de faire quelque chose de plus "développé" éventuellement...