Любая идея, почему фрагмент кода ниже не добавляет элемент сценария в DOM?
var code = "<script></script>";
$("#someElement").append(code);
Любая идея, почему фрагмент кода ниже не добавляет элемент сценария в DOM?
var code = "<script></script>";
$("#someElement").append(code);
Ответы:
Я видел проблемы, когда некоторые браузеры не учитывают некоторые изменения, когда вы делаете их напрямую (я имею в виду создание HTML из текста, как вы пытаетесь с помощью тега script), но когда вы делаете их с помощью встроенных команд дела идут лучше. Попробуй это:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
От: JSON для jQuery
$("#someElement")[0].appendChild( script );
Хорошая новость:
Это на 100% работает.
Просто добавьте что-нибудь внутри тега script, например alert('voila!');. Правильный вопрос, который вы, возможно, захотите задать, возможно, «Почему я не видел его в DOM?» ,
Карл Сведберг сделал приятное объяснение комментарию посетителя на сайте jQuery API . Я не хочу повторять все его слова, вы можете прочитать прямо здесь, здесь (мне было трудно ориентироваться в комментариях там) .
Все методы вставки jQuery используют функцию domManip для очистки / обработки элементов до и после их вставки в DOM. Одна из функций, которую выполняет функция domManip, - это извлекать любые элементы сценария, которые собираются вставить, и запускать их через «подпрограмму evalScript», а не вставлять их с остальным фрагментом DOM. Он вставляет сценарии отдельно, оценивает их, а затем удаляет их из DOM.
Я считаю, что одной из причин, по которой jQuery делает это, является предотвращение ошибок «Permission Denied», которые могут возникать в Internet Explorer при вставке сценариев при определенных обстоятельствах. Это также позволяет избежать повторной вставки / оценки одного и того же сценария (который потенциально может вызвать проблемы), если он находится внутри содержащего элемента, который вставляется, а затем перемещается по DOM.
Следующее, я подведу итог плохих новостей, используя .append()функцию для добавления скрипта.
И плохие новости это ..
Вы не можете отлаживать свой код.
Я не шучу, даже если вы добавите debugger;ключевое слово между строкой, которую вы хотите установить в качестве точки останова, вы в конечном итоге получите только стек вызовов объекта, не увидев точку останова в исходном коде (не говоря уже о том, что это ключевое слово работает только в браузере webkit, во всех других основных браузерах это ключевое слово отсутствует) .
Если вы полностью понимаете, что делает ваш код, то это будет незначительным недостатком. Но если вы этого не сделаете, вы в конечном итоге добавите debugger;ключевое слово повсеместно, просто чтобы выяснить, что не так с вашим (или моим) кодом. В любом случае, есть альтернатива, не забывайте, что javascript может манипулировать HTML DOM.
Обходной путь.
Используйте JavaScript (не JQuery) для управления HTML DOM
Если вы не хотите терять возможность отладки, тогда вы можете использовать нативную манипуляцию HTML DOM на JavaScript. Рассмотрим этот пример:
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);
Вот оно, как в старые добрые времена, не так ли? И не забывайте очищать вещи в DOM или в памяти для всех объектов, на которые ссылаются и которые больше не нужны, чтобы предотвратить утечки памяти. Вы можете рассмотреть этот код, чтобы очистить вещи:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
Недостаток этого обходного пути заключается в том, что вы можете случайно добавить дубликат сценария, и это плохо. Отсюда вы можете слегка имитировать .append()функцию, добавив проверку объекта перед добавлением и удалив сценарий из DOM сразу после его добавления. Рассмотрим этот пример:
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;
}
Таким образом, вы можете добавить скрипт с возможностью отладки, в то же время не допуская дублирования скриптов. Это всего лишь прототип, вы можете расширить его так, как хотите. Я использовал этот подход и вполне доволен этим. Конечно же, я никогда не буду использовать jQuery .append()для добавления скрипта.
$.getScriptвстроен в JQuery.
Можно динамически загрузить файл JavaScript с помощью функции jQuerygetScript
$ .getScript ('http://www.whwhat.com/shareprice/shareprice.js', function () {
Display.sharePrice ();
});
Теперь будет вызываться внешний скрипт, и если он не может быть загружен, он будет постепенно ухудшаться.
eval().
Что значит "не работает"?
jQuery обнаруживает, что вы пытаетесь создать элемент SCRIPT, и автоматически запускает содержимое элемента в глобальном контексте. Вы говорите мне, что это не работает для вас? -
$('#someElement').append('<script>alert("WORKING");</script>');
Изменить: Если вы не видите элемент SCRIPT в DOM (например, в Firebug) после запуска команды, потому что jQuery, как я уже сказал, запустит код и затем удалит элемент SCRIPT - я считаю, что элементы SCRIPT всегда добавляются к телу ... но в любом случае - размещение не имеет абсолютно никакого отношения к выполнению кода в этой ситуации.
Это работает:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Кажется, что jQuery делает что-то умное со скриптами, поэтому вам нужно добавить элемент html, а не объект jQuery.
Попробуйте это может быть полезно:
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>В строковых литералов Завершает весь сценарий, чтобы избежать этого , "</scr" + "ipt>"можно использовать вместо.
"\x3cscript\x3e\x3c/script\x3e". В XHTML вам нужно только вставить закомментированный блок CDATA.
</, это не разрешено. См. Stackoverflow.com/questions/236073/…
Добавление sourceURL в файл сценария помогло, как упоминалось на этой странице: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
Ваш скрипт выполняется, вы просто не можете использовать document.writeего. Используйте предупреждение, чтобы проверить его и избегать использования document.write. Операторы вашего js-файла с document.writeне будут выполнены, а остальные функции будут выполнены.
Это то, что я считаю лучшим решением. Google Analytics вводится таким образом.
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); })();
Вам не нужен jQuery для создания DOM-элемента Script . Это можно сделать с помощью vanilla ES6 примерно так:
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!'))
Его не нужно переносить в a Promise, но это позволяет разрешить обещание при загрузке сценария, что помогает предотвратить состояние гонки для долго выполняющихся сценариев.
Добавить скрипт в тело:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Другой способ сделать это, если вы хотите добавить код, - использовать document.createElementметод, но затем использовать .innerHTMLвместо .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 );
Можно попробовать вот так
var code = "<script></" + "script>";
$("#someElement").append(code);
Единственная причина, по которой вы не можете этого сделать, "<script></script>"заключается в том, что строка не разрешена внутри javascript, потому что слой DOM не может анализировать, что такое js и что такое HTML.
Я написал npmпакет, который позволяет вам взять строку HTML, включая теги сценария, и добавить ее в контейнер при выполнении сценариев.
Пример:
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)
Найдите его здесь: https://www.npmjs.com/package/appendhtml
Просто создайте элемент, проанализировав его с помощью jQuery.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Рабочий пример: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz