Masz pojęcie, dlaczego poniższy fragment kodu nie dodaje elementu skryptu do DOM?
var code = "<script></script>";
$("#someElement").append(code);
Masz pojęcie, dlaczego poniższy fragment kodu nie dodaje elementu skryptu do DOM?
var code = "<script></script>";
$("#someElement").append(code);
Odpowiedzi:
Widziałem problemy, w których niektóre przeglądarki nie szanują niektórych zmian, gdy robisz je bezpośrednio (przez co mam na myśli tworzenie kodu HTML z tekstu, tak jak próbujesz ze znacznikiem script), ale kiedy robisz to za pomocą wbudowanych poleceń wszystko idzie lepiej. Spróbuj tego:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
Od: JSON dla jQuery
$("#someElement")[0].appendChild( script );
Dobrą wiadomością jest:
To działa w 100%.
Po prostu dodaj coś do znacznika skryptu, np alert('voila!');. Właściwe pytanie, które możesz zadać, być może: „Dlaczego nie widziałem go w DOM?” .
Karl Swedberg wyjaśnił komentarz gościa na stronie API jQuery . I nie chcą powtórzyć wszystkie jego słowa można odczytać bezpośrednio tam tutaj (I trudno było poruszać się po komentarzach tam) .
Wszystkie metody wstawiania jQuery używają funkcji domManip wewnętrznie do czyszczenia / przetwarzania elementów przed i po ich wstawieniu do DOM. Jedną z rzeczy, którą robi funkcja domManip, jest wyciąganie wszelkich elementów skryptu, które mają zostać wstawione, i uruchamianie ich za pomocą „procedury evalScript” zamiast wstrzykiwania ich resztą fragmentu DOM. Wstawia skrypty osobno, ocenia je, a następnie usuwa z DOM.
Uważam, że jednym z powodów, dla których jQuery to robi, jest uniknięcie błędów „Odmowa zezwolenia”, które mogą wystąpić w Internet Explorerze podczas wstawiania skryptów w określonych okolicznościach. Pozwala to również uniknąć wielokrotnego wstawiania / oceny tego samego skryptu (co mogłoby potencjalnie powodować problemy), jeśli znajduje się w elemencie zawierającym, który wstawiasz, a następnie poruszasz się po DOM.
Następną rzeczą jest, podsumuję złe wieści, używając .append()funkcji do dodania skryptu.
A złą wiadomością jest ...
Nie możesz debugować swojego kodu.
Nie żartuję, nawet jeśli dodasz debugger;słowo kluczowe między wierszem, który chcesz ustawić jako punkt przerwania, skończysz na otrzymywaniu tylko stosu wywołań obiektu, nie widząc punktu przerwania w kodzie źródłowym (nie wspominając o tym słowo kluczowe działa tylko w przeglądarce webkit, wszystkie inne główne przeglądarki wydają się pomijać to słowo kluczowe) .
Jeśli w pełni rozumiesz, co robi Twój kod, będzie to niewielka wada. Ale jeśli tego nie zrobisz, w końcu dodasz debugger;słowo kluczowe, aby dowiedzieć się, co jest nie tak z twoim (lub moim) kodem. W każdym razie istnieje alternatywa, nie zapominaj, że javascript może natywnie manipulować HTML DOM.
Obejście
Użyj javascript (nie jQuery) do manipulowania HTML DOM
Jeśli nie chcesz utracić możliwości debugowania, możesz użyć natywnej manipulacji DOM HTML w javascript. Rozważ ten przykład:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js"; // use this for linked script
script.text = "alert('voila!');" // use this for inline script
document.body.appendChild(script);
Oto jest, tak jak za dawnych czasów, prawda? I nie zapomnij wyczyścić rzeczy w DOM lub w pamięci dla wszystkich obiektów, do których istnieje odwołanie i które nie są już potrzebne, aby zapobiec wyciekom pamięci. Możesz wziąć pod uwagę ten kod, aby wyczyścić rzeczy:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Wadą tego obejścia jest to, że możesz przypadkowo dodać duplikat skryptu i to źle. Stąd możesz nieco naśladować .append()funkcję, dodając weryfikację obiektu przed dodaniem i usuwając skrypt z DOM zaraz po jego dodaniu. Rozważ ten przykład:
function AddScript(url, object){
if (object != null){
// add script
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js";
document.body.appendChild(script);
// remove from the dom
document.body.removeChild(document.body.lastChild);
return true;
} else {
return false;
};
};
function DeleteObject(UnusedReferencedObjects) {
delete UnusedReferencedObjects;
}
W ten sposób możesz dodać skrypt z funkcją debugowania, jednocześnie bezpieczny przed duplikatem skryptu. To tylko prototyp, który możesz rozbudować o to, co chcesz. Korzystam z tego podejścia i jestem z tego całkiem zadowolony. Na pewno nigdy nie użyję jQuery, .append()aby dodać skrypt.
$.getScriptjest wbudowany w jQuery.
Możliwe jest dynamiczne ładowanie pliku JavaScript za pomocą funkcji jQuerygetScript
$ .getScript („http://www.whokolwiek.com/shareprice/shareprice.js”, function () {
Display.sharePrice ();
});
Teraz zewnętrzny skrypt zostanie wywołany, a jeśli nie będzie można go załadować, z wdziękiem się pogorszy.
eval().
Co masz na myśli mówiąc „nie działa”?
jQuery wykrywa, że próbujesz utworzyć element SCRIPT i automatycznie uruchomi zawartość tego elementu w kontekście globalnym. Mówisz mi, że to nie działa dla ciebie? -
$('#someElement').append('<script>alert("WORKING");</script>');
Edycja: Jeśli nie widzisz elementu SCRIPT w DOM (na przykład w Firebug) po uruchomieniu polecenia, ponieważ jQuery, jak powiedziałem, uruchomi kod, a następnie usunie element SCRIPT - Wierzę, że elementy SCRIPT są zawsze dołączane do treści ... ale w każdym razie - umieszczenie nie ma absolutnie żadnego wpływu na wykonanie kodu w tej sytuacji.
To działa:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Wygląda na to, że jQuery robi coś sprytnego ze skryptami, więc musisz dodać element HTML zamiast obiektu jQuery.
Spróbuj to może być pomocne:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
<script>
...
...jQuery("<script></script>")...
...
</script>
</script>Ciągu Ciąg dosłownych kończy cały scenariusz, aby uniknąć sytuacji, "</scr" + "ipt>"może być stosowany zamiast.
"\x3cscript\x3e\x3c/script\x3e". W XHTML wystarczy wstawić skomentowany blok CDATA.
</nie jest to dozwolone. Zobacz stackoverflow.com/questions/236073/…
Dodanie sourceURL w pliku skryptu pomogło, jak wspomniano na tej stronie: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-w--sourceurl/
Twój skrypt jest wykonywany, po prostu nie możesz document.writez niego korzystać. Użyj alertu, aby go przetestować i unikaj używania document.write. Instrukcje pliku js z document.writenie zostaną wykonane, a reszta funkcji zostanie wykonana.
To jest, moim zdaniem, najlepsze rozwiązanie. Google Analytics jest wstrzykiwany w ten sposób.
var (function(){
var p="https:" == document.location.protocol ? "https://" : "http://";
d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.src=p+'url-to-your-script.js';
s.parentNode.insertBefore(g,s); })();
Nie potrzebujesz jQuery, aby utworzyć element DOM skryptu . Można to zrobić za pomocą wanilii ES6 tak:
const script = "console.log('Did it work?')"
new Promise((resolve, reject) => {
(function(i,s,o,g,r,a,m){
a=s.createElement(o),m=s.getElementsByTagName(o)[0];
a.innerText=g;
a.onload=r;m.parentNode.insertBefore(a,m)}
)(window,document,'script',script, resolve())
}).then(() => console.log('Sure did!'))
Nie musi być zawinięty w Promise, ale pozwala to spełnić obietnicę, gdy skrypt zostanie załadowany, co pomoże zapobiec warunkom wyścigowym dla długo działających skryptów.
Dołącz skrypt do treści:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Innym sposobem na zrobienie tego, jeśli chcesz dołączyć kod, jest użycie document.createElementmetody, a następnie użycie .innerHTMLzamiast .src.
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.innerHTML = 'alert("Hey there... you just appended this script to the body");';
$("body").append( script );
Możesz spróbować w ten sposób
var code = "<script></" + "script>";
$("#someElement").append(code);
Jedynym powodem, dla którego nie możesz tego zrobić, "<script></script>"jest to, że ciąg znaków nie jest dozwolony w javascript, ponieważ warstwa DOM nie może przeanalizować, co to jest js, a co HTML.
Napisałem npmpakiet, który pozwala pobrać ciąg HTML, w tym znaczniki skryptu i dołączyć go do kontenera podczas wykonywania skryptów
Przykład:
import appendHtml from 'appendhtml';
const html = '<p>Hello</p><script src="some_js_file.js"></script>';
const container = document.getElementById('some-div');
await appendHtml(html, container);
// appendHtml returns a Promise, some_js_file.js is now loaded and executed (note the await)
Znajdź tutaj: https://www.npmjs.com/package/appendhtml
Wystarczy utworzyć element, analizując go za pomocą jQuery.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Przykład roboczy: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz