Linuchs: Javascript-Datei laden und aktivieren

Guten Morgen,

ich möchte eine Google Maps Karte nur anzeigen, wenn der Leser auf eine Aktivierungs-Schaltfläche klickt. Die Schaltfläche wird mit Javascript eingeblendet. Macht Sinn, denn bei ausgeschaltetem Javascript kann die Karte eh nicht gezeigt werden.

Nun ist aber zum Zeigen eine Javascript-Datei von Google nötig, die ich auch erst nach der Aktivierung laden möchte:

document.write("<script src=\"https://maps.googleapis.com/maps/api/js?sensor=false\"><\/script>");

Doch laden heisst nicht, dass sie auch funktioniert. Ich erinnere mich, dass dazu noch ein Zauberwort nötig ist, finde das aber trotz Recherche nicht.

Linuchs

  1. Hallo Linuchs,

    ich möchte eine Google Maps Karte nur anzeigen, wenn der Leser auf eine Aktivierungs-Schaltfläche klickt. Die Schaltfläche wird mit Javascript eingeblendet. Macht Sinn, denn bei ausgeschaltetem Javascript kann die Karte eh nicht gezeigt werden.

    ich verstehe ein Problem nicht. Um eine GM-Karte zu zeigen, musst du

    1. Die GM-API einbinden

    2. Mit ein paar Befehlen aus der API die Karte anlegen, die Optionen setzen und die Karte dann anzeigen.

    1. machst du onload, 2. onclick.

    Gruß, Jürgen

    1. Om nah hoo pez nyeetz, JürgenB!

      ich verstehe ein Problem nicht. Um eine GM-Karte zu zeigen, musst du

      1. Die GM-API einbinden

      2. Mit ein paar Befehlen aus der API die Karte anlegen, die Optionen setzen und die Karte dann anzeigen.

      3. machst du onload, 2. onclick.

      Für statische Karten gehts auch ohne.

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Kran und Krankenschwester.

  2. Sorry, ich fasse mich kürzer:

    In eine bereits geladene HTML-Seite möchte ich eine Javascript-Datei einfügen (vom Server laden) und ausführen. Wie geht das?

    Linuchs

    1. Sorry, ich fasse mich kürzer:

      In eine bereits geladene HTML-Seite möchte ich eine Javascript-Datei einfügen (vom Server laden) und ausführen. Wie geht das?

      Molily/Forum

    2. Lieber Linuchs,

      In eine bereits geladene HTML-Seite möchte ich eine Javascript-Datei einfügen (vom Server laden) und ausführen. Wie geht das?

      function load_script (url) {  
          // new <script>-Element  
          var s = document.createElement("script");  
        
          // add parameters: <script type="text/javascript" src="url">  
          s.type = "text/javascript";  
          s.src = url;  
        
          // insert element into <head>  
          document.getElementsByTagName("head")[0].appendChild(s);  
      }
      

      In Deiner nachgeladenen JS-Datei muss dann in etwa soetwas stehen:

      function mach_mir_eine_google_map () {  
          // Code hier  
      }  
        
      mach_mir_eine_google_map();
      

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Hallo Felix,

        mit der Google-Maps-API geht das aber nicht so einfach, da Google weitere Scripte asynchron nachläd. Hier muss die dafür vorgesehene Callback-Funktion verwendet werden.

        Gruß, Jürgen

        1. Lieber JürgenB,

          mit der Google-Maps-API geht das aber nicht so einfach,

          da hast Du absolut Recht. Jedoch bin ich in meiner Antwort auf ein ganz spezielles (Teil-)Problem eingegangen, nicht aber auf das Thema Google-Maps oder seine API.

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Hallo Felix,

            ich wollte auch nur Linuchs darauf aufmerksam machen.

            Gruß, Jürgen

            1. Hallo Jürgen,

              ich wollte auch nur Linuchs darauf aufmerksam machen.

              Ich bin sehr aufmerksam. Die von moloily vorgeschlagene Korrektur führt nicht zum Erfolg.

              Offenbar wird die Javascript-Datei jetzt geladen und auch abgewartet, bis sie komplett da ist. Doch dann wird in die Init- Funktion gesprungen, obwohl in der eben geladenen JS-Datei noch eine weitere JS-Datei angefordert wird.

              Eine Fehlermeldung weist daruf hin:

              "[10.10.2013 19:50:42] JavaScript - http://remso.eu/?LO=kompakt&KM=100&ORT=11593&lg=de
              Event thread: load
              Uncaught exception: TypeError: Cannot convert 'google.maps.MapTypeId' to object
              Error thrown at line 21, column 2 in google_init() in http://remso.eu/?LO=kompakt&KM=100&ORT=11593&lg=de:
                  var mapOptions = {"

              Ich vermute, dass hier ROADMAP noch nicht bekannt ist:

              function google_init() {  
                var mapOptions = {  
                 zoom:      8  
                ,mapTypeId: google.maps.MapTypeId.ROADMAP  
                ,center:    new google.maps.LatLng(47.7974,9.16384)  
                };  
              
              

              Ich müsste also nicht nur auf die von mir geladene JS-Datei warten, sondern auch auf die darin geladene JS-CHILD-Datei - oder zumindest eine kleine Pause einlegen. Habe ich gemacht mit alert(). Fehler bleibt.

              Kann es sein, dass die gerade geladene JS-Datei nicht wirklich eine weitere JS-Dartei laden kann?

              Hier mal der Link zur Seite: http://remso.eu/?LO=kompakt&KM=100&ORT=11593&lg=de

              Linuchs

              1. Hallo Linuchs,

                einfache Lösung: GM-API normal mit <script src=... einbinden.

                Wenn es unbedingt dynamich sein soll, hier ein Auszug aus meinem GPX-Viewer:

                  
                JB.LoadScript = function(url,callback) {  
                	var scr = document.createElement('script');  
                	scr.type = "text/javascript";  
                	scr.async = "async";  
                	if(typeof(callback)=="function") {  
                		scr.onloadDone = false;  
                		scr.onload = function() {  
                			if ( !scr.onloadDone ) {  
                				scr.onloadDone = true;  
                				JB.Debug_Info(url,"loaded",false);  
                				callback();  
                			}  
                		};  
                		scr.onreadystatechange = function() {  
                			if ( ( "loaded" === scr.readyState || "complete" === scr.readyState ) && !scr.onloadDone ) {  
                				scr.onloadDone = true;  
                				JB.Debug_Info(url,"ready",false);  
                				callback();  
                			}  
                		}  
                	}  
                	scr.onerror = function() {  
                		JB.Debug_Info(url,"Konnte nicht geladen werden.",false);  
                	}  
                	scr.src = url;  
                	document.getElementsByTagName('head')[0].appendChild(scr);  
                } // LoadScript  
                  
                JB.gmcb = function() {  
                	JB.Scripte.googlemaps = 2;  
                } // gmcb  
                  
                  
                	JB.LoadScript("http://maps.google.com/maps/api/js?sensor=false&callback=JB.gmcb", function() {});  
                
                

                JB.gmcb wird aufgerufen, wenn die API vollständig geladen ist. Die Callbackfunktion meines JS-Loaders wird hier nicht benötigt, daher leere Funktion.

                Gruß, Jürgen

          2. mit der Google-Maps-API geht das aber nicht so einfach,

            da hast Du absolut Recht.

            Das verstehe ich nicht. Warum soll das nicht gehen? Wenn ich ein Script, welches asynchron Scripte lädt, selbst asynchron lade macht das doch keinen unterschied?

            1. Hallo unknown,

              mit der Google-Maps-API geht das aber nicht so einfach,

              da hast Du absolut Recht.

              Das verstehe ich nicht. Warum soll das nicht gehen? Wenn ich ein Script, welches asynchron Scripte lädt, selbst asynchron lade macht das doch keinen unterschied?

              das onload-Event des Script-Elements feuert, wenn das Script geladen ist. Von diesem Script nachgeladene weitere Scripte werden nicht berücksichtigt.

              Gruß, Jürgen

              1. Hallo unknown,

                mit der Google-Maps-API geht das aber nicht so einfach,

                da hast Du absolut Recht.

                Das verstehe ich nicht. Warum soll das nicht gehen? Wenn ich ein Script, welches asynchron Scripte lädt, selbst asynchron lade macht das doch keinen unterschied?

                das onload-Event des Script-Elements feuert, wenn das Script geladen ist. Von diesem Script nachgeladene weitere Scripte werden nicht berücksichtigt.

                das würde aber bedeuten, es werden keine scripte asynchron nachgeladen, sondern synchron über document.write was dann das eigentliche problem ist, weil es das document neu öffnet?

                1. Hallo unknown,

                  mit der Google-Maps-API geht das aber nicht so einfach,

                  da hast Du absolut Recht.

                  Das verstehe ich nicht. Warum soll das nicht gehen? Wenn ich ein Script, welches asynchron Scripte lädt, selbst asynchron lade macht das doch keinen unterschied?

                  das onload-Event des Script-Elements feuert, wenn das Script geladen ist. Von diesem Script nachgeladene weitere Scripte werden nicht berücksichtigt.

                  das würde aber bedeuten, es werden keine scripte asynchron nachgeladen, sondern synchron über document.write was dann das eigentliche problem ist, weil es das document neu öffnet?

                  Nein. Jedes nachgeladene Script feuert den Onload, wenn es fertig geladen ist, unabhängig davon, ob die von ihm angestoßenen asynchronen Prozesse, z.B. das Nachladen weiterer Scripte, schon fertig sind. Asynchrone Programmierung hat viele Fallen, Google hat das Problem mit dem Callback-Parameter gelöst.

                  Gruß, Jürgen

                  1. Nein. Jedes nachgeladene Script feuert den Onload, wenn es fertig geladen ist, unabhängig davon, ob die von ihm angestoßenen asynchronen Prozesse, z.B. das Nachladen weiterer Scripte, schon fertig sind.

                    Ja, aber entweder habe ich das Problem generell, ich weiß nach Einbinden des "Haupt"-Scriptes nicht, wann sind alle dynamisch nachgeladenen Scripte geladen und ich kann mit meinem Code darauf zugreifen, oder ich muss das sowieso schon beachten und somit Callbacks angeben.
                    Wenn ich dann allerdings das "Haupt"-Script asynchron lade und in dessen Callback (Haupt"-Script-geladen) meine Callbacks der wiederum durch das "Haupt"-Script asynchron geladenen Scripte registriere (also der code der vorher direkt nach dem "Haupt"-Script folgte einfach ins Callback des "Haupt"-Scriptes verschoben) sollte das genau so funktionieren wie vorher, nur asynchron verzögert.
                    Dann stößt man das asynchrone Nachladen der Scripte also selbst an, da fällt mir aber kein Grund ein, warum ich das nicht wieder in einem asynchronen Aufruf(Callback) selbst machen könnte.

      2. Lieber Felix,

        danke für dein Beispiel. In der Zwischenzeit habe ich über Linksetzer dieses gefunden, ganz ähnlich:

        function google_start() {  
        }  
        function google_init() {  
          // Google JS laden  
          var appendTo = document.head || document.getElementsByTagName('head');  
          function require(scriptSrc, fn) {  
            var script = document.createElement('script');  
            script.type = 'text/javascript';  
            script.src = scriptSrc;  
            script.onload = fn;  
            appendTo.insertBefore(script, appendTo.firstChild);  
          }  
          require("https://maps.googleapis.com/maps/api/js?sensor=false", google_start() );  
        
        

        Das Einbinden, das du ja auch beschreibst (allerdings ohne Abfrage, ob geladen), ist wohl nicht das Problem. Aber wie wird das eingebundenen Script ausgeführt?

        Es ist ja keine Funktion.

        Linuchs

        1. Hallo,

          function google_start() {

          }
          function google_init() {
            // Google JS laden
            var appendTo = document.head || document.getElementsByTagName('head');
            function require(scriptSrc, fn) {
              var script = document.createElement('script');
              script.type = 'text/javascript';
              script.src = scriptSrc;
              script.onload = fn;
              appendTo.insertBefore(script, appendTo.firstChild);
            }
            require("https://maps.googleapis.com/maps/api/js?sensor=false", google_start() );

            
          Es sollte `require("…", google_start)`{:.language-javascript} heißen, nicht `require("…", google_start())`{:.language-javascript}! Sonst wird die Funktion sofort ausgeführt, anstatt wenn das Script geladen ist.  
            
          
          > Das Einbinden, das du ja auch beschreibst (allerdings ohne Abfrage, ob geladen), ist wohl nicht das Problem. Aber wie wird das [eingebundenen Script](https://maps.googleapis.com/maps/api/js?sensor=false) ausgeführt?  
            
          Das macht der Browser automatisch, wenn ein script-Element ins DOM eingehangen wird. Das Script wird herunterladen und ausgeführt.  
            
          Grüße,  
          Mathias