Alguma idéia de por que o trecho de código abaixo não adiciona o elemento de script ao DOM?
var code = "<script></script>";
$("#someElement").append(code);
Alguma idéia de por que o trecho de código abaixo não adiciona o elemento de script ao DOM?
var code = "<script></script>";
$("#someElement").append(code);
Respostas:
Vi problemas em que alguns navegadores não respeitam algumas alterações quando você as faz diretamente (o que significa criar o HTML a partir de texto como você está tentando com a tag de script), mas quando você faz isso com comandos internos as coisas vão melhor. Tente o seguinte:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
De: JSON para jQuery
$("#someElement")[0].appendChild( script );
A boa notícia é:
Está 100% funcionando.
Basta adicionar algo dentro da tag de script, como alert('voila!');
. A pergunta certa que você talvez queira fazer, "Por que não a vi no DOM?" .
Karl Swedberg fez uma boa explicação para o comentário do visitante no site da API do jQuery . Eu não quero repetir todas as suas palavras, você pode ler diretamente lá aqui (Eu achei difícil de navegar através dos comentários lá) .
Todos os métodos de inserção do jQuery usam uma função domManip internamente para limpar / processar elementos antes e depois da inserção no DOM. Uma das coisas que a função domManip faz é extrair qualquer elemento de script a ser inserido e executá-lo através de uma "rotina evalScript" em vez de injetá-lo com o restante do fragmento DOM. Ele insere os scripts separadamente, avalia-os e os remove do DOM.
Acredito que um dos motivos pelos quais o jQuery faça isso é evitar erros de "Permissão Negada" que podem ocorrer no Internet Explorer ao inserir scripts em determinadas circunstâncias. Também evita inserir / avaliar repetidamente o mesmo script (que pode causar problemas) se estiver dentro de um elemento que você está inserindo e depois se mover pelo DOM.
O próximo passo é resumir as más notícias usando a .append()
função para adicionar um script.
E as más notícias são ..
Você não pode depurar seu código.
Não estou brincando, mesmo se você adicionar uma debugger;
palavra-chave entre a linha que deseja definir como ponto de interrupção, você acabará recebendo apenas a pilha de chamadas do objeto sem ver o ponto de interrupção no código-fonte (sem mencionar que isso Se a palavra-chave funcionar apenas no navegador da WebKit, todos os outros principais navegadores parecem omitir essa palavra-chave) .
Se você entender completamente o que seu código faz, isso será uma pequena desvantagem. Mas se não o fizer, você acabará adicionando uma debugger;
palavra - chave em todo o lugar apenas para descobrir o que há de errado com o seu (ou o meu) código. De qualquer forma, existe uma alternativa, não esqueça que o javascript pode manipular nativamente o HTML DOM.
Gambiarra.
Use javascript (não jQuery) para manipular o DOM HTML
Se você não deseja perder a capacidade de depuração, pode usar a manipulação de DOM HTML nativo em javascript. Considere este exemplo:
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);
Aí está, assim como nos velhos tempos, não é? E não esqueça de limpar as coisas, seja no DOM ou na memória, para todos os objetos referenciados e que não são mais necessários para evitar vazamentos de memória. Você pode considerar este código para limpar as coisas:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
A desvantagem desta solução alternativa é que você pode adicionar acidentalmente um script duplicado, e isso é ruim. A partir daqui, você pode imitar levemente a .append()
função adicionando uma verificação de objeto antes de adicionar e removendo o script do DOM logo após a adição. Considere este exemplo:
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;
}
Dessa forma, você pode adicionar scripts com capacidade de depuração, protegidos da duplicidade de scripts. Este é apenas um protótipo, você pode expandir para o que quiser. Eu tenho usado essa abordagem e bastante satisfeito com isso. Com certeza, nunca usarei o jQuery .append()
para adicionar um script.
$.getScript
está embutido no jQuery.
É possível carregar dinamicamente um arquivo JavaScript usando a função jQuerygetScript
$ .getScript ('http://www.whatever.com/shareprice/shareprice.js', function () { Display.sharePrice (); });
Agora, o script externo será chamado e, se não puder ser carregado, será degradado normalmente.
eval()
.
O que você quer dizer com "não está funcionando"?
O jQuery detecta que você está tentando criar um elemento SCRIPT e executará automaticamente o conteúdo do elemento dentro do contexto global. Você está me dizendo que isso não funciona para você? -
$('#someElement').append('<script>alert("WORKING");</script>');
Edit: Se você não está vendo o elemento SCRIPT no DOM (no Firebug, por exemplo) depois de executar o comando, porque o jQuery, como eu disse, executará o código e excluirá o elemento SCRIPT - acredito que os elementos SCRIPT sempre são anexados ao corpo ... mas de qualquer maneira - o posicionamento não tem absolutamente nenhuma influência na execução do código nessa situação.
Isso funciona:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
Parece que o jQuery está fazendo algo inteligente com os scripts, então você precisa acrescentar o elemento html ao invés do objeto jQuery.
Tente isto pode ser útil:
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>
O </script>
literal dentro da string finaliza o script inteiro, para evitar que "</scr" + "ipt>"
possa ser usado.
"\x3cscript\x3e\x3c/script\x3e"
. No XHTML, você só precisa inserir um bloco CDATA comentado.
</
que não é permitido. Veja stackoverflow.com/questions/236073/…
A adição do sourceURL ao arquivo de script ajudou conforme mencionado nesta página: https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
Seu script está em execução, você simplesmente não pode usá document.write
-lo. Use um alerta para testá-lo e evite usá-lo document.write
. As instruções do seu arquivo js com document.write
não serão executadas e o restante da função será executada.
É isso que eu acho que é a melhor solução. O Google Analytics é injetado dessa maneira.
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); })();
Você não precisa do jQuery para criar um elemento DOM do script . Isso pode ser feito com a baunilha ES6 da seguinte forma:
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!'))
Ele não precisa ser envolvido em um arquivo Promise
, mas isso permite que você resolva a promessa quando o script é carregado, ajudando a evitar condições de corrida para scripts de longa execução.
Anexe o script ao corpo:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Outra maneira de fazer isso se você quiser acrescentar código é usar o document.createElement
método, mas depois usar em .innerHTML
vez de .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 );
Pode tentar assim
var code = "<script></" + "script>";
$("#someElement").append(code);
A única razão pela qual você não pode fazer isso "<script></script>"
é porque a string não é permitida dentro do javascript, porque a camada DOM não pode analisar o que é js e o que é HTML.
Eu escrevi um npm
pacote que permite pegar uma string HTML, incluindo tags de script e anexá-la a um contêiner durante a execução dos scripts
Exemplo:
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)
Encontre-o aqui: https://www.npmjs.com/package/appendhtml
Basta criar um elemento analisando-o com o jQuery.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Exemplo de trabalho: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz