Supportnet Computer
Planet of Tech

Supportnet / Forum / Skripte(PHP,ASP,Perl...)

Bedingte externe Scriptdatei





Frage

Hallo. Ich benutze auf meinen Seiten Google AdSense-Werbung. Dabei soll man u.a. eine Zeile wie [code]<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>[/code] in die Seite einbauen. Ich möchte aber, dass dieses externe Script nur dann ausgeführt wird, wenn die Bedingung [code]location.protocol != "file:"[/code] erfüllt ist. Wenn man die Seite auf CD oder HD hat, soll also die Werbung nicht erscheinen. Leider habe ich keine Ahnung, wie man das machen kann und meine bisherige Suche hat auch nichts gebracht. Oder mir fehlt einfach nur die richtige Idee. Mit Konstruktionen wie [code]<script type="text/javascript"> if(location.protocol != "file:") this.src="http://pagead2.googlesyndication.com/pagead/show_ads.js"; </script>[/code] oder ähnlichen Experimenten bin ich nicht weiter gekommen. Weiß jemand eine Lösung? P.S. Auf die externe Scriptdatei habe ich natürlich keinen Zugriff. Die ist von Google.

Antwort 1 von Computerfreaki

Wenn es darum geht, um zu prüfen ob in der URL-Leiste ein "File:" könnte dir das nützlich sein:

<script type="text/javascript">
var url = location.href;
if(url.toLowerCase.indexOf('file') != -1) {
document.write('<script type=\"text/javascript\" src=\"http://pagead2.googlesyndication.com/pagead/show_ads.js\"></script>')
}
</script>

Gruß Computerfreaki

Antwort 2 von Computerfreaki

Oh sry hab Fehler gemacht :

<script type="text/javascript">
var url = location.href;
if(url.toLowerCase.indexOf('file') == -1) {
document.write('<script type=\"text/javascript\" src=\"http://pagead2.googlesyndication.com/pagead/show_ads.js\"></script>')
}
</script>

Du musst statt
!=
ein
==
machen

Antwort 3 von katy

Hallo Friedel,

das this in deinem Code hat als einzigen Bezug das window-Objekt. Da dies kein src-Attribut kennt, passiert dann auch nichts. Du könntest höchstens über eine DOM-Methode dein Script identifizieren und dann manipulieren (über eine der document.getElement/s... - Methoden). Da aber dann ja schon Inhalte zwischen <script ...> und </script> abgearbeitet wurden, bezweifle ich, dass das so zuverlässig funktioniert.

Ich würde dir daher folgendes empfehlen:


<script type="text/javascript">
function nachladen() {
if(location.protocol != "file:") { 
 var head = document.getElementsByTagName("head")[0];
 var script = document.createElement("script");
 script.type = "text/javascript";
 script.src = "http://pagead2.googlesyndication.com/pagead/show_ads.js";
 head.appendChild(script);
 }
}
window.onload = nachladen;
</script>


Diese Methode würde dann auch mit XHTML noch klappen, das die Alternative von Computerfreaki nicht unterstützt, denn document.write() gibt es da nicht mehr. Außerdem empfinde ich solches Geschreibe in den Code persönlich als äußerst unelegant.

Schönes Wochenende wünscht
katy

Antwort 4 von Friedel

Danke für die Antworten. Ich denke, der Ansatz von Computerfreaki könnte mir helfen. Ich bin nicht auf die Idee gekommen, dass es möglich sein könnte, Scriptbereiche zu verschachteln. Mal probieren, ob es geht. Sowas habe ich noch nicht gemacht, aber ich kenne auch keine Regel, die sowas verbietet. Zumindest fällt mir jetzt keine ein.

Der Ansatz von katy nützt sicher nichts, denn damit würde dieses Script in den Head eingefügt. Und da hat es nichts zu suchen und kann da natürlich auch nicht funktionieren. Das Script enthält ja keine Variablendeklarationen oder Funktionen, sondern es fügt die Google Werbebanner in die Seite ein. Und der soll natürlich nicht in den Head.

Wie kommst du darauf, dass document.write in XHTML nicht unterstützt wird? Das kann ich mir nicht vorstellen. Nur mit dem MIME-Type application/xhtml+xml kann man document.write nicht verwenden, aber das habe ich auch nicht vor. Normale Webseiten, die in Xhtml geschrieben sind, haben den MIME-Type text/html, und da gibt es afaik kein Problem mit document.write. Natürlich muss man es dann in einen Cdata-Bereich einschließen.

Antwort 5 von katy

Hallo Friedel

Zitat:
Der Ansatz von katy nützt sicher nichts, denn damit würde dieses Script in den Head eingefügt.
das ist schon etwas enttäuschend, denn ich schätzte dich schon anhand deiner Kursseiten für fit genug ein, das Script deinem Bedarf anzupassen:

<script type="text/javascript" id="bannerplatz">
function nachladen() {
if(location.protocol != "file:") { 
 var banner = document.getElementById("bannerplatz");
 var script = document.createElement("script");
 script.type = "text/javascript";
 script.src = "http://pagead2.googlesyndication.com/pagead/show_ads.js";
 banner.parentNode.insertBefore(script, banner); 
 }
}
 nachladen();
</script>


zusammengefasst: dem Script eine ID geben und mittels insertBefore dort das neue Script einfügen.

Eleganter gehts natürlich auch, indem die ID "bannerplatz" zb einem (vorher leeren) DIV gegeben wird, und dort das neue Script-Element als firstChild eingefügt wird. Dann ließe sich mein Code auch wieder dorthin packen wo er hingehört (head oder extern) und die Funktion könnte per window.onload=nachladen; gestartet werden.

Der Rest: ich gehe davon aus, dass gewisse Browser bald XHTML auch verstehen, wenn es nicht degradiert zu text/html ausgeliefert wird und arbeite deshalb bereits entsprechend. Natürlich hast du Recht, wenn du davon ausgehst deine Seiten auch künftig als Tag-Soup auszuliefern.

Schönen Sonntag
katy

Antwort 6 von Friedel

Ich habe jetzt folgendes probiert:
<!-- Google Werbung -->
<script type="text/javascript">
//if(location.protocol == "file:"){
  document.write("<div style=\"width:728px; height:90px; margin:0 auto; border: solid red 1px;\">");
  document.write("<script type=\"text\/javascript\" src=\"http:\/\/pagead2.googlesyndication.com\/pagead\/show_ads.js\">");
  document.write("<\/script>");
  document.write("<\/div>");
//};
</script>
<!-- Ende Google Werbung -->


Im FF2 und FF3 sieht alles so aus, wie es aussehen soll. Web Developer und FireBug melden keine Fehler. Aber im IE wird das Div linksbündig angezeigt und der Werbebanner ist unter dem Div statt im Div.

Dass ich die Bedingung auskommentiert habe, ist Absicht. So kann ich den Fehler natürlich leichter beheben. Ht jemand eine Idee, warum der IE das so merkwürdig darstellt bzw. wo der Fehler ist?

Antwort 7 von Computerfreaki

Hallo Friedel,
wenn du deine Seite mit dem IE 6 anschaust könnte es Probleme geben.
Entferne am besten mal den Außenabstand und schau mal ob es funktioniert.

  • Entferne am besten mal den Außenabstand und schau mal ob es funktioniert.
  • Probiers mal mit min-width und min-height statt width und height


  • Antwort 8 von Computerfreaki

    Und noch was:
    Du kannst mal probieren im Style-Bereich overflow:scroll; hinzuzufügen. Durch diese Eigenschaft müsste das Banner eigentlich immer im Kasten bleiben

    Antwort 9 von Friedel

    Oha. Das Posting von kati 07.09.2008, 08:15 hatte ich noch nicht gesehen.

    Das könnte gehen. Allerdings kann ich das nicht mit Textbausteinen einbauen. Jedenfalls nicht, wenn ich auch mehrere solcher Werbebanner ensetzen können möchte. Aber das müsste sich mit einem weiteren Script auch noch machen lassen. Vielleicht sollte ich mich aber besser mal schlafen legen. Nur verpasse ich dann sicher das Formel1-Rennen.

    Ich werde sicher auch weiterhin versuchen meine Seiten so zu machen, dass die auch im IE einwandfrei funktionieren. Obwohl das in Zukunft wohl immer schwieriger wird. Mircosoft erleichtert einem das ja nicht gerade. Interessanterweise schlagen jetzt auch Safari und Google mit ihren neuen Browsern diese Richtung ein. Man kann das nur benutzen, wenn man XP oder Vista hat, was ich mir beides definitiv nicht zulegen werde.

    Antwort 10 von Friedel

    @Computerfreaki: Der Außenabstand hat mit dem Problem nicht zu tun. Es ändert sich auch nicht, wenn ich ihn entferne. min-width und min-heigjt funktionieren im IE6 nicht. Außerdem hat auch das mit dem Problem nichts zu tun.

    @kati: Ich versuche seit einger Zeit etwas auf deiner Grundlage zu basteln, aber bisher funktioniert es im FF und im IE sehr unterschiedlich und in beiden nich wie es sein soll. Wie du auf
    Zitat:
    banner.parentNode.insertBefore(script, banner);
    kommst, ist mir nicht klar. Jedenfalls ist parentNode sicher nicht richtig. Das wäre in meinem Fall der Body. Ich denke, der Weg sollte richig sein. Mal sehen, ob ich es hin bekomme, denn das Nodeobjekt benutze ich ehr selten und es ist imho nicht gerade leicht zu handhaben.

    Antwort 11 von Friedel

    Ich komme nicht weiter. Ich ahbe keine Ahnung, warum es nicht klappt. Das Verhalten ist im IE genau wie bei der Lösung von Computerfreaki. Im FF wird mit dieser Methode der Werbebanner aber auch außerhalb des dafür vorgesehenen Div dargstellt. Ich verwene jetzt
    <script type="text/javascript">
      <!--
      var fwerbi=0;
      
      function werbungzeigen() {
        fwerbi++;
        bannerplatz = "werbung" + fwerbi;
        if(location.protocol == "file:") {
          var banner = document.getElementById(bannerplatz);
          var fwerbscript = document.createElement("img");
          fwerbscript.src = "http://www.friedels-home.de/Board/templates/subSilver/images/lang_german/post.gif";
    //      var fwerbscript = document.createElement("script");
    //      fwerbscript.type = "text/javascript";
    //      fwerbscript.src = "http://pagead2.googlesyndication.com/pagead/show_ads.js";
          banner.appendChild(fwerbscript); 
        };
      };
      //-->
    </script>
    </head>
    
    <body>
    <!-- Google Werbung -->
    <div id="werbung1" style="width:100%; height:90px; text-align:center; border: solid red 1px;">
    </div>
    <script type="text/javascript">
    <!--
    werbungzeigen();
    //-->
    </script>
    <!-- Ende Google Werbung -->
    


    So, wie es jetzt ist, wird das Bild im Div dargestellt. Wenn ich die 3 auskommentierten Zeilen aktiviere (die Doppelslashes entferne) und die beiden Zeilen darüber, die as Bild erzeugen, auskommentiere oder entferne, ist der Werbebanner nicht im Div sondern im IE unter dem Div und im FF irgendwo in der Seite, jedenfalls auch nicht im Div. Ich ahbe keine Idee, warum das so ist. Der Banner soll natürlich im Div sein.

    Antwort 12 von Computerfreaki

    Und wenn du das Banner ohne JavaScript einbindest funktioniert dann alles im IE und FF?

    Antwort 13 von Friedel

    @Computerfreaki: Wie soll das gehen? Das Banner ist ein Script.

    @kati: Ich halts nicht aus. Ich hab die Seite jetzt mal hochgeladen. http://www.friedels-home.de/htaccess/test.html. Weder im IE noch im FF erscheint das Bild. Wenn ich lokal teste, funktioniert alles. Wenn nicht mal das Bild funktioniert, brauche ich das mit dem Script nicht zu testen.

    Antwort 14 von Computerfreaki

    Mache einfach das ganze mit dem File: weg und mach es so wie du es schon immer hattest

    Antwort 15 von Friedel

    Das ist mir zu viel Arbeit. Dann muss ich bei jeder Cd, die bestellt wird, 993 Stellen in 756 Seiten ändern. Das geht nat+ürlich mit ein par Macros teilautomatisoiert, ist aber trotzdem ein Haufen (ziemlich stupide) Arbeit und recht fehleranfällig. Mit diesem Script wären es nur noch 6 Stellen in 6 Dateien. Und dafür könnte ich dann auch noch passende Scripte schreiben.

    Antwort 16 von versteh_nix

    wieso steht im quelltext plötzlich
    location.protocol == "file:"
    statt
    location.protocol != "file:"
    ???

    Antwort 17 von katy

    Hi Friedel,

    Zitat:
    Wie du auf banner.parentNode.insertBefore(script, banner);
    kommst, ist mir nicht klar. Jedenfalls ist parentNode sicher nicht richtig.

    nun, wenn es dir nicht jklar ist, wie kannst du dann behaupten es wäre nicht richtig?

    Wenn banner.parentNode bei dir der body ist, dann liegt das Script eben direkt im body. Dann wird das neue Script bei dir eben in den body gehängt und zwar unmittelbar vor das Script, das das macht. Wäre das Script in irgendeinem DIV, dann beträfe banner.parentNode dieses DIV. Das elegante daran ist ja, das nur das Script eine ID braucht und dann irgendwo in der Seite stehen kann.

    katy

    Antwort 18 von katy

    Hi Friedel,

    die antwort auf dein Problem in Antwort 13 wurde dir in Antwort 16 gegeben. Du hast die if-Abfrage drin gelassen mit umgekehrtem Inhalt. Das kann nur noch lokal funktionieren. Sowie ich die Seite bei mir auf dem rechner speichere und dann öffne funktioniert das problemlos, nur auf deinem Webspace nicht, denn dort ist das Protokoll ja auch nicht "file:".

    Ich würde dir übrigens raten bei der Arbeit mit variablen IDs doch immer erst die Existenz der Elemente zu prüfen:

          var banner = document.getElementById(bannerplatz);
          if (banner) {
            ... restliche Anweisungen ...
          }
    


    Das erspart so manche Abstürze ;-)

    katy (mit y, eigentlich sogar mit ÿ)

    Antwort 19 von Friedel

    @katy: Ach so. Du hast das Script in das Div gemacht. Ich ahbe das Script nach dem Div gemacht. Im Div darf es auch nicht sein, denn mit getElementById kann man auf das Element erst zugreifen, wenn es ganz geladen ist. Das Script darf als erst nach </div> kommen, wenn man damit auf das Div zugreifen will.

    @versteh_nix: Danke. Manchmal macht man so blöde Fehler, dass man sie nicht findet. Ich hatte != zu == geändert, damit ich lokal testen kann. Dann habe ich vergessen, die Änderung rückgängig zu machen, bevor ich das gaze hochgeladen habe und bevor ich den Quellcode hier gepostet habe. Ich ahbe den Fehler jetzt korrigiert und das Bild wird jetzt ach online angezeigt.

    Jetzt bin ich also wieder so weit, wie ich vor dem Hochladen war. Unter http://www.friedels-home.de/htaccess/test.html ist jetzt die Datei mit dem Bild statt Banner. So soll es sein. In http://www.friedels-home.de/htaccess/test2.html ist das Banner eingebaut. Ich ahbe keine Erklärung dafür, warum das Banner nicht im Div dargestellt wird. Im IE wird es unter dem Div dargestellt, im FF bricht das Script ab!

    Antwort 20 von Friedel

    Unsere Postings ahben sich mal wieder überschnitten. Ich hätte vielleicht do speichern sollen, bevor ich die Kinder wecke. Aber ich war ja noch nicht fertig.

    Mit deinem Hinweis, dass ich die Existenz der Elemente prüfen soll, hast du natürlich recht. Aber ich teste ja noch. In der Endfassung soll dann eh das Script immer 3 mal gestartet werden, dann wird geprüft, ob es den betreffenden Bannerplatz gibt. Maximal 3 mal darf man solche Banner auf jeder Seite einsetzen. Vielleicht erzeuge ich die Ids er Bannerplätze auch dynamisch und zähle mit. darüber habe ich mir noch keine Gedanken gemacht.

    Jedenfalls ist mir nicht klar, warum das Bild im Div ist und der Banner nicht.

    Antwort 21 von katy

    Hi Friedel
    Zitat:
    Das Script darf als erst nach </div> kommen, wenn man damit auf das Div zugreifen will.

    Hast du das getestet?
    Falls ja, böte sich ein Aufruf zB per window.onload an:

    <script type="text/javascript" id="bannerplatz">
    var altesonload = window.onload;
    window.onload = function() {
     if (typeof(altesonload) == "function")) {
      altesonload();
      altesonload = null;
     }
     if(location.protocol != "file:") { 
      var banner = document.getElementById("bannerplatz");
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "http://pagead2.googlesyndication.com/pagead/show_ads.js";
      banner.parentNode.insertBefore(script, banner); 
     }
    }
    </script>


    Ich hab hier die Funktion gleich anonymisiert und einen Mechanismus um Probleme mit mehreren onload-Funktionen zu steuern eingebaut, so dass der Script-Block mit jeweils geänderter ID eigentlich mehrfach vorkommen darf.
    Ist natürlich ungetestet. Falls es doch Probleme mit dem Namespace geben sollte, würde ich alles in ein Objekt kapseln.

    katy

    Antwort 22 von Friedel

    Ich habe keine Ahnung, wozu das gut ist. Inwiefern könnte es das Problem lösen? Wozu wird altesonload gebraucht? Und was soll ist der Funktion altesonload() stehen? Ich habe immer noch keine Idee, woran es leigen könnte, dass die Werbung nicht im Div erscheint. Vielleicht liegt es daran, dass ich deinen Gedanken nicht folgen kann.

    Eine Zeile wie
    Zitat:
    window.onload = function() {
    habe ich noch nie gesehen. Ist das eine Funktion ohne Namen? Geht das? Was ist der Vorteil gegenüber der üblichen Schreibweise? Und was spricht dagegen, einfach den Funktionsausruf hinter das Div zu setzen, wie ich es gemacht habe?

    Antwort 23 von katy

    Hi Friedel,

    es war ein Vorschlag. Was du machst ist dein Ding. Ich würde es überhaupt nicht so machen, weil ich JavaScript direkt im HTML nicht besonders mag.

    Wenn du die verwendete Syntax nicht verstehst, kann ich es dir gerne erläutern, falls es dich wirklich interessiert. Falls du aber nur deinen Unglauben zum Ausdruck bringen möchtest mit derlei Fragen und Äußerungen wie "noch nie gesehen", dann erspare ich mir lieber die Mühe auf derlei fruchtlosem Boden zu sähen. Also denke hierüber bitte genau nach und teile deine Entscheidung mit.

    katy

    Antwort 24 von Friedel

    Ich verstehe die Syntax nicht. Kann man sowas irgendwo nachlesen? In den Quellen, aus denen ich JavaScript gelernt habe und wo ich bei Bedarf nachschlage, steht sowas nicht.

    Aber unabhängig davon verstehe ich auch nicht, warum in meiner Beispielseite die Werbung nicht im Div ist. Irgendwo muss ja ein Fehler sein, aber ich finde keine. Dass die Debugger und anderen Analysetools, die ich bei sowas manchmal verwende, nichts finden, hat nichts zu bedeuten. Die taugen imho nichts.

    Antwort 25 von katy

    Guten Morgen,

    in Kürze ein paar Lesetipps:
    Barrierefreies JavaScript
    Galileo Computing JavaScript

    und vieles aus den Tipps im SelfHTML-Forum

    katy

    Antwort 26 von katy

    Guten Morgen

    altesonload
    nimmt eventuell schon gesetzte Event-Handler auf. Es könnte ja sein, dass window.onload schon mal gesetzt wurde und ein einfaches Überschreiben unerwünscht ist.

    window.onload = function() {}
    hier wird window.onload eine anonyme Funktion zugewiesen. Wenn die Funktion nur einmal (in einem event-Handler) genutzt wird ist das für mich übersichtlicher.

    Geht das?
    Deine Rückfragen sind mit derlei Skepsis gewürzt, dass ich mich immer noch frage, ob du wirklich etwas wissen willst, oder einfach nur meine Kompetenz anzweifeln möchtest.

    katy

    Antwort 27 von Friedel

    Sorry, aber ich habe nicht die Zeit und auch keine Lust tagelang zu versichern, dass ich das wissen will. In meinen Büchern und in den Websites, wo ich danach gesucht habe, habe ich nichts dazu gefunden. Wenn du es mir nicht erklären willst und mir auch keinen Link gibst, wo ich es nachlesen kann, werde ich es leider wohl nicht lernen können. Schade. Jedenfalls habe ich mit "anonyme Funktion" mal einen brauchbaren Suchbegriff. Vielleicht finde ich ja was, was mich weiter bringt. Wenn ich deine Kompetenz anzweifeln wollte, würde ich das einfach machen. Es hindert mich ja nichts daran. Dass ich es nicht mache, zeigt eigentlich schon, dass ich es nicht will. Dein Sicherer Umgang mit DOM zeigt ja, dass du dich in der Materie auskennst. Ich muss meine DOM-Sachen immer ausgiebig testen und korrigieren, weil ich das selten benutze und die Syntax besonders beim Node-Objekt sehr verwirrend finde.

    Vielen Dank für deine bisherige Hlfe.

    Antwort 28 von katy

    vielleicht hilft dir dies:
    Geheimnisse der JavaScript-Syntax

    Ein richtig gutes aktuelles JavaScript-Kompendium gibt's meines Wissen nicht deutschsprachig im Netz. das JavaScript-Kapitel in SelfHTML ist leider völlig veraltet und außer Versprechungen ist seitens der SelfHTML-Aktivisten keine Änderung in Sicht.

    Übrigens wird dein Bild bei mir im FF und Opera im DIV dargestellt, die google-Werbung lädt unendlich. FF mag's lieber wenn die Funktion über window.onload aufgerufen wird, der direkte Aufruf im HTML nach dem DIV wird ebenfalls mit unendlichem Laden quittiert.

    katy

    Antwort 29 von Friedel

    Hallo.
    Ich hatte einen kleinen Unfall und deshalb ein paar Tage keine Gelegenheit um zu antworten. Der von dir verlinkte Artikel ist imho sehr gut und er enthält einges, was ich bisher nicht wusste. Vor allem enthält es aber auch ein paar liks, die sehr gut sind. Da werde ich eine Weile brauchen, bis ich das alles gelesen und kapiert habe.

    Zitat:
    Übrigens wird dein Bild bei mir im FF und Opera im DIV dargestellt, die google-Werbung lädt unendlich. FF mag's lieber wenn die Funktion über window.onload aufgerufen wird, der direkte Aufruf im HTML nach dem DIV wird ebenfalls mit unendlichem Laden quittiert.
    Stimmt ungefähr so habe ich das auch beschrieben (09.09.2008, 07:19). Mir ist immer noch nicht klar, warum das so ist. Ich habe das Bild genau so eingebaut, wie das Bannerscript. Aber das kannst du am Quellcode ja selbst sehen. Deshalb verstehe ich ja auch nicht, warum die beiden Seiten so unterschiedlich ausfallen.

    Antwort 30 von Friedel

    Zitat:
    ...stellen die Functions Expressions dar. Dies ist eine Spezialität von JavaScript, die viele elegante, aber auch unverständliche Schreibweisen erlaubt.
    Schön formuliert. *ggg*.