Aşağıdaki kod parçasının neden script öğesini DOM'ye eklemediğine dair bir fikriniz var mı?
var code = "<script></script>";
$("#someElement").append(code);
Aşağıdaki kod parçasının neden script öğesini DOM'ye eklemediğine dair bir fikriniz var mı?
var code = "<script></script>";
$("#someElement").append(code);
Yanıtlar:
Bazı tarayıcıların doğrudan yaptığınızda bazı değişikliklere saygı duymadığı (kod etiketi ile denediğiniz gibi metinden HTML oluşturduğum), ancak yerleşik komutlarla yaptığınız sorunlar gördüm işler daha iyi. Bunu dene:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
Gönderen: jQuery için JSON
$("#someElement")[0].appendChild( script );
İyi Haber:
% 100 çalışıyor.
Komut dosyası etiketinin içine bir şey eklemeniz yeterlidir alert('voila!');
. Belki de "Neden DOM'da görmedim?" Diye sormak isteyebileceğiniz doğru soru. .
Karl Swedberg, jQuery API sitesindeki ziyaretçinin yorumuna güzel bir açıklama yaptı . Ben yok , doğrudan okuyabilir tüm sözlerini tekrarlamak istiyorum orada burada (ı yorumlarla arasında gezinmek için sert orada bulunan) .
JQuery'nin tüm ekleme yöntemleri, DOM'ye yerleştirilmeden önce ve sonra öğeleri temizlemek / işlemek için domManip işlevini dahili olarak kullanır. DomManip işlevinin yaptığı şeylerden biri, eklenecek komut dosyası öğelerini dışarı çıkarmak ve bunları DOM parçasının geri kalanıyla enjekte etmek yerine "evalScript yordamı" ile çalıştırmaktır. Komut dosyalarını ayrı olarak ekler, değerlendirir ve daha sonra DOM'dan kaldırır.
JQuery'nin bunu yapmasının nedenlerinden birinin, belirli koşullar altında komut dosyaları eklerken Internet Explorer'da oluşabilecek "İzin Reddedildi" hatalarından kaçınmak olduğuna inanıyorum. Ayrıca, eklediğiniz bir kapsayıcı öğenin içindeyse ve daha sonra DOM içinde gezinirken aynı komut dosyasını (sorunlara neden olabilecek) tekrar tekrar eklemekten / değerlendirmekten kaçınır.
Bir sonraki şey, .append()
bir komut dosyası eklemek için işlevi kullanarak kötü haberlerin ne olduğunu özetleyeceğim .
Ve Kötü Haber ..
Kodunuzda hata ayıklama yapamazsınız.
Şaka yapmıyorum, debugger;
kesme noktası olarak ayarlamak istediğiniz satır arasına anahtar kelime ekleseniz bile , kaynak koddaki kesme noktasını görmeden yalnızca nesnenin çağrı yığınını elde edersiniz ( anahtar kelime yalnızca webkit tarayıcısında çalışır, diğer tüm büyük tarayıcılar bu anahtar kelimeyi atlamış gibi görünür) .
Kodunuzun ne yaptığını tam olarak anlarsanız, bunun küçük bir dezavantajı olacaktır. Ancak bunu yapmazsanız, debugger;
yalnızca (veya benim) kodunuzda neyin yanlış olduğunu bulmak için her yere bir anahtar kelime ekleyeceksiniz . Her neyse, bir alternatif var, javascript'in yerel olarak HTML DOM'yi değiştirebileceğini unutmayın.
Geçici çözüm.
HTML DOM'yi değiştirmek için javascript (jQuery değil) kullanın
Hata ayıklama yeteneğini kaybetmek istemiyorsanız, javascript yerel HTML DOM manipülasyonunu kullanabilirsiniz. Bu örneği düşünün:
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);
Orada, tıpkı eski günlerde olduğu gibi değil. Ve bellek sızıntılarını önlemek için artık başvurulmayan ve artık gerekli olmayan tüm nesneler için DOM'da veya bellekte olan şeyleri temizlemeyi unutmayın. İşleri temizlemek için bu kodu düşünebilirsiniz:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Bu geçici çözümün dezavantajı, yanlışlıkla yinelenen bir komut dosyası ekleyebilmenizdir ve bu kötüdür. Buradan .append()
, eklemeden önce bir nesne doğrulaması ekleyerek ve komut dosyasını eklendikten hemen sonra DOM'dan kaldırarak işlevi biraz taklit edebilirsiniz . Bu örneği düşünün:
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;
}
Bu şekilde, komut dosyası yinelemesinden koruyarak hata ayıklama özelliğine sahip komut dosyası ekleyebilirsiniz. Bu sadece bir prototip, olmasını istediğiniz her şey için genişletebilirsiniz. Bu yaklaşımı kullanıyorum ve bundan oldukça memnunum. Tabii ki ben .append()
bir komut dosyası eklemek için asla jQuery kullanmaz .
$.getScript
jQuery içine yerleştirilmiştir.
JQuery işlevini kullanarak bir JavaScript dosyasını dinamik olarak yüklemek mümkündürgetScript
$ .getScript ('http://www.whatever.com/shareprice/shareprice.js', işlev () { Display.sharePrice (); });
Şimdi harici komut dosyası çağrılır ve yüklenemezse nazikçe bozulur.
eval()
.
Ne demek "çalışmıyor"?
jQuery, bir SCRIPT öğesi oluşturmaya çalıştığınızı algılar ve öğenin içeriğini otomatik olarak genel bağlam içinde çalıştırır. Bana bunun işe yaramadığını mı söylüyorsun? -
$('#someElement').append('<script>alert("WORKING");</script>');
Düzenleme: jQuery, dediğim gibi, kodu çalıştıracak ve sonra SCRIPT öğesini silecek çünkü komutu çalıştırdıktan sonra DOM (örneğin Firebug içinde) SCRIPT öğesi görmüyorsanız - Ben SCRIPT öğeleri inanıyorum vücuda her zaman eklenir ... ama yine de - yerleştirme bu durumda kod yürütme üzerinde kesinlikle hiçbir etkisi yoktur.
Bu çalışıyor:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Görünüşe göre jQuery komut dosyaları ile akıllıca bir şey yapıyor, bu yüzden jQuery nesnesi yerine html öğesini eklemeniz gerekiyor.
Bu yardımcı olabilir deneyin:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
Ben aynı şeyi yapmak istiyorum ama diğer çerçeveye bir komut dosyası etiketi eklemek için!
var url = 'library.js';
var script = window.parent.frames[1].document.createElement('script' );
script.type = 'text/javascript';
script.src = url;
$('head',window.parent.frames[1].document).append(script);
<script>
...
...jQuery("<script></script>")...
...
</script>
</script>
Dize sona erdiği tüm komut, içinde bunu önlemek "</scr" + "ipt>"
yerine kullanılabilir.
"\x3cscript\x3e\x3c/script\x3e"
. XHTML'de yalnızca yorum yapılmamış bir CDATA bloğu koymanız gerekir.
</
buna izin verilmiyor. Bkz. Stackoverflow.com/questions/236073/…
ScriptUR dosyasına sourceURL eklemek bu sayfada belirtildiği gibi yardımcı oldu: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
Senaryonuz yürütülüyor, document.write
ondan kullanamazsınız . Test etmek ve kullanmaktan kaçınmak için bir uyarı kullanın document.write
. İle js dosyanızın ifadeleri document.write
yürütülmez ve işlevin geri kalanı yürütülür.
Bence en iyi çözüm bu. Google Analytics bu şekilde enjekte edilir.
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); })();
Komut Dosyası DOM Öğesi oluşturmak için jQuery'ye ihtiyacınız yoktur . Vanilya ES6 ile şu şekilde yapılabilir:
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!'))
Bir içine sarılmasına gerek yoktur Promise
, ancak bunu yaparak komut dosyası yüklendiğinde vaatleri çözmenize izin verir ve uzun süren komut dosyaları için yarış koşullarını önlemeye yardımcı olur.
Gövdeye komut dosyası ekle:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Kod eklemek istiyorsanız bunu yapmanın başka bir yolu document.createElement
yöntemi kullanmaktır, ancak .innerHTML
yerine kullanmaktır .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 );
Böyle deneyebilirim
var code = "<script></" + "script>";
$("#someElement").append(code);
Yapamamanızın tek nedeni "<script></script>"
, dize javascript içinde izin verilmiyor, çünkü DOM katmanı js ve HTML'nin ne olduğunu ayrıştıramıyor.
Komut dosyası etiketleri dahilnpm
bir HTML dizesi almanıza ve komut dosyalarını yürütürken bir kaba eklemenize izin veren bir paket yazdım
Misal:
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)
Burada bulabilirsiniz: https://www.npmjs.com/package/appendhtml
Sadece jQuery ile ayrıştırarak bir öğe oluşturun.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Çalışma örneği: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz