Martin Seidel: Javascript Überprüfung ob Datei vorhanden

Hallo,

ich möchte mit Javascript eine if Anweisung schreiben, die überprüft ob eine Datei in einem Unterverzeichnis vorhanden ist, wenn das der Fall ist soll ein html link dargestellt werden, wenn nicht soll nichts passieren. Also etwa so:

if exist "xyz/01.jpg" then <a href="..."></a> else fi

kann mir jemand bei der Implementierung helfen?

Gruß Martin

akzeptierte Antworten

  1. Hallo,

    mit Javascript ... eine Datei

    JS ist nicht wirklich für Arbeit auf Dateiebene gedacht.
    Außerdem solltest du präzisieren, wo genau du eine bestimmte Datei suchst. Beim User? nö, da hast du nix zu suchen. Auf dem Server? Da solltest du serverseitig arbeiten.

    Warum hast du java/jsp als tag gewählt? Was genau hast du vor?

    Gruß
    Kalk

    1. Was genau hast du vor?

      Ich habe auf einer Seite eine Anzahl Links erstellt, die über Bilder dargestellt werden:

      <a href=01.html><img src=01.jpg></img></a>
      <a href=02.html><img src=02.jpg></img></a>
      <a href=03.html><img src=03.jpg></img></a>
      usw...
      
      

      Diese Links sollen jedoch nur dargestellt werden wenn die zugehörigen Bilder vorhanden sind. Die Anzahl der Bilder wird sich jedoch laufend ändern. Das Ziel ist es Wartungsaufwand zu reduzieren, da der Server von Laien gewartet werden soll. Es geht im Grunde darum dass das Fehlersymbol ausgeblendet wird, wenn ein Bild nicht vorhanden ist.

      Du bist nicht etwa identisch mit Tobias Fritsch?

      Wenn ich das richtig verstanden habe ist es fast genau seine Problemstellung, denn mein Ziel ist nicht eine sofortige Weiterleitung, sondern nur dass html code "verarbeitet wird". Ist das überhaupt möglich?

      1. Hallo,

        Es geht im Grunde darum dass das Fehlersymbol ausgeblendet wird, wenn ein Bild nicht vorhanden ist.

        Genau für den Fall ist das alt-Attribut für img-Elemente vorgesehen. Das soll(te) man nicht unterschlagen.

        Gruß
        Kalk

        1. ich habe es mit alt="" versucht, leider wird immer noch ein Symbol angezeigt, dass das Bild nicht vorhanden ist...

      2. Diese Links sollen jedoch nur dargestellt werden wenn die zugehörigen Bilder vorhanden sind. Die Anzahl der Bilder wird sich jedoch laufend ändern.

        Du kannst an img-Elementen auf das error-Ereignis warten; tritt es ein, konnte die URL nicht geladen werden.

        Das Ziel ist es Wartungsaufwand zu reduzieren, da der Server von Laien gewartet werden soll. Es geht im Grunde darum dass das Fehlersymbol ausgeblendet wird, wenn ein Bild nicht vorhanden ist.

        Die Begründung erschließt sich mir nicht so recht. Es gibt einerseits das bereits genannte alt-Attribut, falls der Verweis noch benutzbar sein soll. Alternativ könnte srcset in Frage kommen, falls ein allgemeines Alternativbild gewünscht ist (ich weiss nicht, ob das auch für Ladefehler funktioniert, da geht es mehr um Auflösungen).
        Andererseits, soll der Verweis bei fehlendem Bild nicht mehr benutzbar sein, frage ich mich, warum überhaupt erst Verweise ausgegeben werden, obwohl der Server selber am besten weiss, dass das dazugehörige Bild fehlt. Der Browser muss stattdessen mehrmals quasi im Nebel rumstochern, was dem Seitenaufbau nicht förderlich ist.

        1. Klar ist das nicht optimal, wie ich schon erwähnte geht es darum die Serverwartung für Laien zu ermöglichen, die nur Bilder auf einen Server kopieren oder löschen.

          Unter Firefox werden die Links mit dem Alt Attribut tatsächlich ausgeblendet, unter Opera und Chrome leider nicht.

          1. Hallo,

            Serverwartung für Laien

            das halte ich für einen groben Konzeptfelher!

            Gruß
            Kalk

          2. geht es darum die Serverwartung für Laien zu ermöglichen, die nur Bilder auf einen Server kopieren oder löschen.

            Darauf können sie sich ja auch gerne beschränken und hindert den Server doch nicht daran, die Seite den vorhandenen Bildern entsprechend auszugeben.

            Wie dem auch sei: Mit img.addEventListener("error", blendemiraus(img)) sollte sich das per Javascript machen lassen.

      3. @@Martin Seidel

        <a href=01.html><img src=01.jpg></img></a>
        <a href=02.html><img src=02.jpg></img></a>
        <a href=03.html><img src=03.jpg></img></a>
        usw...
        

        Das HTML ist kaputt. Zum einen gibt es beim img-Element kein End-Tag[1], zum anderen muss ein img-Element immer einen Alternativtext (alt-Attribut) haben.

        <a href=01.html><img src="01.jpg" alt="Bild 1"></a>
        <a href=02.html><img src="02.jpg" alt="Bild 2"></a>
        <a href=03.html><img src="03.jpg" alt="Bild 3"></a>
        

        Du solltest überlegen, wie du statt „Bild 1, 2, 3, …“ zu aussagekräftigen Alternativtexten kommst.

        Diese Links sollen jedoch nur dargestellt werden wenn die zugehörigen Bilder vorhanden sind.

        Du bist die Antwort schuldig geblieben, wie du darauf kommst, das mit JavaScript machen zu wollen (wo der Client (Browser) erst einen Request zum Server schicken muss) anstatt bspw. mit PHP (wo der Server selbst nachsieht, ob eine entsprechende Datei vorhanden ist und wenn ja entsprechendes HTML dafür generiert).

        Es geht im Grunde darum dass das Fehlersymbol ausgeblendet wird, wenn ein Bild nicht vorhanden ist.

        Nein. Es geht im Grunde darum, dass ein Verweis auf ein nicht vorhandenes Bild gar nicht erst in HTML auftaucht.

        LLAP 🖖

        --
        “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
        Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|

        1. Es sei denn, es handelt sich um als XML verarbeitetes XHTML. ↩︎

        1. Du bist die Antwort schuldig geblieben, wie du darauf kommst, das mit JavaScript machen zu wollen (wo der Client (Browser) erst einen Request zum Server schicken muss) anstatt bspw. mit PHP (wo der Server selbst nachsieht, ob eine entsprechende Datei vorhanden ist und wenn ja entsprechendes HTML dafür generiert).

          Achso, ich wusste nicht, dass das mit PHP auch möglich ist, also wenn es nicht allzuviel Code benötigt (die Abfrage soll für 30 Links laufen) dann mache ich das gerne so.

          Falls es zu aufwändig wird, ist es vielleicht einfacher wenn ich ein AutoIT Script schreibe mit dem die entsprechende Zeile im Quelltext auskommentiert wird und anschließen neu auf den Server geladen wird. Aber das gehört dann nicht mehr hier ins Forum

          Gruß Martin

          1. Tach!

            Achso, ich wusste nicht, dass das mit PHP auch möglich ist, also wenn es nicht allzuviel Code benötigt (die Abfrage soll für 30 Links laufen) dann mache ich das gerne so.

            An der Stelle, an der du die Links erzeugst, kannst du auch je Link nach file_exists() die Existenz der Datei befragen und entsprechende HTML-Ausgabe erzeugen - im einfachsten Fall. Die Daten für die Links kommen doch in Form eines Arrays aus einer Datenquelle und du läufst da mit foreach drüber, oder ähnlich? Dann kommt die Existenzabfrage mit in den foreach-Schleifenkörper.

            dedlfix.

            1. An der Stelle, an der du die Links erzeugst, kannst du auch je Link nach file_exists() die Existenz der Datei befragen und entsprechende HTML-Ausgabe erzeugen - im einfachsten Fall. Die Daten für die Links kommen doch in Form eines Arrays aus einer Datenquelle und du läufst da mit foreach drüber, oder ähnlich? Dann kommt die Existenzabfrage mit in den foreach-Schleifenkörper.

              Ich hab mich mal ein bisschen Schlau gemacht in PHP, leider funktioniert es so noch nicht:

              <?php
              	
              $nummer = 30;
              
              for($i=1; $i < count($nummer); $i++) {
                  
                  if (file_exists("images/carpet_preview/klassisch/"$i".jpg")) {
                		  echo "<a href="zpic-carpet-klassisch-"$i".php" alt=" "><img src="images/carpet_preview/klassisch/"$i".jpg" class="zoom-gal" /></a>";
                	 }
              }
               
              ?>
              

              Ich brauche noch eine Möglichkeit wie ich bei den Zahlen 1-9 eine Null davor setze, evtl. sowas?:

              $myText = (string)$myVar;
              

              Gruß Martin

              1. Tach!

                Ich brauche noch eine Möglichkeit wie ich bei den Zahlen 1-9 eine Null davor setze, evtl. sowas?:

                Wenn Zahl kleiner als 10 dann '0' ansonsten Leerstring.

                Oder du verwendest die Funktion str_pad().

                dedlfix.

                1. Hallo,

                  Ich brauche noch eine Möglichkeit wie ich bei den Zahlen 1-9 eine Null davor setze, evtl. sowas?:

                  Wenn Zahl kleiner als 10 dann '0' ansonsten Leerstring.

                  Oder du verwendest die Funktion str_pad().

                  oder sprintf(), dann ist auch das Zusammenbasteln des Strings ordentlicher.

                  So long,
                   Martin

                  --
                  Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
                  - Douglas Adams, The Hitchhiker's Guide To The Galaxy
                  1. Es funktioniert! Echt cool, ich wusste garnicht dass man mit php soviel machen kann. Falls jemand was ähnliches sucht hier mal der Quelltext:

                    <?php
                    	
                    $nummer = 100;
                    
                    for($i=0; $i < $nummer; $i++) 
                    {
                    
                    	if($i<10)
                    	{
                    		$format = 'http://localhost/zpic-carpet-klassisch-0%d.php';
                    		$link = sprintf($format, $i);
                    		
                    		$format = 'images/carpet_preview/klassisch/0%d.jpg';		
                    		$bild = sprintf($format, $i);
                    			
                    	}
                    	else
                    	{
                    		$format = 'http://localhost/zpic-carpet-klassisch-%d.php';
                    		$link = sprintf($format, $i);
                    		
                    		$format = 'images/carpet_preview/klassisch/%d.jpg';		
                    		$bild = sprintf($format, $i);
                    	}
                    	
                       if (file_exists($bild)) 
                       {
                      	  echo '<a href=' .$link. ' alt=" "><img src='.$bild.' class="zoom-gal" /></a>';
                      	}
                      	else 
                      	{
                      	}
                    }
                     
                    ?>
                    

                    Gruß Martin

                    1. PHP kann "alles", für einen gewissen Wert von alles. Es mag nur irgendwann zu langsam sein. Aber dafür gibt's dann alternative Ausführungsumgebungen, z.B. ist Facebook in PHP geschrieben, und nutzt einen eigenen optimierten Interpreter (vll auch Compiler, weiß nicht genau).

                      Deine Schleife lässt sich viel optimaler ausdrücken, wenn Du, wie vorgeschlagen, eine entsprechende Formatierung nutzt. Die Formatsymbole von printf und Konsorten sind hier beschrieben. Der ganze Rest von PHP ist von da aus erreichbar ;-)

                      %d heißt: Hier eine Zahl in der benötigten Größe ausgeben.
                      %2d heißt: Hier eine Zahl mit Länge von 2 oder mehr ausgehen. Ist sie einstellig, nach links mit Leerstellen auffüllen.
                      %02d heißt: Hier eine Zahl mit Länge von 2 oder mehr ausgeben. Ist sie einstellig, nach links mit Nullen auffüllen.

                      Sodann hat PHP ein Feature, das sich Variablenexpansion nennt (hier dokumentiert). Statt
                      'Hallo '.$name.', wie geht es'
                      kannst Du auch schreiben
                      "Hallo $name, wie geht es".
                      Das passiert nur bei Strings, die in doppelten Anführungszeichen stehen (oder Heredoc Syntax nutzen, siehe vorigen Link). Strings in einfachen Anführungszeichen expandieren nicht.

                      Dein Code optimiert sich damit zu:

                      for ($i=0; $i < $nummer; $i++) 
                      {
                         $link = sprintf('http://localhost/zpic-carpet-klassisch-%02d.php', $i);
                         $bild = sprintf('images/carpet_preview/klassisch/%02d.jpg', $i);
                      	
                         if (file_exists($bild)) 
                         {
                            echo "<a href='$link' alt=' '><img src='$bild' class='zoom-gal' /></a>";
                         }
                      }
                      

                      Damit das funktioniert, musste ich die von Dir genutzte Anführungszeichenverwendung umdrehen. Doppelte für PHP, und einfache fürs generierte HTML. Wenn Du bisher immer einfache Anführungszeichen für deinen PHP Code genutzt hast, bedeutet das für Dich etwas Aufmerksamkeit. Aber das ist eine PHP Vorgabe. Willst Du Variablenexpansion, brauchst Du doppelte Anführungszeichen (oder Heredoc Syntax, siehe die verlinkte PHP Seite).

                      Die leere Else habe ich nach Hause geschickt, der war es zu langweilig.

                      Rolf

                      1. @@Rolf b

                        Deine Schleife lässt sich viel optimaler ausdrücken,

                        Es gibt kein „optimaler“. „Optimal“ lässt sich nicht mehr steigern.

                        Dein Code optimiert sich damit zu:

                        Auch dein Code ist nicht optimal.

                              echo "<a href='$link' alt=' '><img src='$bild' class='zoom-gal' /></a>";
                        

                        Fehler: Der Alternativtext fürs Bild fehlt. Und beim a-Element hätte das alt-Attribut auch nichts zu suchen.

                        Und natürlich: Markup nicht mit PHP ausgeben

                        Damit das funktioniert, musste ich die von Dir genutzte Anführungszeichenverwendung umdrehen. Doppelte für PHP, und einfache fürs generierte HTML. Wenn Du bisher immer einfache Anführungszeichen für deinen PHP Code genutzt hast, bedeutet das für Dich etwas Aufmerksamkeit.

                        … und schon löst sich die mit Anführungszeichen verbundene Aufmerksamkeit in Luft auf.

                        LLAP 🖖

                        --
                        “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
                        Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
                      2. PHP kann "alles", für einen gewissen Wert von alles. Es mag nur irgendwann zu langsam sein. Aber dafür gibt's dann alternative Ausführungsumgebungen, z.B. ist Facebook in PHP geschrieben, und nutzt einen eigenen optimierten Interpreter (vll auch Compiler, weiß nicht genau).

                        Facebook hat sich schon länger von PHP getrennt, die neue Codebasis basiert auf der hauseigenen Programmiersprache Hacklang. Die Sprache wird von einem Just-In-Time-Compiler (genannt HHVM) ausgeführt, der auch PHP verarbeiten kann. Reines PHP wird allerdings meistens nur interpretiert oder auf dem JIT-Compiler von Zend ausgeführt, der seinerseits auf LLVM basiert.

                    2. @@Martin Seidel

                      Falls jemand was ähnliches sucht hier mal der Quelltext:

                      Dein Quelltext ist (noch) nicht dazu geeignet, dass sich andere ein Beispiel dran nehmen könnten.

                      Es wurde gesagt:

                      Wenn Zahl kleiner als 10 dann '0' ansonsten Leerstring.

                      Oder du verwendest die Funktion str_pad().

                      oder sprintf(), dann ist auch das Zusammenbasteln des Strings ordentlicher.

                      Oder“, nicht „und“.

                      	if($i<10)
                      

                      Die Abfrage macht überhaupt keinen Sinn, da die genannten Funktionen str_pad() bzw. sprintf() eben genau diese Aufgabe erfüllen, die Ausgabe zu formatieren – in dem Fall eine Zahl bei der Ausgabe mit führenden Nullen auf die gewünschte Stellenzahl aufzufüllen. Die Dokumentation wurde dir doch verlinkt. Bei beiden Funktionen geht aus den dort angegebenen Beispielen hervor, wie diese Funktionen anzuwenden sind.


                      Desweiteren solltest du nie™ Markup mit PHP ausgeben, sondern nur die jeweils eingefügten Werte. Also nicht HTML in PHP schachteln, sondern PHP in HTML.

                      Die Variablen/Konstanten definierst du gleich zu Anfang der Datei:

                      <?php
                      $number = 100;
                      $pathToPage = 'http://localhost/zpic-carpet-klassisch-%02d.php';
                      $pathToImage = 'images/carpet_preview/klassisch/%02d.jpg';
                      ?>
                      <!DOCTYPE html>
                      <html lang="de">
                      

                      Die Anpassung der Pfade überlasse ich dir. localhost wird ja nicht der endgültige sein.

                      $nummer hab ich mal umbenannt in $number – im Sinne von „Anzahl“; nicht „(laufende) Nummer“, denn das wäre ja $i.

                      Für die Kontrollstrukturen verwendest du die alternative Syntax:

                      <?php for($i=0; $i < $number; $i++): ?>
                        <?php if (file_exists(sprintf($pathToImage, $i))): ?>
                          <a href="<?php echo sprintf($pathToPage, $i); ?>">
                            <img class="zoom-gal" src="<?php echo sprintf($pathToImage, $i); ?>" alt="Bild <?php echo $i; ?>"/>
                          </a>
                        <?php endif; ?>
                      <?php endfor; ?>
                      

                      Für <?php echo?> kannst du auch kurz <?=?> schreiben.

                      Oder anstatt <?php echo sprintf() ?> gleich <?php printf() ?> verwenden.

                      LLAP 🖖

                      --
                      “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
                      Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
                      1. Moin,

                        [zahlreiche Verbesserungsvorschläge]

                        und last, but not least würde ich empfehlen, nicht stur von 0 (oder 1) bis 100 durchzuzählen und so 100mal das Dateisystem zu befragen "gibt's diese Datei?", sondern nur einmal zu fragen "was haben wir denn überhaupt?"

                        Das ist hier ein bisschen knifflig, weil die Pfade für die Bilder und die eigentlichen Links leicht verschieden sind, aber vielleicht findet sich da auch noch eine schlaue Lösung.

                        Ich weiß zwar nicht, ob file_exists() ein nennenswerter Performance-Killer ist, aber Dateisystem-Zugriffe sind allgemein teuer, und ich reduziere die gern auf das nötige Minimum.

                        So long,
                         Martin

                        --
                        Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
                        - Douglas Adams, The Hitchhiker's Guide To The Galaxy
                        1. Ich weiß zwar nicht, ob file_exists() ein nennenswerter Performance-Killer ist, aber Dateisystem-Zugriffe sind allgemein teuer, und ich reduziere die gern auf das nötige Minimum.

                          also wenn ich die Galerie aufrufe (auch über einen web-link) dann kann ich keinen Performance-verlust feststellen. Die Seite wird auch nicht übermäßig frequentiert werden, also ich nehme mal an es wird deswegen keinen Serverabsturz bei Strato geben ;)

                          Bin ganz froh dass es jetzt so funktioniert, weitere Kniffe habe ich mir für die nächste Webseite auf :)

                          Gruß Martin

  2. Hallo Martin Seidel,

    ich möchte mit Javascript eine if Anweisung schreiben, die überprüft ob eine Datei in einem Unterverzeichnis vorhanden ist, wenn das der Fall ist soll ein html link dargestellt werden, wenn nicht soll nichts passieren.

    Du bist nicht etwa identisch mit Tobias Fritsch?

    Bis demnächst
    Matthias

    --
    Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
  3. Lieber Martin,

    Du kannst das nicht in einem simplen if-else-Zweig verarbeiten. Um festzustellen, ob eine Datei vorhanden ist, musst Du sie mit JS anfordern, damit der Browser sie lädt. Das kann man im Hintergrund mit AJAX machen (XmlHttpRequest nennt sich das erforderliche Werkzeug). Je nach Rückmeldung dieses Vorgangs, der sicher einige (Milli-)Sekunden benötigt, kannst Du dann entsprechend reagieren.

    Auf diese Weise "pflanzt" Du verschiedene Ladeprozesse, die ihrerseits "irgendwann" etwas tun, wenn sie abgeschlossen sind. Sie können im Erfolgs- oder Fehlerfall ihnen zugewiesene Callback-Funktionen ausführen, die zu einer völlig anderen Zeit abgearbeitet werden (Du kannst nicht beeinflussen wann und in welcher Reihenfolge!), als es Dein Hauptzweig, der die Ladeprozesse verursacht, tut. Daher hätte es einen Sinn, wenn die Callback-Funktionen sich ein bestimmtes Element per ID schnappen, um dieses dann im Erfolgsfall mit einem entsprechenden Inhalt zu befüllen. Im Fehlerfall tun sie das halt nicht.

    Liebe Grüße,

    Felix Riesterer.

    1. Tach!

      Du kannst das nicht in einem simplen if-else-Zweig verarbeiten. Um festzustellen, ob eine Datei vorhanden ist, musst Du sie mit JS anfordern, damit der Browser sie lädt. Das kann man im Hintergrund mit AJAX machen (XmlHttpRequest nennt sich das erforderliche Werkzeug). Je nach Rückmeldung dieses Vorgangs, der sicher einige (Milli-)Sekunden benötigt, kannst Du dann entsprechend reagieren.

      Mir ist da neulich die Fetch API über den Weg gelaufen. Damit ist ein Ajax-Request fast so simpel wie ein if-else.

      fetch(url, {method: 'HEAD'}) // in dem Fall nicht die gesamte Resource laden sondern nur den HTTP-Header
        .then(function(response) {
      	
        })
        .catch(function(err) {
      	// Error :(
        });
      

      Man muss dazu nur das Promise-Konzept kennen, und dann wissen, dass alles was vom Ergebnis des Fetchens abhängig ist nicht unterhalb des fetch()-Aufrufs stehen kann, sondern innerhalb der bei then() übergebenen Funktion, beziehungsweise aus ihr heraus aufgerufen werden muss.

      dedlfix.

      1. Hallo,

        Mir ist da neulich die Fetch API über den Weg gelaufen. Damit ist ein Ajax-Request fast so simpel wie ein if-else.

        leider ist es für fetch noch etwas zu früh.

        Gruß
        Jürgen

        1. Tach!

          Mir ist da neulich die Fetch API über den Weg gelaufen. Damit ist ein Ajax-Request fast so simpel wie ein if-else.

          leider ist es für fetch noch etwas zu früh.

          Safari und ein alter IE. Kann man vielleicht drauf verzichten, wenn es um eine interne Anwendung geht.

          dedlfix.

          1. Safari und ein alter IE. Kann man vielleicht drauf verzichten, wenn es um eine interne Anwendung geht.

            Leider nicht, Unterstützung bis IE unter Win7 SP1 erforderlich!

            1. Tach!

              Safari und ein alter IE. Kann man vielleicht drauf verzichten, wenn es um eine interne Anwendung geht.

              Leider nicht, Unterstützung bis IE unter Win7 SP1 erforderlich!

              Na gut, dann kann man wenigstens mit jQuery ein ähnliches Er(l/g)ebnis erreichen. Selbst die alten und zu alten Browsern kompatiblen Versionen kapselten ja schon das Ajax-Handling recht verwenderfreundlich. Polyfills, die das fetch() nachbilden gibt es auch, da muss man dann schauen, inwieweit die abwärtskompatibel sind.

              dedlfix.

  4. Hallo,

    wenn es in dem Unterverzeichnis keine Datei „index.html“ o.Ä. gibt, und du per .htaccess (beim Apachen) mit „Options +Indexes“ das „Dirctorylisting“ einschaltest, kannst du mit einem httpRequest den Ordner anfordern und erhältst so eine Liste aller Dateien im Ordner. So mache ich es in diesem Beispiel.

    Gruß
    Jürgen