Por que o document.getElementById () retornando um valor nulo quando eu sei que o ID existe?

StackOverflow https://stackoverflow.com/questions/3823063

  •  26-09-2019
  •  | 
  •  

Pergunta

Estou trabalhando em algum JavaScript personalizado para um modelo CMS no trabalho. Eu quero ser capaz de fazer um certo <li> Elemento na página Receba a classe de "atual" apenas para essa página. Então, na cabeça da página global, eu tenho algo assim:

<script type="text/javascript">
    function makeCurrent(id) {
      var current = document.getElementById(id);
      current.setAttribute("class", "current"); // for most browsers
      current.setAttribute("className", "current"); // for ie
    }
</script>

Então em cada página individual <head>, Eu tenho algo assim:

<script type="text/javascript">makeCurrent("undergraduate")</script>

Na página eu tenho um navegação <ul>, com algo como:

<li id="undergraduate"><a href="...">Undergraduate Program</a></li>
<li id="graduate"><a href="...">Graduate Program</a></li>

etc.

Quando carrego a página, a classe não é aplicada. Quando olho no console do Firebug, ele fornece a mensagem de erro:

current is null
(x)  current.setAttribute("class", "current"); 

Ainda estou pegando o javascript sólido e cru (aprendendo para trás após o jQuery, você sabe como vai), mas quero escrever apenas JS. Que erro idiota estou cometendo?

Obrigado a todos!

Foi útil?

Solução

O elemento não existe No entanto, quando esse script está sendo avaliado. Coloque -o no manipulador Onload do corpo ou algo assim, para que ele seja executado quando o DOM estiver no lugar.

Um exemplo de como fazer isso sem tocar em nenhuma marcação:

function callWhenLoaded(func) {
  if (window.addEventListener) {
    window.addEventListener("load", func, false);
  } else if (window.attachEvent) {
    window.attachEvent("onload", func);
  }
}

callWhenLoaded(function() { makeCurrent("undergraduate"); });

Outras dicas

Se você executar o JavaScript antes que a árvore Dom termine de carregar, ela retornará nulo. Portanto, uma idéia seria chamar a função até o final antes de fechar a etiqueta corporal.

É por isso que a maioria das bibliotecas de JavaScript tem suporte para um evento pronto para o DOM, os navegadores modernos também têm isso (DomContentLoaded), no entanto, para o suporte amplo do navegador, é um pouco mais complicado fazer isso por si mesmo (bem, não tão difícil, 3 ou 4 maneiras diferentes Eu penso.)

O DOM não está totalmente carregado se você correr makeCurrent na sua cabeça. Você deve colocar esse script depois sua <li> Tag.

Seu código pode ser otimizado: você pode definir um class atribuir diretamente com current.className = 'current';.

O motivo é que seu script está sendo executado antes da conclusão da carga da página e, portanto, antes que o DOM seja preenchido.

Você precisa garantir que você ligue apenas a função após a conclusão da carga da página. Faça isso acionando -o usando document.onload () ou um evento Onload na tag corporal.

Depois que todas as respostas técnicas já foram vomitadas, vou pular todos aqueles que muito bem poderiam ser e optar por alguns dos mais óbvios que eu encontrei que me fizeram facepalt depois que eu percebi :

  • Erro na identidade
  • A identidade não é o que você acha que é porque está sendo gerada ou parcialmente gerada pela estrutura da web que você está usando no ASP.net, você pode definir o ID do cliente como "mycontrol" apenas para encontrar isso quando é renderizado No cliente, é "Page_1 $ Control_0 $ MyControl $ 1"
  • Você o antecendeu com um # em um ou mais lugares incorretos, por exemplo, embora você não esteja usando jQuery em seu exemplo se o ID do objeto for mycontrol, no jQuery e no CSS, você faz referência a #myControl, mas em O ID real do objeto, você não usou #. Em document.getElementById () você não Use um # como faria no jQuery e no CSS, mas você pode ter usado inadvertidamente.
  • Você definiu o elemento de nome no controle em vez do ID.

Como outras pessoas mencionaram, porém, pode ser por não esperar que o elemento esteja disponível no momento em que você está referenciando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top