11542 sujets

JavaScript, DOM et API Web HTML5

Bonjour à vous tous !

Poursuivant ma lancée récente sur le Javascript (je me documente, je me documente), je me heurte de nouveau à un problème pratique.

Je vous explique ce que je souhaite faire. Dans Firefox 2, vous avez un champ de texte, en haut à droite, pour la recherche. Il contient un texte en grisâtre, avec marqué "Google". Si on clique dessus, il disparait, et on peut taper sa recherche. Si on le quitte sans rien taper, le "Google" gris revient. En revanche, si on tape une recherche, Google ne revient pas, évidemment.

Je souhaiterais faire exactement la même chose.

Un champ input/text, avec marquer "Taper votre recherche" en gris. Au clic, il disparait. Si l'utilisateur entre du contenu, "Taper votre recherche" ne doit pas revenir écraser ce contenu. En revanche, s'il ne tape rien et qu'il clique autre par, "Taper votre recherche" doit réapparaître.

Là, je ne vous demande pas de me coder un script, on est sur un forum d'entraide Smiley cligne
MAIS, j'avais déjà vu des scripts tout fait, que je n'ai plus qu'à adapter, que je n'ai pas retrouvé. Et après une longue recherche sur Google, impossible de trouver ce genre de script.
Je fais donc appel à vous !

Ah, oui, s'il était possible de faire la même chose sur un textarea aussi... ça me ferait plaisir Smiley smile

(et je sais que celà ne dispense pas du label, qui renseigne sur le champ)
Modérateur
Salut,

Je te donne le principe à suivre et tu le codes... Smiley cligne

Pour accéder au champ texte, tu peux te servir de getElementsByTagName ou getElementById suivant qu'il y ait un id ou non.
Pour accèder à la valeur par défaut, tu peux te servir de la méthode getAttribute.

A la prise du focus (onfocus), si cette valeur est égale à "Taper votre recherche" (if...), tu dis que value doit être égale à une chaîne texte vide (setAttribute).
A la perte du focus (onblur), si la valeur est vide (if...), tu la remplaces par "Taper votre recherche" (setAttribute).

A toi de jouer. Smiley ravi

PS : Pour le textarea, c'est le même principe excepté que tu ne te sers pas de getAttribute mais que tu dois chopper la valeur du premier noeud enfant (firstChild.nodeValue) du textarea.
Modifié par koala64 (10 Nov 2006 - 18:53)
Hum. Ca va être dur, car je suis novice, mais c'est en forgeant qu'on devient forgeron Smiley cligne

En revanche, comment faire pour que le texte soit gris, par exemple (c'est à dire une modification des CSS si et seulement si il y a Taper votre recherche: d'affiché)?


Je me lance donc là dessus demain matin.

Merci pour les explications, je vais les apprendre par coeur Smiley smile

Edit: mais ça risque d'être compliqué pour le textarea, car je n'ai pas vraiment compris, je verrais ensuite.
Modifié par Sylvain (10 Nov 2006 - 21:34)
Modérateur
Concernant le texte gris, c'est effectivement via CSS que tu vas le paramétrer... Inutile de passer ça dans le JS à mon avis... Tu peux par exemple donner une couleur grise en normal et une autre couleur lorsque le champ est actif... Maintenant si tu tiens réellement à le différencier du texte rentré par l'utilisateur, tu peux, via JS, le lier à une class CSS avec la propriété className.

Si tu n'y arrives pas pour le code JS, ben propose ton code... Ca permettra de voir ce qui te bloque... Smiley smile

Pour le textarea, tu peux l'identifier de la même manière que pour le champ texte (getElementsByTagName ou getElementById).
Une fois que tu l'as, tu accèdes au premier noeud, c'est à dire le texte qui se trouvera dans le textarea, via la propriété firstChild.
nodeValue sert à lire la valeur du noeud.

N'hésite pas à consulter ce site par exemple... Ca devrait t'aider Smiley cligne
Modifié par koala64 (10 Nov 2006 - 21:57)
Salut,
koala64 a écrit :
Concernant le texte gris, c'est effectivement via CSS que tu vas le paramétrer... Inutile de passer ça dans le JS à mon avis... Tu peux par exemple donner une couleur grise en normal et une autre couleur lorsque le champ est actif...
Par contre, cette solution ne marchera pas avec IE 6, si ?
Modérateur
oui exact... Je n'y pensais plus... Smiley cligne

sous IE7 non plus d'ailleurs, ils ont résolu le hover mais pas le focus... Smiley ohwell

Du coup, ben le JS est bien nécessaire...
Et ça dans la CSS ça ne pourrait pas aller ?

#id_champ[value="Tapez votre recherche"] { ... }

Bon, OK, toujours pas d'IE .. 6 en tout cas. Mais ne sait-on jamais pour la 7.
QuentinC a écrit :
Et ça dans la CSS ça ne pourrait pas aller ?

#id_champ[value="Tapez votre recherche"] { ... }

Bon, OK, toujours pas d'IE .. 6 en tout cas. Mais ne sait-on jamais pour la 7.
Le problème, c'est que ça duplique ta valeur par défaut.
C'est grave de devoir dupliquer sa valeur par défaut ? IL ne faut juste pas oublier de la changer...
Bon, c'est vrai que ce serait mieux d'éviter.
QuentinC a écrit :
Et ça dans la CSS ça ne pourrait pas aller ?

#id_champ[value="Tapez votre recherche"] { ... }

Bon, OK, toujours pas d'IE .. 6 en tout cas. Mais ne sait-on jamais pour la 7.


Après mes premiers tests, cette méthode dit:

"Pour toute balise avec l'id id_champ et l'attribut value Tapez votre recherche".

Le soucis, c'est que même si on tape dedans, le value du champs ne change pas. En d'autre mot, le texte reste gris. Dans ce cas, CSS s'interresse à l'attribut value, et pas à ce que contient réellement le champ de texte. Bref, ça ne fonctionne pas. Je sais pas si on m'a comprit Smiley cligne
Bon, je vous préviens, on sent que ce code est fait par un apprenti.

Ca n'est pas optimisé, optimal, c'est assez lourd (du moins pas très beau dans le code HTML. Je sais qu'avec le DOM, dont j'ai à présent un très bon lien, je peux éviter tous ces onfocus, onblur, dans le HTML, et je vais m'y atteler.

J'ai aussi un autre soucis, c'est d'avoir à rajouter une ligne de javascript dans le code. Etrange.

Enfin, je vous copie mon code actuel qui, à l'exception du gris, marche Smiley smile

Le HTML:

<input type="text" id="recherche" value="" onfocus="textepardefaut('prisedefocus')" onblur="textepardefaut('pertedefocus')"/>
												<script type="text/javascript">textepardefaut('chargement')</script>


Le javascript:
function textepardefaut(evenement){
	if(evenement=="chargement")
	{
		if(document.getElementById('recherche').value == "")
		{
			document.getElementById('recherche').value = 'Tapez ici votre recherche';
		}
	}
	if(evenement=="prisedefocus")
	{
		if(document.getElementById('recherche').value == "Tapez ici votre recherche")
		{
			document.getElementById('recherche').value = '';
		}
	}
	if(evenement=="pertedefocus")
	{
	if(document.getElementById('recherche').value == "")
		{
			document.getElementById('recherche').value = 'Tapez ici votre recherche';
		}
	}
}

Modifié par Sylvain (11 Nov 2006 - 11:48)
Salut,

C'est déjà pas mal !

Première chose, à mon avis, c'est de faire plusieurs fonctions plutôt qu'une seule avec un argument donnant l'action à exécuter.

Soit dit en passant, pour l'instant les codes pour chargement et pertedefocus sont rigoureusement les mêmes. Smiley smile
a écrit :
Soit dit en passant, pour l'instant les codes pour chargement et pertedefocus sont rigoureusement les mêmes. smile


Ah... oui...

On va changer ça Smiley smile

J'ai réussi tout seul à mettre la couleur grise -enfin, gris beige dans mon cas, mais il suffit de changer le code de la couleur, hein-

Voici le javascript:

function textepardefaut(evenement){
	if(evenement=="prisedefocus")
	{
		if(document.getElementById('recherche').value == "Rechercher")
		{
			document.getElementById('recherche').style.color = "#000";
			document.getElementById('recherche').value = '';
		}
	}
	if(evenement=="pertedefocus")
	{
		if(document.getElementById('recherche').value == "")
		{
			document.getElementById('recherche').value = 'Rechercher';
			document.getElementById('recherche').style.color = "#5F4E2D";
		}
		if(document.getElementById('recherche').value == "Rechercher")
		{
			document.getElementById('recherche').style.color = "#5F4E2D";
		}
	}
}


Et voici le HTML:
<input type="text" id="recherche" value="" onfocus="textepardefaut('prisedefocus')" onblur="textepardefaut('pertedefocus')"/>
<script type="text/javascript">textepardefaut('pertedefocus')</script>


Maintenant, que tout marche, tout ce que je souhaiterai, c'est que le code HTML ressemble à ça:
<input type="text" id="recherche" value="" />


Et que les fonctions soient appelées via javascript uniquement; Avez vous une idée?

Merci beaucoup, déjà, de m'avoir guidé pour faire cette fonction, j'ai beaucoup appris déjà.
Sylvain a écrit :
Maintenant, que tout marche, tout ce que je souhaiterai, c'est que le code HTML ressemble à ça:
<input type="text" id="recherche" value="" />
Et que les fonctions soient appelées via javascript uniquement; Avez vous une idée?

Merci beaucoup, déjà, de m'avoir guidé pour faire cette fonction, j'ai beaucoup appris déjà.
Dans ce cas-là, il te suffit d'utiliser l'évènement "load" :
function initTexteParDefaut() {
  ...
}

window.onload = initTexteParDefaut;
(sachant qu'il faudra faire un peu plus compliqué si plusieurs scripts utilisent cet évènement.)

Et ensuite, le principe sera le même pour aller ajouter les évènements "focus" et "blur" à ton élément de formulaire.

Tu peux aussi envisager d'utiliser une classe plutôt qu'un id pour identifier les élèments qui auront ce comportement. Cela te permettra de l'appliquer facilement à plusieurs éléments de ta page.
Modérateur
Salut,

Quelqu'autres petites remarques...

Dans le script que tu as montré, tu répètes 8 fois document.getElementById('recherche').

Une bonne idée serait de le définir au sein d'une variable afin d'augmenter la lisibilité de ton script.

function textepardefaut(evenement){
   var oRech = document.getElementById('recherche');
   ...
}
-> Tu n'aurais plus qu'à écrire oRech à chaque fois que tu as besoin de cette expression.

Eldebaran a écrit :
Tu peux aussi envisager d'utiliser une classe plutôt qu'un id pour identifier les élèments qui auront ce comportement. Cela te permettra de l'appliquer facilement à plusieurs éléments de ta page.
oui ou alors, dans ton script, de définir la valeur de l'id en tant qu'argument de ta fonction.

Par ailleurs, pour tous les styles que tu souhaites appliquer, tu peux définir une classe CSS plutôt que de te servir de l'objet style, ce qui te permettra de ne modifier les styles que dans le CSS si besoin est.

oRech.className = 'gris';


Autre chose que tu pourrais ajouter, c'est de sélectionner ton texte à la prise du focus pour toute valeur autre que "Rechercher". Ca permet de l'effacer en une seule pression. -> voir la méthode select().
Eldebaran a écrit :
Dans ce cas-là, il te suffit d'utiliser l'évènement "load" :
function initTexteParDefaut() {
  ...
}

window.onload = initTexteParDefaut;
(sachant qu'il faudra faire un peu plus compliqué si plusieurs scripts utilisent cet évènement.)

Et ensuite, le principe sera le même pour aller ajouter les évènements "focus" et "blur" à ton élément de formulaire.


J'ai essayé la chose suivante:

var oRech = document.getElementById('sujet');

function textfocus(){
	if(oRech.value == "Rechercher")
	{
		oRech.className = "actif";
		oRech.value = '';
	}
}
function textblur(){
	if(oRech.value == "")
	{
		oRech.className = "inactif";
		oRech.value = 'Rechercher';
	}
}
window.onload = textblur;
oRech.onfocus = textfocus;
oRech.onblur = textblur;


Ca ne fonctionne malheureusement plus du tout. Qu'ais-je fais ?

Faut-il que j'appelle le script après le HTML du input?
<input type="text" id="sujet" value=""/>

Modifié par Sylvain (11 Nov 2006 - 16:33)
Modérateur
Non, pas forcémment... mais c'est pas mal, tu te rapproches... Smiley ravi

En fait, le soucis, c'est qu'au moment où tu crées ta variable oRech, le champ texte n'est pas encore défini. Pour que ce soit le cas, toute la page doit être lue avant que de créer cette variable. C'est ce que permet le gestionnaire onload.
Autrement dit, tout ce que tu déclares doit être lancé une fois toute la page interprétée... dans une fonction anonyme affectée au window.onload.

Lorsque tu affectes des gestionnaires tels que onmachinchose, la fonction réceptrice, ici, textfocus ou textblur est liée à ton élément. Pour faire référence à cet élément, tu peux te servir du mot clé this au sein de tes fonctions.

Il ne te reste alors plus qu'une chose à régler, c'est de définir la classe CSS et la valeur au chargement de la page.