javascript child Como posso referenciar a tag de script que carregou o script atualmente em execução?




javascript get child element array (12)

Existe outra maneira fácil, se você souber o nome do script (ou pelo menos uma parte dele):

document.querySelector('script[src*="<scriptname>.js"]')

Isso também funcionará no IE11.

Como posso referenciar o elemento de script que carregou o javascript atualmente em execução?

Aqui está a situação. Eu tenho um script "mestre" sendo carregado no topo da página, a primeira coisa sob a tag HEAD.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>

Existe um script em "scripts.js" que precisa ser capaz de fazer o carregamento sob demanda de outros scripts. O método normal não funciona muito para mim porque eu preciso adicionar novos scripts sem referenciar a tag HEAD, porque o elemento HEAD não terminou a renderização:

document.getElementsByTagName('head')[0].appendChild(v);

O que eu quero fazer é referenciar o elemento de script que carregou o script atual para que eu possa acrescentar minhas novas tags de script carregadas dinamicamente no DOM depois dele.

<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>

Answer #1

Os scripts são executados sequencialmente apenas se não tiverem um atributo "adiar" ou "assíncrono". Saber um dos possíveis atributos ID / SRC / TITLE da tag de script pode funcionar também nesses casos. Então, as sugestões de Greg e Justin estão corretas.

Já existe uma proposta para um document.currentScript nas listas do WHATWG.

EDIT : Firefox> 4 já implementar esta propriedade muito útil, mas não está disponível no IE11 última vez que verifiquei e só está disponível no Chrome 29 e Safari 8.

EDIT : ninguém mencionou a coleção "document.scripts" mas acredito que o seguinte pode ser uma boa alternativa cross-browser para obter o script atualmente em execução:

var me = document.scripts[document.scripts.length -1];

Answer #2

Eu tenho isso, que está trabalhando em FF3, IE6 e 7. Os métodos nos scripts carregados sob demanda não estão disponíveis até que o carregamento da página seja concluído, mas isso ainda é muito útil.

//handle on-demand loading of javascripts
makescript = function(url){
    var v = document.createElement('script');
    v.src=url;
    v.type='text/javascript';

    //insertAfter. Get last <script> tag in DOM
    d=document.getElementsByTagName('script')[(document.getElementsByTagName('script').length-1)];
    d.parentNode.insertBefore( v, d.nextSibling );
}

Answer #3

Como obter o elemento de script atual:

1. Use document.currentScript

document.currentScript retornará o elemento <script> cujo script está sendo processado no momento.

<script>
var me = document.currentScript;
</script>

Benefícios

  • Simples e explícito. Confiável.
  • Não precisa modificar a tag de script
  • Funciona com scripts assíncronos ( defer e async )
  • Funciona com scripts inseridos dinamicamente

Problemas

  • Não funcionará em navegadores mais antigos e no IE.

2. Selecione o script por id

Ao atribuir ao script um atributo id, você poderá selecioná-lo facilmente pelo id, usando document.getElementById() .

<script id="myscript">
var me = document.getElementById('myscript');
</script>

Benefícios

  • Simples e explícito. Confiável.
  • Quase universalmente suportado
  • Funciona com scripts assíncronos ( defer e async )
  • Funciona com scripts inseridos dinamicamente

Problemas

  • Requer a adição de um atributo personalizado à tag de script
  • atributo id pode causar comportamento estranho para scripts em alguns navegadores para alguns casos extremos

3. Selecione o script usando um atributo data-*

Ao fornecer o script, um atributo data-* permitirá que você o selecione facilmente de dentro.

<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>

Isso tem poucos benefícios em relação à opção anterior.

Benefícios

  • Simples e explícito.
  • Funciona com scripts assíncronos ( defer e async )
  • Funciona com scripts inseridos dinamicamente

Problemas

  • Requer a adição de um atributo personalizado à tag de script
  • HTML5 e querySelector() não são compatíveis em todos os navegadores
  • Menos amplamente suportado do que usando o atributo id
  • Contornará <script> com casos de borda id .
  • Pode ficar confuso se outro elemento tiver o mesmo atributo de dados e valor na página.

4. Selecione o script por src

Em vez de usar os atributos de dados, você pode usar o seletor para escolher o script por fonte:

<script src="//example.com/embed.js"></script>

Em embed.js:

var me = document.querySelector('script[src="//example.com/embed.js"]');

Benefícios

  • Confiável
  • Funciona com scripts assíncronos ( defer e async )
  • Funciona com scripts inseridos dinamicamente
  • Nenhum atributo personalizado ou id necessário

Problemas

  • Não funciona para scripts locais
  • Causará problemas em diferentes ambientes, como Desenvolvimento e Produção.
  • Estático e frágil. Alterar o local do arquivo de script exigirá a modificação do script
  • Menos amplamente suportado do que usando o atributo id
  • Causará problemas se você carregar o mesmo script duas vezes

5. Faça um loop sobre todos os scripts para encontrar o que você quer

Também podemos fazer um loop em cada elemento de script e verificar cada um individualmente para selecionar o que queremos:

<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
    if( isMe(scripts[i])){
      me = scripts[i];
    }
}
</script>

Isso nos permite usar as técnicas anteriores em navegadores mais antigos que não suportam querySelector() com atributos. Por exemplo:

function isMe(scriptElem){
    return scriptElem.getAttribute('src') === "//example.com/embed.js";
}

Isso herda os benefícios e problemas de qualquer abordagem, mas não depende de querySelector() portanto, funcionará em navegadores mais antigos.

6. Obtenha o último script executado

Como os scripts são executados sequencialmente, o último elemento de script geralmente será o script atualmente em execução:

<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>

Benefícios

  • Simples.
  • Quase universalmente suportado
  • Nenhum atributo personalizado ou id necessário

Problemas

  • Não funciona com scripts assíncronos ( defer e async )
  • Não funciona com scripts inseridos dinamicamente

Answer #4

Ele deve funcionar no carregamento da página e quando uma tag de script é adicionada com o javascript (por exemplo, ajax)

<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>

Answer #5

Aqui está um pouco de um polyfill que aproveita document.CurrentScript se ele existir e recua para encontrar o script por ID.

<script id="uniqueScriptId">
    (function () {
        var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');

        // your code referencing thisScript here
    ());
</script>

Se você incluir isso no topo de cada tag de script, acredito que será capaz de saber de forma consistente qual tag de script está sendo disparada e também poderá fazer referência à tag de script no contexto de um retorno de chamada assíncrono.

Não testado, então deixe comentários para os outros se você tentar.


Answer #6

Considere este algoritmo. Quando seu script for carregado (se houver vários scripts idênticos), procure por document.scripts, localize o primeiro script com o atributo "src" correto e salve-o e marque-o como "visitado" com um atributo de dados ou um className exclusivo.

Quando o próximo script for carregado, digitalize novamente os documentos.scripts, passando por cima de qualquer script já marcado como visitado. Tome a primeira instância não visitada desse script.

Isso pressupõe que scripts idênticos provavelmente serão executados na ordem em que são carregados, da cabeça ao corpo, de cima para baixo, de síncrona a assíncrona.

(function () {
  var scripts = document.scripts;

  // Scan for this data-* attribute
  var dataAttr = 'data-your-attribute-here';

  var i = 0;
  var script;
  while (i < scripts.length) {
    script = scripts[i];
    if (/your_script_here\.js/i.test(script.src)
        && !script.hasAttribute(dataAttr)) {

        // A good match will break the loop before
        // script is set to null.
        break;
    }

    // If we exit the loop through a while condition failure,
    // a check for null will reveal there are no matches.
    script = null;
    ++i;
  }

  /**
   * This specific your_script_here.js script tag.
   * @type {Element|Node}
   */
  var yourScriptVariable = null;

  // Mark the script an pass it on.
  if (script) {
    script.setAttribute(dataAttr, '');
    yourScriptVariable = script;
  }
})();

Isso varrerá todo o script para o primeiro script correspondente que não esteja marcado com o atributo especial.

Em seguida, marque esse nó, se encontrado, com um atributo de dados para que as verificações subseqüentes não o escolham. Isso é semelhante aos algoritmos de BFS e DFS do gráfico transversal, nos quais os nós podem ser marcados como 'visitados' para evitar a revisão.


Answer #7

Para obter o script, que atualmente carregou o script que você pode usar

var thisScript = document.currentScript;

Você precisa manter uma referência no início do script, para poder ligar mais tarde

var url = thisScript.src

Answer #8

Eu encontrei o seguinte código para ser o mais consistente, performante e simples.

var scripts = document.getElementsByTagName('script');
var thisScript = null;
var i = scripts.length;
while (i--) {
  if (scripts[i].src && (scripts[i].src.indexOf('yourscript.js') !== -1)) {
    thisScript = scripts[i];
    break;
  }
}
console.log(thisScript);

Answer #9

Uma abordagem para lidar com scripts assíncronos e adiados é alavancar o manipulador onload em um manipulador onload para todas as tags de script e o primeiro que executa deve ser seu.

function getCurrentScript(callback) {
  if (document.currentScript) {
    callback(document.currentScript);
    return;
  }
  var scripts = document.scripts;
  function onLoad() {
    for (var i = 0; i < scripts.length; ++i) {
      scripts[i].removeEventListener('load', onLoad, false);
    }
    callback(event.target);
  }
  for (var i = 0; i < scripts.length; ++i) {
    scripts[i].addEventListener('load', onLoad, false);
  }
}

getCurrentScript(function(currentScript) {
  window.console.log(currentScript.src);
});

Answer #10

Provavelmente, a coisa mais fácil de fazer seria atribuir à sua tag de script um atributo id .


Answer #11

Siga estas etapas simples para obter referência ao bloco de script de execução atual:

  1. Coloque alguma string única aleatória dentro do bloco de script (deve ser única / diferente em cada bloco de script)
  2. Iterar o resultado de document.getElementsByTagName ('script'), procurando a string exclusiva de cada um de seus conteúdos (obtida da propriedade innerText / textContent).

Exemplo (ABCDE345678 é o ID exclusivo) :

<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
  if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>

btw, para o seu caso, você pode simplesmente usar o antigo método document.write () para incluir outro script. Como você mencionou que o DOM ainda não é renderizado, você pode tirar proveito do fato de que o navegador sempre executa scripts em seqüência linear (exceto para um que será renderizado posteriormente), então o restante do documento ainda não existe. Tudo o que você escrever através do document.write () será colocado logo após o script do chamador.

Exemplo de página HTML original :

<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>

Conteúdo do script.js :

document.write('<script src="inserted.js"></script>');

Depois de renderizada, a estrutura DOM se tornará:

HEAD
  SCRIPT script.js
  SCRIPT inserted.js
  SCRIPT otherscript.js
BODY






parent