momoxxl: Focus setzen mit Javascript

Ich habe eine einfache Seite, die nur eine Input-Feld beinhaltet. Diese Seite wird durch einen AJAX-Request in eine HTML-Seite geladen. Ändert sich dessen Ihalt durch eine benutzereingabe (onchange-Event) wird ein AJAX-Request ausgelöst. Die Eingabe wird verarbeitet, das AJAX-Response liefert diesslebe Seite (leer) zurück, der Focus sollte im Eingabefeld sein.

Leider kann ich den Focus nicht im Eingabefeld platzieren. Der Focus landet in der URL-Zeile des Browsers. Ein window.altert() führt dazu dass der Focus korrekt sitzt. Ich habe hier im Forum und auch im WWW was dazu gefunden. bekomme es aber trotzdem nicht hin. Ich verwende z.T. jQuery, aber auch mit nativem Javascript klappt es nicht. Sollte doch nicht so kompliziert sein ... ????????

Ich verwende Win7 und Mozilla FF 7.01. Aber auch mit dem IE 8 gehts genauso wenig.

Danke für jeden Tipp.

<span id="viewarea">
<script type="text/javascript" language="JavaScript">
<!--
submitData = function () {
// AJAX request, lädt dieses Seite erneut
}

setFocus = function() {  
	//$('#myID').focus();  
	document.getElementById("myID").focus();;  
}  

jQuery(function() {  
	setFocus();  
});  
  
// -->					  
</script>  

<form .... >
   <input type="text", id="myID" onchange="submitData ()"... />
</form>

</span>

  1. Hi there,

    Leider kann ich den Focus nicht im Eingabefeld platzieren. Der Focus landet in der URL-Zeile des Browsers. [...] Sollte doch nicht so kompliziert sein ... ????????

    Eh nicht. Kompliziert wird's erst, wenn man soetwas: $('#myID') verwendet. Und ganz kompliziert wird's, wenn man die entscheidende Stelle auskommentiert:

      //$('#myID').focus();  
    

    oder war das dann der Versuch, gleich das richtige zu verwenden?:

      document.getElementById("myID").focus();;  
    

    <form .... >
       <input type="text", id="myID" onchange="submitData ()"... />
    </form>

    Das Komma nach type="text" hat da nichts verloren...

    1.   //$('#myID').focus();  
      

      oder war das dann der Versuch, gleich das richtige zu verwenden?:

        document.getElementById("myID").focus();;  
      

      $('#myID') ist in jeglicher Hinsicht gleichbedeutend zu document.getElementById("myID")

      Wie ich schon öfter sagte: entweder man verwendet ein Framework oder man verwendet es nicht - wenn man ohnehin bei jeder 2. Gelegenheit dran vorbeidoktort, kann man es gleich lassen.

      Und jetzt komm mir keiner mit Performancegründen - das dürfte in den meisten Fälle nicht relevant sein, ein Framework verwendet man idR. aus Bequemlichkeit bzw. der Zeitersparnis beim Entwickeln und nicht weil es besonders schnell/performant ist.

      1. Hi,

        $('#myID') ist in jeglicher Hinsicht gleichbedeutend zu document.getElementById("myID")

        Nein.
        $('#myID')[0] wäre gleichbedeutend.

        ~dave

        1. $('#myID') ist in jeglicher Hinsicht gleichbedeutend zu document.getElementById("myID")

          Nein.
          $('#myID')[0] wäre gleichbedeutend.

          Jein - wenn es mehrere elemente mit derselben ID gibt, kommts auf den Browser an.

          Nagle mich jetzt nicht fest, aber es gibt wenn ich nicht irre auch Browser die dann mit getElementById das letzte mit der gennanten ID liefern.

          Gehen wir aber prinzipiell mal von gültigem Code aus.

          Und wie schon gesagt: wenn Framework, dann richtig

          $('#myID:eq(0)') :p

          1. @@suit:

            nuqneH

            Und wie schon gesagt: wenn Framework, dann richtig

            Da stimme ich dir zu.

            $('#myID:eq(0)') :p

            Aber hier hätte ich doch eher $('myID').first() angeführt.

            Gibt es da Unterschiede in der Performanz?

            Qapla'

            --
            Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
            (Mark Twain)
            1. $('#myID:eq(0)') :p

              Aber hier hätte ich doch eher $('myID').first() angeführt.

              Gibt es da Unterschiede in der Performanz?

              Gute Frage - Daumen mal Pi würde ich sagen, dass deine Variante langsamer ist :p

              ABER:
              http://jsfiddle.net/PhLtt/

              $('#myID') liefert - auch wenn eine ID mehrfach vergeben ist - trotzdem nur ein Element.

              dave hatte also unrecht :)

              1. $('#myID:eq(0)') :p

                Aber hier hätte ich doch eher $('myID').first() angeführt.

                Gibt es da Unterschiede in der Performanz?

                Gute Frage - Daumen mal Pi würde ich sagen, dass deine Variante langsamer ist :p

                Damit wir das hier festhalten, ich hatte unrecht: .first() ist je nach Browser 5 bis 10x so schnell.

                http://jsfiddle.net/XHx54/

                1. @@suit:

                  nuqneH

                  Damit wir das hier festhalten, ich hatte unrecht: .first() ist je nach Browser 5 bis 10x so schnell.

                  Hm, vielleicht sollte man gerechterweise $('#myID:eq(0)') und $('#myID').eq(0) vergleichen?

                  Qapla'

                  --
                  Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
                  (Mark Twain)
                  1. @@Gunnar Bittersmann:

                    nuqneH

                    Damit wir das hier festhalten, ich hatte unrecht: .first() ist je nach Browser 5 bis 10x so schnell.

                    Hm, vielleicht sollte man gerechterweise $('#myID:eq(0)') und $('#myID').eq(0) vergleichen?

                    .eq(0) ist noch etwas schneller als .first().

                    Ohne jetzt in den jQuery-Quelltext zu kucken würde ich vermuten, intern wird .first() zu .eq(0) umgesetzt.

                    Interessant der deutliche Unterschied zwischen jQuery und der DOM-Methode. Wasser auf Klawischniggs Mühlen. ;-)

                    Qapla'

                    --
                    Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
                    (Mark Twain)
                    1. Ohne jetzt in den jQuery-Quelltext zu kucken würde ich vermuten, intern wird .first() zu .eq(0) umgesetzt.

                      .eq(n) wird intern vermutlich auch zu [n] umgemünzt, dennoch ist der Unterschied zur DOM-Variante enorm.

                      Interessant der deutliche Unterschied zwischen jQuery und der DOM-Methode. Wasser auf Klawischniggs Mühlen. ;-)

                      Wieso? Ich hab' doch explizit gesagt, dass man das Framework nicht aus Performancegründen einsetzt sondern eben um sich Code und Zeit zu sparen.

                      Beim Auswählen einer ID kommt das natürlich nicht so deutlich rüber - aber bei komplexeren DOM-Manipulationen wird man ohne Framework ziemlich schnell Arm, wenn man das auch noch crossbrowserkompatibel haben will.

                      Ich hab' das mal vervollständigt:
                      http://jsfiddle.net/Vf7hf/

                    2. Hi there,

                      Interessant der deutliche Unterschied zwischen jQuery und der DOM-Methode. Wasser auf Klawischniggs Mühlen. ;-)

                      Danke, ich werd' einen Generator anhängen...;)

                    3. Interessant der deutliche Unterschied zwischen jQuery und der DOM-Methode. Wasser auf Klawischniggs Mühlen. ;-)

                      Das ist bekannt, aber nicht als Argument für irgendetwas brauchbar. $('#foo') ist nicht äquivalent zu getElementById('foo'). Ersteres prüft z.B., ob das zurückgelieferte Element auch tatsächlich eine solche ID hat. Klingt dumm, aber ältere IEs und Operas liefern gerne Elemente mit dem angegebenen Namen zurück (wie es document.all getan hat).
                      https://github.com/jquery/jquery/blob/master/src/core.js#L144

                      Cross-Browser-Kompatibilität ist nicht so einfach, wie man denkt. Natürlich reicht ein getElementById völlig - wenn man von ganz spezifischen neueren Browsern im Standard-Modus ausgeht und gerade die Use-Cases testet, die in der gegenwärtig entwickelten Software aktuell vorkommen. Das tun Bibliotheken wie jQuery nicht. Deshalb sind sie robuster, aber auch langsamer als Low-Level-Operationen.

                      Mathias

            2. $('#myID:eq(0)') :p

              Aber hier hätte ich doch eher $('myID').first() angeführt.

              Gibt es da Unterschiede in der Performanz?

              Selektor-Engines nehmen verschiedene Optimierungen vor, wählen dann die Grundmethoden (getElementById, getElementsByTagName, getElementsByClassName, querySelectorAll usw.) und arbeiten sich bei Nicht-CSS-Selektoren wie :eq mit eigenen Filtermethoden vor. Eine Optimierung ist die Erkennung einfacher Selektoren. Der einfachste Selektor #\w+ durchläuft nicht die komplette Engine, sondern wird direkt zu getElementById umgesetzt. Daher ist es i.d.R. schneller, einen einfachen Selektor zu verwenden und hinterher manuell Filtermethoden anzulegen.

              Mathias

      2. Hi there,

        $('#myID') ist in jeglicher Hinsicht gleichbedeutend zu document.getElementById("myID")

        in welcher Programmiersprache? Gleichbedeutend wäre, ich setzt mich in, denk nix böses, möchte auf irgendein Element im DOM zugreifen und schreibe $('#myID'). Doch plötzlich, siehe, sogar der &%$MrxBrowser von Mirkosaft wirft eine Fehlermeldung...

        Wie ich schon öfter sagte: entweder man verwendet ein Framework oder man verwendet es nicht - wenn man ohnehin bei jeder 2. Gelegenheit dran vorbeidoktort, kann man es gleich lassen.

        so isses. Deswegen ist es besser, man lässt es gleich bleiben...

        1. in welcher Programmiersprache? Gleichbedeutend wäre, ich setzt mich in, denk nix böses, möchte auf irgendein Element im DOM zugreifen und schreibe $('#myID'). Doch plötzlich, siehe, sogar der &%$MrxBrowser von Mirkosaft wirft eine Fehlermeldung...

          $('#myID') führt mit jQuery in jedem Browser zu demselben Ergebnis - das ist unter anderem der Vorteile eines Frameworks: es sorgt dafür, solche differenzen zwischen den Browser zu normalisieren.

          Wie ich schon öfter sagte: entweder man verwendet ein Framework oder man verwendet es nicht - wenn man ohnehin bei jeder 2. Gelegenheit dran vorbeidoktort, kann man es gleich lassen.

          so isses. Deswegen ist es besser, man lässt es gleich bleiben...

          Wenn man über genügend Zeit und Know-How verfügt um die Unterschiede selbst auszubügeln ist das sicher OK - aber in den anderen Fällen würde ich eben die "Konseqent nutzen"-Variante bevorzugen.

          Ich handhabe das jedenfalls so - <schleim><![CDATA[einem Mathias Schäfer mag es völlig wurst sein ob er jetzt MooTools, jQuery oder blankes JavaScript verfasst - der weiß, welche Eigenheiten welcher Browser hat.]]></schleim> - aber für mich ist sowas ein Ding der "Unmöglichkeit" :)

          1. Hi there,

            $('#myID') führt mit jQuery in jedem Browser zu demselben Ergebnis - das ist unter anderem der Vorteile eines Frameworks: es sorgt dafür, solche differenzen zwischen den Browser zu normalisieren.

            Du sagst, es, mit jQuery. Das ist aber nicht Bestandteil von Javascript, nicht einmal eine Erweiterung, es ist schlicht und ergreifend eine in Javascript geschriebene Library (naja, vor tausenden von Jahren hat man zu so etwas halt Library gesagt)

            Ich handhabe das jedenfalls so - <schleim><![CDATA[einem Mathias Schäfer mag es völlig wurst sein ob er jetzt MooTools, jQuery oder blankes JavaScript verfasst - der weiß, welche Eigenheiten welcher Browser hat.]]></schleim> - aber für mich ist sowas ein Ding der "Unmöglichkeit" :)

            Ja eh. Ich kenn halt die Macken von ein paar Browsern, die müssen meine Kunden verwenden und das wars dann. Wenn sich jemand beschwert, daß das mit seinem exotischen Lieblingsbrowser oder irgendeiner Klicki-Bunti-Alphaversion von einem quasireligiösen Konzern daherkommt, dann sag ich ihm, er soll sich einen neuen Browser installieren oder ein neues Programm suchen. Bei Webseiten (die ich ohnehin immer seltener mache) verwend' ich kein Javascript, dort mag das einen gewissen Vorteil haben, andererseits muss man auch da sagen, Leute die solche Browserexoten etc. verwenden werden schon wissen, warum sie das tun, die sind Kummer ohnehin gewöhnt...

          2. Wenn man über genügend Zeit und Know-How verfügt um die Unterschiede selbst auszubügeln ist das sicher OK - aber in den anderen Fällen würde ich eben die "Konseqent nutzen"-Variante bevorzugen.

            Ich handhabe das jedenfalls so - <schleim><![CDATA[einem Mathias Schäfer mag es völlig wurst sein ob er jetzt MooTools, jQuery oder blankes JavaScript verfasst - der weiß, welche Eigenheiten welcher Browser hat.]]></schleim> - aber für mich ist sowas ein Ding der "Unmöglichkeit" :)

            Mit Sicherheit nicht. Jede robuste DOM-Bibliothek hat eine Komplexität, die ein Einzelner nicht überblicken kann. Ich würde nicht behaupten, eine solche Bibliothek schreiben zu können. Dafür gibt es zuviele Browserfehler zu beachten, die sich seit 10 Jahren angehäuft haben. Man kann dieses Wissen, das andere erarbeitet haben, höchstens zeitaufwändig recherchieren. Eine Bibliothek wie jQuery kann man nur mit exzessivem Unit-Testing entwickeln. Mit Können hat das nichts zu tun, das ist einfach Fleißarbeit.

            Schau dir einmal jQuery-Changelogs an, deren Entwickler sind weit davon entfernt, besonders klug zu sein oder alles richtig zu machen. Das einzige, was die können und was jeder kann, ist Fehler machen, Fehler einsehen, Fehler korrigieren und Tests schreiben. Wenn viele mitmachen und die Maintainer ihre Aufgabe gut machen, ist dieser Kreislauf klein und wiederholt sich häufig. Software-Entwicklung ist i.d.R. so erschreckend primitiv.

            Es läuft daher wirklich darauf hinaus, was du auch sagst: Mit genug Zeit könnte man in jede Falle noch einmal rennen und jedes Problem noch einmal lösen. Ich wüsste aber nicht, welchen Reiz das hat, außer einem Lerneffekte wie bei DailyJS Let's make a Framework. Ich programmiere, um irgendeinen Nutzwert zu erhalten, meistens professionell unter Zeitdruck, und niemanden bezahlt einen dafür, ungetestete, undokumentierte DOM-Bibliotheken zu bauen.

            Mathias

  2. Damit wir da auch mal zu einem Schluss kommen:

    die Reihenfolge beachten.

    Du kannst kein Element mit JavaScript in den Fokus rücken, wenn es noch garnicht existiert.

    ggf. solltest du die jQuery-Variante nehmen und mit $(document).ready(); kapseln, damit sie erst ausgeführt wird, wenn das DOM komplett ist (oder zumindest das ready() auf das Element mit der Wunsch-ID packen.

    1. Danke für die vielen Tipps,

      leider habe ich es immer noch nicht geschafft. Lt. JQuery-Doku (http://api.jquery.com/ready/) ist

      jQuery(function() {
      ...
      });

      identisch mit

      $(document).ready(function() {
      ...
      });

      und sollte auch erst ausgeführt werden wenn das DOM vollständig ist:
      Description: Specify a function to execute when the DOM is fully loaded.

      Aber, da sich die Seite selbst nachlädt, stellt sich mir die Frage: ist das DOM nicht auch schon immer vollständig, dann wird das DOM durch AJAX aber nur noch aktualisiert.
      Beim erstmaligen Laden der Seite funktioniert der Code ja auch, nur wenn die Seite via AJAX aktualisiert wird nicht.

      Grüße
      momoxxl

      Damit wir da auch mal zu einem Schluss kommen:

      die Reihenfolge beachten.

      Du kannst kein Element mit JavaScript in den Fokus rücken, wenn es noch garnicht existiert.

      ggf. solltest du die jQuery-Variante nehmen und mit $(document).ready(); kapseln, damit sie erst ausgeführt wird, wenn das DOM komplett ist (oder zumindest das ready() auf das Element mit der Wunsch-ID packen.

      1. Danke für die vielen Tipps,

        leider habe ich es immer noch nicht geschafft. Lt. JQuery-Doku (http://api.jquery.com/ready/) ist

        jQuery(function() {
        ...
        });

        identisch mit

        $(document).ready(function() {
        ...
        });

        jQuery anstatt $ setzt aber den noConflict-Modus voraus, wenn ich jetzt nicht irre.

        Aber, da sich die Seite selbst nachlädt, stellt sich mir die Frage: ist das DOM nicht auch schon immer vollständig, dann wird das DOM durch AJAX aber nur noch aktualisiert.

        Wenn du durch Ajax nachher eine aktualisierung vornimmst, ist es schon zu spät - aber hierzu gibts success bzw. ajaxStop() und auf Ajax-Vorgänge zu reagieren.

        Beim erstmaligen Laden der Seite funktioniert der Code ja auch, nur wenn die Seite via AJAX aktualisiert wird nicht.

        Dann ist ajaxStop() dein Freund - einfach das dort ausführen, was du auch bei ready() ausführst.

        Ich hab' gestern deine Frage falsch verstanden bzw. nicht genau genug gelesen.