Не удается добавить элемент

любая идея, почему часть кода ниже не добавляет элемент сценария в DOM?

var code = "<script></script>";
$("#someElement").append(code);

18 ответов


Я видел проблемы, когда некоторые браузеры не уважают некоторые изменения, когда вы делаете их напрямую (под этим я подразумеваю создание HTML из текста, как вы пытаетесь с тегом скрипта), но когда вы делаете их со встроенными командами, все идет лучше. Попробуйте это:

var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );

From:JSON для jQuery


хорошая новость:

это 100% работает.

просто добавьте что-то внутри тега скрипта, например alert('voila!');. Правильный вопрос, который вы, возможно, захотите задать,не хотите повторить все его слова, вы можете прочитать непосредственно здесь здесь (мне было трудно перемещаться по комментариям там).

все методы вставки jQuery используют функция domManip внутри очистить / обработать элементы до и после того, как они будут вставлены в DOM. Одна из вещей domManip функции вытащить любой сценарий элементы, которые будут вставлены и запущены их через " процедуру evalScript" вместо того чтобы впрыснуть их с остальными из DOM фрагмент. Он вставляет скрипты отдельно, оценивает их, а затем удаляет их из дома.

я считаю, что одна из причин jQuery делает это, чтобы избежать " разрешения Отказано " ошибки, которые могут возникнуть в Internet Explorer при вставке сценарии при определенных обстоятельствах. Он также избегает повторно вставка / оценка одного и того же скрипта (что потенциально может вызвать проблемы), если он находится в содержащих элемент, который вы вставка и затем двигаясь вокруг дома.

следующее, я подытожу, что плохие новости, используя .append() функция добавления скрипта.


и плохая новость..

вы не можете отладить свой код.

Я не шучу, даже если добавить debugger; ключевое слово между строкой, которую вы хотите установить в качестве точки останова, вы получите только стек вызовов объекта, не видя точка останова в исходном коде,(не говоря уже о том, что это ключевое слово работает только в браузере webkit, все другие основные браузеры, похоже, опускают это ключевое слово).

если вы полностью понимаете, что делает ваш код, то это будет незначительным недостатком. Но если вы этого не сделаете, вы в конечном итоге добавите debugger; ключевое слово повсюду, чтобы узнать, что не так с вашим (или моим) кодом. Во всяком случае, есть альтернатива, не забывайте, что javascript может изначально манипулировать HTML DOM.


временное решение.

используйте javascript (не jQuery) для управления HTML DOM

если вы не хотите потерять возможность отладки, вы можете использовать javascript native HTML DOM manipulation. Рассмотрим следующий пример:

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() добавить скрипт.


можно динамически загружать файл JavaScript с помощью функции jQuery getScript

$.getScript('http://www.whatever.com/shareprice/shareprice.js', function() {
  Display.sharePrice();
});

теперь будет вызван внешний скрипт, и если он не может быть загружен, он будет изящно деградировать.


что значит "не работает"?

jQuery обнаруживает, что вы пытаетесь создать элемент сценария и автоматически запускает содержимое элемента в глобальном контексте. Ты хочешь сказать, что это не работает для тебя? -

$('#someElement').append('<script>alert("WORKING");</script>');

Edit: если вы не видите элемент сценария в DOM (например, в Firebug) после запуска команды, это потому, что jQuery, как я уже сказал, запустит код, а затем удалит элемент сценария-I поверьте, что элементы сценария всегда добавляются к телу... но в любом случае-размещение не имеет абсолютно никакого отношения к выполнению кода в этой ситуации.


это работает:

$('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 в другие рамки!

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> внутри строкового литерала завершает весь скрипт, чтобы избежать этого "</scr" + "ipt>" может использоваться вместо этого.


добавление sourceURL в файл скрипта помогло, как указано на этой странице: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/

  1. в файле сценария добавьте оператор с sourceURL, например " / / @ sourceURL=foo.js"
  2. загрузите скрипт с помощью jQuery $.getScript () и скрипт будут доступны на вкладке "Источники" в Chrome dev tools

ваш скрипт , вы просто не можете использовать 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 Element. Это можно сделать с помощью 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!'))

его не нужно оборачивать в 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 );

Я пробовал это один и работает отлично. Просто замените < символ с \x3C.

// With Variable
var code = "\x3Cscript>SomeCode\x3C/script>";
$("#someElement").append(code);

или

//Without Variable
$("#someElement").append("\x3Cscript>SomeCode\x3C/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