Linuchs: Abfrage auf Feld-ID klappt nicht

Moin,

obwohl ich das Vorhandensein eines Feldes überprüfe ...

if ( typeof document.getElementById( "XMLHttpRequest_gesendet" ) !== "undefined" ) {
  alert ("id vorhanden: XMLHttpRequest_gesendet");
  document.getElementById( "XMLHttpRequest_gesendet" ).innerHTML = url;
}

... bekomme ich den alert und anschließend die Fehlermeldung TypeError: document.getElementById(...) is null

Was stimmt an der Abfrage nicht?

Gruß, Linuchs

  1. Tach!

    obwohl ich das Vorhandensein eines Feldes überprüfe ...

    if ( typeof document.getElementById( "XMLHttpRequest_gesendet" ) !== "undefined"
    

    ... bekomme ich den alert und anschließend die Fehlermeldung TypeError: document.getElementById(...) is null

    Wenn der Wert null ist, dann ist er nicht undefined. Deine Prüfung prüft also das falsche.

    dedlfix.

    1. Wenn der Wert null ist, dann ist er nicht undefined. Deine Prüfung prüft also das falsche.

      Verstehe ich nicht.

      Ich möchte das Vorhandensein dieser ID prüfen unabhängig vom Inhalt. Wenn ich das Objekt einrichte, passiert der Fehler nicht, obwohl der Inhalt leer (NULL?) ist:

      <p id="XMLHttpRequest_gesendet" class="em08 cdgrau"></p>
      
      1. Tach!

        Wenn der Wert null ist, dann ist er nicht undefined. Deine Prüfung prüft also das falsche.

        Verstehe ich nicht.

        Die Fehlermeldung sagt dir "... is null". Das ist nicht einfach nur ein dahergeredeter Text, den man ignorieren kann. Zudem sollte man Debugging betreiben. Wenn ein Vergleich nicht klappt, dann wäre es sinnvoll, sich den Inhalt der Beteiligten anzuschauen, um sich zu vergewissern, ob das was man da zu tun gedenkt, auch so ist.

        typeof document.getElementById( "XMLHttpRequest_gesendet" ) !== "undefined"
        

        "undefined" ist ein Stringliteral, da wird beim Prüfen nichts anderes rauskommen, kann man sich also schenken. Aber der andere Teil, typeof dingenskirchen, den kann man mal näher anschauen: console.log(typeof ...).

        Das "undefined" bezieht sich nicht auf das Vorhandensein irgendwelcher Elemente im DOM, sondern ist einer der Javascript-Typen. Wenn document.getElementById() nichts findet, dann ist das Ergebnis null, wie in "nichts vorhanden", also durchaus ein definiertes Ergebnis.

        Ich möchte das Vorhandensein dieser ID prüfen unabhängig vom Inhalt. Wenn ich das Objekt einrichte, passiert der Fehler nicht, obwohl der Inhalt leer (NULL?) ist:

        Logisch. Das Ergebnis von document.getElementById() ist in keinem Fall undefined, deine Prüfung ist also immer wahr. Aber wenn kein Element vorhanden ist, ist das Ergebnis null, und null hat kein innerHTML, weswegen es zur Fehlermeldung kommt.

        Außerdem muss man nicht den Umweg über den Typnamen gehen, man kann den Wert direkt prüfen, also

        if (document.getElementById( "XMLHttpRequest_gesendet" ) !== undefined)
        

        was immer noch stets wahr wäre, aber

        if (document.getElementById( "XMLHttpRequest_gesendet" ) !== null)
        

        das wäre der ausführliche funktionierende Vergleich. Da aber null ein falsy Wert ist, beim Finden das Ergebnis aber truthy ist, kann man den Vergleich mit dem null einsparen und gleich direkt testen, ob document.getElementById(...) wahr ist oder nicht.

        if (document.getElementById( "XMLHttpRequest_gesendet" ))
        

        Weiter kann man optimieren, dass das DOM nicht zweimal durchsucht werden muss, indem man Das Ergebnis in einer Variable ablegt und mit der weiterarbeitet.

        const sent = document.getElementById('XMLHttpRequest_gesendet');
        if (sent) {
          alert ('id vorhanden: XMLHttpRequest_gesendet');
          sent.innerHTML = url;
        }
        

        (Für alte Browser var statt const nehmen.)

        dedlfix.

        1. Hallo dedlfix,

          (Für alte Browser var statt const nehmen.)

          kennst du einen Weg, bei dem ich prüfen kann, ob der Browser var (und das andere neue Zeug) kennt, außer try/catch ?

          Gruß
          Jürgen

          1. Tach!

            kennst du einen Weg, bei dem ich prüfen kann, ob der Browser var (und das andere neue Zeug) kennt, außer try/catch ?

            Nichtmal try/catch hilft da, denn für die alten Browser ist das neue Zeugs ein Syntaxfehler, und das hat einen nicht fangbaren Abbruch zur Folge. Außer es ist in eval() und try/catch verpackt.

            dedlfix.

            1. Hallo dedlfix,

              nur, was macht man aus dieser Erkenntnis? Ob ich let oder var verwende, dürfte auf die Performance meines Scripts keinen Einfluss haben. Wenn ich also für die Let It Be Fraktion JavaScript anbieten will, dann schreibe ich eben alles für diese Sprachversion (bzw. stelle mein TypeScript oder Babel entsprechend ein).

              Würde jemand eine "große Javascript" Lösung mit let/const/... bauen und eine kleine Fallback-Version für var? Würde jemand auf die noscript-Version seiner Seite zurückfallen, weil let nicht funktioniert? Würde jemand mit Hilfe von TypeScript oder Babel zwei Versionen seines JavaScript vorhalten? Die Frage ist ernst gemeint, ich kann es nicht beantworten.

              Rolf

              --
              sumpsi - posui - clusi
              1. Hallo Rolf,

                Würde jemand eine "große Javascript" Lösung mit let/const/... bauen und eine kleine Fallback-Version für var?

                Unwahrscheinlich.

                Würde jemand auf die noscript-Version seiner Seite zurückfallen, weil let nicht funktioniert?

                Nein.

                Würde jemand mit Hilfe von TypeScript oder Babel zwei Versionen seines JavaScript vorhalten? Die Frage ist ernst gemeint, ich kann es nicht beantworten.

                Nein. Die übliche Variante ist, dass man sich anschaut, welche Browser das Zielpublikum nutzt und eine dementsprechende Sprach-Version als Ziel für Babel oder TypeScript einstellt. Geschrieben wird allerdings vollständig in ES>=6.

                nur, was macht man aus dieser Erkenntnis?

                Wenn das Projekt so klein ist, dass kein Babel/TS o.ä. verwendet wird oder wenn das Projekt Legacy-Code ist, verwendet man ES5 (und damit var). Ansonsten verwendet man ES>=6 und lässt mit Babel/TS den kleinsten gemeinsamen Nenner generieren. Der kleinste gemeinsame Nenner ergibt sich aus den Zugriffsstatistiken bzw aus einem educated guess mit Hilfe von caniuse.com.

                LG,
                CK

  2. Lieber Linuchs,

    if ( typeof document.getElementById( "XMLHttpRequest_gesendet" ) !== "undefined" )
    

    dass Du auf das falsche Ergebnis prüfst, hat @dedlfix Dir schon aufgezeigt. In meinen Projekten würde ich so vorgehen:

    if (document.getElementById("XMLHttpRequest_gesendet")) { ... }
    
    // umständlicher
    var found = document.getElementById("XMLHttpRequest_gesendet");
    
    if (found) { ... }
    

    Die Methode getElementById soll mir ein Objekt zurück liefern. Nämlich das HTMLElementObject meines HTML-Elements. Wenn sie das nicht finden kann, liefert sie mir einen Wert zurück (nämlich null), der als false gewertet werden kann. Das HTMLElementObject wäre wie true, daher kann ich den Rückgabewert einfach in dem Ausdruck des if-Statements so notieren.

    Liebe Grüße,

    Felix Riesterer.