2015-08-28 15 views
12

Dajemy kawałek tagów javascript, takich jak <script src="http://ours.com/some.js"></script>, które właściciele witryn umieszczają na swojej stronie, takich jak http://example.com iw tym tagu javascript chcemy dynamicznie zawierać trzeci strona js takich jak, które mogą mieć document.write w nim, ale oczywiście, jeśli staramy się uwzględnić go metodą konwencjonalną,Jak ładować asynchronicznie tag strony trzeciej, który ma 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); 

otrzymamy ostrzeżenie od przeglądarki,

Warning: wezwanie do document.write() z asynchronicznie załadowanego zewnętrzny skrypt został zignorowany.

Jak sobie z tym poradzimy? Pamiętaj, że nie mamy kontroli nad skryptami stron trzecich, więc nie możemy zmienić logiki. Szukamy rozwiązania, które może działać we wszystkich przeglądarkach.

+4

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

+0

Wy na pewno nie są pierwszymi ludźmi, którzy zajmowali się tym zagadnieniem. Które skrypty próbujesz wczytać? Odpowiedź będzie prawdopodobnie zależeć od skryptu i mogą być różne podejścia do tych konkretnych skryptów. – Matt

Odpowiedz

-1

Co to jest plik javascript innej firmy?

Jeśli to Google Maps JavaScript API v3, upewnij się, że w adresie URL skryptu znajduje się "& callback = your_init_funct". Następnie wywoła funkcję "your_init_funct" po załadowaniu biblioteki map, dzięki czemu możesz zacząć wyświetlać mapę.

Innym rozwiązaniem byłoby bezen.domwrite.js który jest dostępny tutaj: http://bezen.org/javascript/index.html

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

-1

Tak, document.write nie można nazwać z asynchronicznie załadowanego skryptu, ponieważ jest oderwana od dokument, więc nie może do niego pisać.

Możesz zobaczyć podejście stosowane tutaj dla api mapy google, aby ominąć ten problem. Jest więc możliwe, że niektóre ze skryptów innych firm, których nie nazwiesz, mogą mieć zaimplementowany podobny wzór wywołania zwrotnego.

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

Jak o zamiast wczytywania skryptu poprzez dołączenie elementu skryptu załadować zawartości URL skryptu z AJAX, a następnie użyć funkcji eval(), aby uruchomić go w zasięgu globalnym ? Oto przykład i ja go przetestować, aby sprawdzić, czy działa:

<!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> 

A oto zawartości miałem w pliku test.js:

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

zrobiłem żądania AJAX dla skryptu synchroniczny, aby był ładowany dokładnie tak, jakby był zwykłym osadzonym znacznikiem skryptu. Jeśli uruchomisz go asynchronicznie, a skrypt użyje document.write po pełnym wyrenderowaniu strony, wyczyści DOM, a następnie zapisze do niego ... Trochę irytujące w rzeczywistości. Lemme, wiedz, że to działa dla ciebie. :)

0

Document.write nie będzie działał ze skryptu asynchronicznego, ponieważ dokument jest już załadowany po uruchomieniu skryptu.

Ale można to zrobić:

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

2

Problem z załadowaniem skryptu na już załadowanego dokumentu (zamiast przeglądarka ignoruje document.write()) jest to, że chcesz usunąć całą istniejącą HTML. Zobacz: this example, aby dokładnie zrozumieć, co się dzieje lub aby uzyskać więcej informacji na temat metody document.write() dla metody documentation page.

Chociaż wiem, że może nie być to, co spodziewasz się uzyskać jako odpowiedź, uważam, że masz pecha, ponieważ przepisanie skryptu nie wchodzi w grę.

This wydaje się być podobnym pytaniem o podobnych odpowiedziach.

0

Inna procedura polega na zmianie zachowania funkcji document.write().
Załóżmy masz główną index.php plik:

<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> 

i jsfile.js jest tak:

document.write("OK MAN!"); 

teraz po wpisaniu doit() w konsoli przeglądarki js do realizacji tej funkcji (i skrypt zrobić co napisałeś), wtedy wynik byłby następujący:

Hello 
OK MAN! 

W którym znajduje się html:

<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

Można wspornik wtrysku skrypt poprawny sposób, przechwytując wywołania document.write w ten sposób:

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); 
    } 
}; 

Oczywiście można kondensować w dół trochę dalej, ale nazwy zmiennych są włączone do przejrzystość.

Source

Powiązane problemy