(jQuery, Tipp) onfocus, onblur bei Input

 


Matze
Chefetage

17.10.08
10:09 Uhr
Wer kennt sie nicht, die onfocus-onblur-Grütze bei Inputfeldern? Früher hat man sie einfach in den <input>-Tag geschrieben. Z.B. so:

  1. <input id="email" name="email" onblur="if (this.value=='') this.value='E-Mail Adresse'" onfocus="if (this.value=='E-Mail Adresse') this.value='';" type="text" value="E-Mail Adresse" />
Quelltext in Zwischenablage kopieren

siehe hier

Ich fand das aber für heutige Verhältnisse zuwider und habe eine kleine Erweiterung für jQuery geschrieben, da ich auf Anhieb nichts vergleichbares gefunden habe. Vielleicht hilft das ja dem einen oder anderen weiter. Schöner als die Variante oben ist es allemal.

  1. var $j = jQuery;
  2. $j.fn.extend({
  3. toggleValue : function (defaultText) {
  4. return this.each(function() {
  5. $j(this).focus(function() {
  6. if ($j(this).val() == defaultText) {
  7. $j(this).val('');
  8. }
  9. $j(this).blur(function () {
  10. if ($j.trim($j(this).val()) == '') {
  11. $j(this).val(defaultText);
  12. }
  13. });
  14. });
  15. });
  16. }
  17. });
Quelltext in Zwischenablage kopieren

Diese Erweiterung erwartet als Parameter den Standardwert für das aktuelle Inputfeld. Beim Fokus wird überprüft, ob der aktuelle Wert mit dem übergebenen Wert übereinstimmt. Ist dem so, wird das Feld geleert. Verlässt man das Inputfeld dann wieder, wird gecheckt, ob das Feld leer ist. Wenn ja, wird es wieder mit dem übergebenen Standardwert gefüllt.

Der Aufruf geschieht dann beispielsweise wie folgt:

  1. <input name="mail" value="E-Mail-Adresse" size="20" />
  2. <script type="text/javascript">
  3. $j('input').toggleValue('E-Mail-Adresse');
  4. </script>
Quelltext in Zwischenablage kopieren

Ich hoffe, ich konnte einigen damit helfen. -)
Link zu diesem Beitrag in die Zwischenablage kopieren
atzoo
Dauergast

17.10.08
11:21 Uhr
Danke!
Werds beim nächsten Mal benutzen/ausprobieren wenn es wieder soweit ist )
Link zu diesem Beitrag in die Zwischenablage kopieren
Matze
Chefetage

17.10.08
13:47 Uhr
cheer
Link zu diesem Beitrag in die Zwischenablage kopieren
timp
Stammgast

17.10.08
14:57 Uhr
Editiert: 17.10.08, 15:03 Uhr
jQuery frei

  1. function toggleInputsValues() {
  2. var inputs = document.getElementsByTagName('input');
  3. for (var i=0;i<inputs.length;i++) {
  4. if (inputs[i].getAttribute('type') == 'text' && inputs[i].getAttribute('value') != '') {
  5. inputs[i].default_str = inputs[i].getAttribute('value');
  6. inputs[i].onfocus = function() {
  7. if (this.getAttribute('value') == this.default_str) {
  8. this.setAttribute('value','');
  9. }
  10. }
  11. inputs[i].onblur = function() {
  12. if (this.getAttribute('value') == '') {
  13. this.setAttribute('value',this.default_str);
  14. }
  15. }
  16. }
  17. }
  18. }
Quelltext in Zwischenablage kopieren

  1. <input type="text" value="Dein Name" />
Quelltext in Zwischenablage kopieren

So ist das Feld dann auch bei deaktiviertem Javascript gekennzeichnet.

cheer
Link zu diesem Beitrag in die Zwischenablage kopieren
Erik Hehrmann
Veteran

18.10.08
11:01 Uhr
Ich raff's zwar nicht, glaub euch aber, dass das dem Zeitgeist entspricht und werde es dann auch mal verwenden ;)

Danke! cheer
Link zu diesem Beitrag in die Zwischenablage kopieren
Dollr
Gast

03.11.08
14:56 Uhr
jQuery-variante mit den vorzügen
von timp's nicht-jQuery variante: text-input? + selbstständiges
erkennen/sammeln der value-attribute ...

  1. $('input[type="text"]').each(function(){$(this).toggleValue($(this).val());});
Quelltext in Zwischenablage kopieren
Link zu diesem Beitrag in die Zwischenablage kopieren
stefan schleich
Veteran

14.11.08
13:13 Uhr
danke hörthört
Link zu diesem Beitrag in die Zwischenablage kopieren
Dollr
Gast

23.01.09
10:57 Uhr
  1. function v(e){
  2. y=$(this);D=y.data('v');V=$.trim(y.val());
  3. if(!V||V==D)y.val((V==D&&!(e.type=='blur')?true:false)?'':D);}
  4.  
  5. ...
  6.  
  7. $(':text,:password').each(function(){
  8. $(this).data('v',$(this).val()).bind('focus blur',v);});
Quelltext in Zwischenablage kopieren
honks
Link zu diesem Beitrag in die Zwischenablage kopieren
data.elmo
Gast

06.09.09
20:49 Uhr
Der Eintrag ist zwar schon etwas älter aber ich versuchs trotzdem mal.

Wie verwende ich denn die jQuery-freie Variante von timp am besten? Oder anders gefragt, wie rufe ich die Funktion am besten auf?

Ich hoffe das ist jetzt nicht zu blöd, aber erstens steh' ich manchmal aufm Schlauch, zweitens gibt es keine dummen fragen und drittens Erstens.
Vielleicht erbarmt sich ja jemand. Das wäre toll.
Link zu diesem Beitrag in die Zwischenablage kopieren
timp
Stammgast

06.09.09
20:55 Uhr
Du musst die Funktion nur bei einem bestimmten event aufrufen, zum Beispiel wenn das Dokument geladen wurde:

  1. window.onload = toggleInputValues;
Quelltext in Zwischenablage kopieren
Link zu diesem Beitrag in die Zwischenablage kopieren
data.elmo
Gast

06.09.09
21:28 Uhr
Editiert: 06.09.09, 21:35 Uhr
Das ging ja super schnell. Vielen Dank.

Hab jetzt folgendes gemacht...

  1. <body onload="toggleInputsValues()">
Quelltext in Zwischenablage kopieren

...was erstmal gut funktioniert.

P.S. timp im 'code' hast du dich verschrieben. Deine Funktion heißt toggleInputsValues

P.P.S. Danke nochmal
Link zu diesem Beitrag in die Zwischenablage kopieren
Naboolean
Gast

07.09.09
00:49 Uhr
Cooler ist es noch, wenn du die Event-Handler nicht im HTML-Code zuweist.
Denn sonst könntest du eigentlich gleich bei der Methode bleiben, die Matze als Beispiel für früher gepostet hat.

Also ist timps Methode noch besser.
Alternativ könntest du auch deine und timps Methode vereinen:
  1. document.body.onload = toggleInputsValues;
Quelltext in Zwischenablage kopieren
(Obacht, hier stehen keine Klammern hinter dem Namen der Funktion, sie soll ja noch nicht ausgeführt werden.)

Das muss irgendwo in den Skripts, die du einbindest, stehen.

Die Event-Handler so direkt zu füllen hat übrigens Nachteile, denn so kann beim Eintreten des Events nur diese eine Aktion ausgeführt werden. Aber vielleicht brauchst du ja nur die. )
Link zu diesem Beitrag in die Zwischenablage kopieren
data.elmo
Gast

07.09.09
01:24 Uhr
So isses mittlerweile:

  1. function init() {
  2. toggleInputsValues();
  3. }
  4. window.onload = init;
Quelltext in Zwischenablage kopieren

@Naboolean: Das mit den Klammern versteh ich nicht.
Link zu diesem Beitrag in die Zwischenablage kopieren
Naboolean
Gast

07.09.09
01:43 Uhr
So isses super!

Wenn du jetzt z.B. schreiben würdest window.onload = init();, würdest du dem Event-Handler den Wert zuweisen, der berechnet wird, wenn init() ausgeführt wird. In dem Fall wäre das glaube ich undefined.

Wenn du die Klammern weg lässt, weist du dem Event-Handler eine Referenz auf die Funktion zu (die ja init »heißt«). Dann ist die onload-Funktion des window-Objekts die selbe, wie die Funktion mit dem Namen init. Wenn dann die onload-Funktion beim Eintreten des Events aufgerufen wird, wird demnach deine definierte Funktion aufgerufen. Und so soll es ja sein.
Link zu diesem Beitrag in die Zwischenablage kopieren
loeffler
Veteran

27.06.11
14:47 Uhr
Der Thread ist zwar schon etwas älter, aber aus aktuellem Anlass hab ich gerade was ähnliches gebastelt, allerdings mit Fading-Effekt. Das ganze benötigt jQuery und eine kleine Anpassung im CSS:

  1. (function( $ ){
  2. $.fn.inputFader = function() {
  3. $(this).find('input[type=text][value][class!=no-input-value]').each(function(i, elem) {
  4. $(elem).wrap($('<div>').addClass('input-wrap')).closest('.input-wrap').prepend($('<div>').addClass('input-text').text($(elem).val()));
  5. $(elem).val('');
  6.  
  7. $(elem).focus(function() {
  8. $(this).closest('.input-wrap').find('.input-text').stop(true, true).fadeOut(400);
  9. });
  10. $(elem).keydown(function() {
  11. $(this).closest('.input-wrap').find('.input-text').stop(true, true).hide();
  12. });
  13. $(elem).blur(function() {
  14. if ($(this).val() == '') {
  15. $(this).closest('.input-wrap').find('.input-text').stop(true, true).fadeIn(400);
  16. }
  17. });
  18. });
  19. };
  20. })( jQuery );
Quelltext in Zwischenablage kopieren
Dazu muss man noch zwei CSS-Klassen definieren, einmal „.input-wrap“ mit „position: relative; display: inline-block;“ und ggf. der Hintergrundfarbe der Input Felder und „.input-wrap .input-text“, welches die selben Eigenschaften wie das Input Feld haben muss.
Zusätzlich dazu wird noch folgendes benötigt
  1. .input-wrap .input-text {
  2. background: transparent;
  3. border-color: transparent;
  4. position: absolute;
  5. top: 0; left: 0;
  6. z-index: 0;
  7. }
  8. .input-wrap input[type=text] {
  9. background: transparent;
  10. position: relative;
  11. z-index: 1;
  12. }
Quelltext in Zwischenablage kopierenAlle Input Felder, bei denen der voreingetragene Text nicht verschwinden soll, müssen mit class=“no-input-value“ gekennzeichnet werden. Das mag jetzt auf den ersten Blick etwas unnötig kompliziert für so eine Kleinigkeit klingen, ich find den Effekt aber ziemlich toll. Und so viel ist es auch wieder nicht. Habs bisher mit Chrome, Firefox, Safari sowie IE9 und IE8 erfolgreich getestet.

Ein Beispiel gibt es bei jsFiddle, damit man das ganze auch mal in Aktion sieht. Vielleicht wird dann auch etwas klarer, wie genau die CSS Klassen definiert werden müssen.
Link zu diesem Beitrag in die Zwischenablage kopieren
Martin R.
Veteran

27.06.11
15:14 Uhr
Placeholder und so. Das hier sieht elegant gelöst aus: http://www.hagenburger.net/BLOG/HTML5-In...Query.html
Link zu diesem Beitrag in die Zwischenablage kopieren
loeffler
Veteran

27.06.11
18:22 Uhr
Editiert: 27.06.11, 18:30 Uhr
Placeholder hatte ich bei mir irgendwie gar nicht mehr auf dem Schirm, nach dem das anfänglich nur von Chrome wirklich unterstützt wurden. Aber mir geht es ja eh in erster Linie um den Fading-Effekt beim auswählen, den bekommt man mit placeholder allein auch nicht hin.

Hab das jetzt mal mit placeholder kombiniert, ein Beispiel gibts wieder bei jsFiddle. Damit erübrigt sich dann auch das setzen von class=“no-input-value“.
Link zu diesem Beitrag in die Zwischenablage kopieren
JanB
Veteran

28.06.11
14:18 Uhr
Hatte auch sowas ähnliches vor, hab aber eine etwas andere Lösung gefunden:

HTML
  1. <form id="form" method="post">
  2. <div>
  3. <label for="name">Name</label>
  4. <input type="text" name="name" id="name" />
  5. </div>
  6. <div>
  7. <label for="email">E-Mail Adresse</label>
  8. <input type="text" name="email" id="email" />
  9. </div>
  10. <div>
  11. <label for="url">Domain</label>
  12. <input type="text" name="url" id="url" />
  13. </div>
  14. <div>
  15. <label for="message">Ihre Nachricht</label>
  16. <input type="text" name="message" id="message" />
  17. </div>
  18. </form>
Quelltext in Zwischenablage kopieren

CSS
  1. body { color: #333; font-family: Arial, serif; font-size: 15px; line-height: 1.5; }
  2. form { padding: 1em; border: 1px solid #eee; background: #fafafa; }
  3. form div { margin-bottom: 1em; }
  4. label { display: block; margin-bottom:.2em; font-weight: bold; }
  5.  
  6. input {
  7. border:1px solid #ddd;
  8. padding:.5em .75em;
  9. background-color:#fff;
  10. margin:0;
  11. font-size: 1em;
  12. color: #888;
  13. vertical-align:middle;
  14. -webkit-box-shadow: inset 0 2px 0 rgba(0,0,0,0.04), 0 1px 0 white;
  15. -moz-box-shadow: inset 0 2px 0 rgba(0,0,0,0.04), 0 1px 0 white;
  16. box-shadow: inset 0 2px 0 rgba(0,0,0,0.04), 0 1px 0 white;
  17. -webkit-transition: background .1s ease-in;
  18. -moz-transition: background .1s ease-in;
  19. -o-transition: background .1s ease-in;
  20. -ms-transition: background .1s ease-in;
  21. transition: background .1s ease-in;
  22. }
  23.  
  24. input:hover {
  25. background-color: #f5f5f5;
  26. border: 1px solid #ccc;
  27. outline: none;
  28. color: black;
  29. }
  30.  
  31. input:focus {
  32. background-color: #E6EFC2;
  33. outline: none;
  34. border-color: #C6D880;
  35. }
Quelltext in Zwischenablage kopieren

JS
  1. // Hide Labels and Use Them as Values
  2. // http://snipplr.com/view.php?codeview&id=15358
  3.  
  4. $.fn.labelHide = function(){
  5. return this.each(function(){
  6. var current = $(this);
  7. var id = current.attr("id");
  8. var label = $("label[for='"+id+"']:not(.error)");
  9. if (id.length && label.length) {
  10. current.val(label.text());
  11. label.hide();
  12. }
  13. });
  14. };
  15.  
  16.  
  17. // Clear Default Input Values
  18. // http://snipplr.com/view.php?codeview&id=15360
  19.  
  20. (function($){
  21. $.fn.clearDefault = function(){
  22. return this.each(function(){
  23. var default_value = $(this).val();
  24. $(this).focus(function(){
  25. if ($(this).val() == default_value) $(this).val("");
  26. });
  27. $(this).blur(function(){
  28. if ($(this).val() == "") $(this).val(default_value);
  29. });
  30. });
  31. };
  32. })(jQuery);
  33.  
  34.  
  35. // Call Functions
  36. jQuery(document).ready(function() {
  37. $('input').labelHide().clearDefault();
  38. });
Quelltext in Zwischenablage kopieren

jsFiddle

Die Fading-Animation mache ich mit CSS-Transitions. Das Clearen selbst mag ich nicht gerne animiert. Finde ein Feld sollte sofort leer sein, wenn man darauf klickt.

Interessant ist die labelHide Funktion. Es sucht nach den dem Inputfield zugewiesenen Labels und fügt dessen Text als value ein. Man hat somit einen schöneren, zugänglicheren Quellcode, der auch ohne Javascript Sinn ergibt.
Nachteil ist, dass der Labeltext immer identisch mit dem Valuetext sein muss. Man hätte z.B. gerne „URL“ als Label und „http://“ als Value. Schade.

Sehr schön auch, wie Apple das im Checkout z.B. macht. Die Labels werden absolut so positioniert, dass sie über den Inputs liegen und wie Values aussehen. Klickt man dann auf die Labels faden sie aus und man ist im Inputfield fokusiert. Sobald man dann beginnt zu tippen verschwindet der Label/Valuetext.
Link zu diesem Beitrag in die Zwischenablage kopieren
caZpa
Veteran

28.06.11
15:07 Uhr
Ich mache das auch mit labels. Ist sowieso besser, für form Validation z.b.

http://jsfiddle.net/EVhfm/17/
Link zu diesem Beitrag in die Zwischenablage kopieren
loeffler
Veteran

28.06.11
17:21 Uhr
Das mit den Labels ist ein guter Einwand. Hab meins gleich mal modifiziert. Unterstützt jetzt Labels und Placeholder. -)

Das ganze setzt jetzt wie bei caZpa die Labels über die entsprechenden Input-Felder. Ein placeholder überschreibt immer den Text des labels (dadurch kann man bspw. erreichen, dass im Label zwar „URL“ steht, im Textfeld aber „http://“ ). Sollte kein Label existieren, aber ein Placeholder, wird wie zuvor vorgegangen, nur mit dem Unterschied, dass kein neues div, sondern ein Label mit dem entsprechenden Text gesetzt wird.

http://jsfiddle.net/loeffler/eaDMk/
Link zu diesem Beitrag in die Zwischenablage kopieren
JanB
Veteran

28.06.11
19:00 Uhr
Coole Sache )
Link zu diesem Beitrag in die Zwischenablage kopieren
 
#