Por que o document.getElementById () retornando um valor nulo quando eu sei que o ID existe?
-
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!
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.