2015-08-28 9 views
12

Wir geben ein Stück von Javascript-Tags wie <script src="http://ours.com/some.js"></script>, die Website-Besitzer auf ihre Website wie http://example.com setzen und in diesem Javascript-Tag möchten wir ein drittes dynamisch hinzufügen Partei js wie der document.write daran haben kann, aber natürlich, wenn wir es sind durch konventionelle Verfahren versuchen,So laden Sie JavaScript-Tags von Drittanbietern asynchron, die document.write

var script_tag = document.createElement('script'); 
script_tag.type = 'text/javascript'; 
script_tag.src="http://third-party.com/some.js"; 
document.getElementById('target').appendChild(script_tag); 

wir bekommen eine Warnung von Browser,

Warnung: ein Anruf zu document.write() von einem asynchron geladenen externes Skript wurde ignoriert.

Wie umgehen wir das? Denken Sie daran, wir haben keine Kontrolle über Skripte von Drittanbietern, so dass wir die Logik darin nicht ändern können. Wir suchen nach einer Lösung, die über alle Browser funktionieren kann.

+4

Siehe http://stackoverflow.com/a/19119061/689161 – gengkev

+0

Ihr Jungs sind definitiv nicht die ersten, die sich mit diesem Thema beschäftigt zu haben. Welche Skripte möchten Sie laden? Die Antwort hängt wahrscheinlich vom Skript ab und es gibt verschiedene Ansätze, die für diese spezifischen Skripte verwendet werden. – Matt

Antwort

-1

Was ist die 3rd-Party-Javascript-Datei?

Wenn es sich um Google Maps JavaScript API v3 handelt, stellen Sie sicher, dass Sie "& callback = your_init_funct" in die Skript-URL einfügen. Dann wird 'your_init_funct' aufgerufen, sobald die Kartenbibliothek geladen ist, sodass Sie mit der Anzeige der Karte beginnen können.

Eine andere Lösung wäre bezen.domwrite.js sein, die hier zur Verfügung: http://bezen.org/javascript/index.html

Demo: http://bezen.org/javascript/test/test-domwrite.html

-1

Ja, document.write von einem asynchron geladen Skript kann nicht aufgerufen werden, weil sie von abgelöst hat das Dokument, damit es nicht darauf schreiben kann.

Sie können den hier verwendeten Ansatz für die Google Maps API sehen, um dieses Problem zu umgehen. Es ist also möglich, dass einige Ihrer Drittanbieter-Skripts, die Sie nicht benannt haben, ähnliche Callback-Muster implementiert haben.

https://developers.google.com/maps/documentation/javascript/examples/map-simple?hl=EN

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Simple Map</title> 
    <meta name="viewport" content="initial-scale=1.0"> 
    <meta charset="utf-8"> 
    <style> 
     html, body { 
     height: 100%; 
     margin: 0; 
     padding: 0; 
     } 
     #map { 
     height: 100%; 
     } 
    </style> 
    </head> 
    <body> 
    <div id="map"></div> 
    <script> 

var map; 
function initMap() { 
    map = new google.maps.Map(document.getElementById('map'), { 
    center: {lat: -34.397, lng: 150.644}, 
    zoom: 8 
    }); 
} 

    </script> 
    <script src="https://maps.googleapis.com/maps/api/js?callback=initMap" 
     async defer></script> 
    </body> 
</html> 
0

Wie wäre es stattdessen das Skript des Ladens durch ein Skript Element anhängen, können Sie den Inhalt des Skript-URL mit einem Aufruf AJAX laden und dann eval() verwenden, es im globalen Bereich zu laufen ? Hier ist ein Beispiel, und ich habe es zu testen, um sicherzustellen, dass es funktioniert:

<!DOCTYPE html> 
<html> 
<head> 
<script> 

var xmlhttp; 

if (window.XMLHttpRequest) { 
    xmlhttp = new XMLHttpRequest(); 
}else{ 
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
} 

xmlhttp.onreadystatechange = function() { 
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
    window.eval(xmlhttp.responseText); //Indirect call to eval to execute in global scope (http://perfectionkills.com/global-eval-what-are-the-options/) 
    } 
} 

xmlhttp.open("GET", "https://third-party.com/test.js", false); //This is synchronous so that any document.write calls don't overwrite the entire page when they get called after the document is finished rendering. For all intents and purposes, this just loads the script like any other script, synchronously. 

xmlhttp.send(); 

</script> 
</head> 
<body> 

<div><h2>Hello World</h2></div> 

</body> 
</html> 

Und hier sind die Inhalte ich in der test.js Datei hatte:

document.write("This is a test..."); 
alert("...This is a test alert..."); 
console.log("...And a console message."); 

ich die AJAX-Request für das Skript gemacht synchron, so dass es genau so geladen würde, als wäre es ein normales eingebettetes Skript-Tag. Wenn Sie es asynchron ausführen und das Skript document.write verwendet, nachdem die Seite vollständig gerendert wurde, löscht es das DOM und schreibt dann darauf ... Ärgerlich eigentlich. Lass mich wissen, ob das für dich funktioniert. :)

0

Document.write funktioniert nicht vom asynchronen Skript, da das Dokument bereits geladen ist, wenn das Skript zu arbeiten beginnt.

Aber Sie können dies tun:

document.body.innerHTML = document.body.innerHTML + '<h1>Some HTML</h1>';

2

Das Problem mit einem Skript auf ein bereits geladenes Dokument laden (statt mit dem Browser die document.write() ignoriert) ist, dass Sie alle vorhandenen HTML löschen würden. Siehe this example, damit Sie genau verstehen können, was passiert, oder für weitere Details sehen Sie sich einen documentation page für die Methode document.write() an.

Obwohl ich weiß, dass dies nicht das ist, was Sie als Antwort erwarten, glaube ich, dass Sie kein Glück haben, da das Umschreiben des Skripts keine Option ist.

This scheint eine ähnliche Frage mit ähnlichen Antworten zu sein.

0

Eine andere Prozedur ist das Verhalten der document.write() Funktion zu ändern.
Angenommen, Sie die Haupt index.php Datei haben:

<html> 
<head> 
<meta charset="utf-8" /> 
</head> 
<body> 
Hello<br> 
<div id="target"></div> 
<script> 
document.write = function(input) { 
    document.body.innerHTML += input; 
} 
var doit = function() { 
    var script_tag = document.createElement('script'); 
    script_tag.type = 'text/javascript'; 
    script_tag.src="http://127.0.0.1:8080/testPlace/jsfile.js"; 
    document.getElementById('target').appendChild(script_tag); 
} 
</script> 
</body> 
</html> 

und die jsfile.js ist wie folgt:

document.write("OK MAN!"); 

jetzt, wenn Sie doit() in der js Browser-Konsole geben Sie diese Funktion (und das Skript auszuführen tun was Sie geschrieben haben), dann wäre das Ergebnis:

Hello 
OK MAN! 

, in dem die hTML ist wie folgt:

<html><head> 
<meta charset="utf-8"> 
</head> 
<body> 
Hello<br> 
<div id="target"><script src="http://127.0.0.1:8080/testPlace/jsfile.js" type="text/javascript"></script></div> 
<script> 
    //That Script which here I removed it to take less space in answer 
</script> 

OK MAN!</body> 
</html> 
0

Sie können durch das Abfangen Anrufe Skripteinschleusung die richtige Art und Weise unterstützen auf diese Weise document.write:

document.writeText = document.write; 

document.write = function(parameter) { 
    if (!parameter) return; 
    var scriptPattern = /<script.*?src=['|"](.*?)['|"]/; 
    if (scriptPattern.test(parameter)) { 
     var srcAttribute = scriptPattern.exec(parameter)[1]; 
     var script = document.createElement('script'); 
     script.src = srcAttribute; 
     document.head.appendChild(script); 
    } 
    else { 
     document.writeText(parameter); 
    } 
}; 

Offensichtlich kann dies ein wenig weiter nach unten kondensiert werden, aber die Variablennamen sind enthalten für Klarheit.

Source

Verwandte Themen