web-dev-qa-db-fra.com

Impossible de lire la propriété 'addEventListener' de null

Je dois utiliser JavaScript vanille pour un projet. J'ai quelques fonctions, dont l'une est un bouton qui ouvre un menu. Cela fonctionne sur les pages où l'ID cible existe, mais provoque une erreur sur les pages où l'ID n'existe pas. Sur les pages où la fonction ne peut pas trouver l'ID, je reçois l'erreur "Impossible de lire la propriété 'addEventListener' of null" et aucune de mes autres fonctions ne fonctionne.

Vous trouverez ci-dessous le code du bouton qui ouvre le menu. 

function swapper() {
toggleClass(document.getElementById('overlay'), 'open');
}

var el = document.getElementById('overlayBtn');
el.addEventListener('click', swapper, false);

var text = document.getElementById('overlayBtn');
text.onclick = function(){
this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
return false;
};

Comment puis-je gérer cela? J'ai probablement besoin de tous envelopper ce code dans une autre fonction ou utiliser une instruction if/else afin qu'il ne recherche que l'id sur des pages spécifiques, mais pas exactement. 

57
morocklo

Je pense que la solution la plus simple serait de vérifier que el n'est pas null avant d'ajouter un écouteur d'événement

var el = document.getElementById('overlayBtn');
if(el){
  el.addEventListener('click', swapper, false);
}
123
Rob M.

Il semble que document.getElementById('overlayBtn'); renvoie null car il s'exécute avant que le DOM ne soit complètement chargé.

Si vous mettez cette ligne de code sous

window.onload=function(){
  -- put your code here
}

alors il se déroulera sans problème.

Exemple:

window.onload=function(){
    var mb = document.getElementById("b");
    mb.addEventListener("click", handler);
    mb.addEventListener("click", handler2);
}


function handler() {
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-1!<br>");
}

function handler2() {
    $("p").html("<br>" + $("p").text() + "<br>You clicked me-2!<br>");
}
69
Dilip Agheda

J'ai fait face à une situation similaire. C'est probablement parce que le script est exécuté avant le chargement de la page. En plaçant le script au bas de la page, j'ai contourné le problème.

15
sridhar

Je recevais la même erreur, mais effectuer un contrôle nul ne semblait pas aider.

La solution que j'ai trouvée consistait à intégrer ma fonction dans un écouteur d'événement pour l'ensemble du document afin de vérifier le chargement du DOM.

document.addEventListener('DOMContentLoaded', function () {
    el.addEventListener('click', swapper, false);
});

Je pense que c'est parce que j'utilise un framework (Angular) qui modifie dynamiquement mes classes HTML et mes identifiants.

11
MattSidor

Merci à Robert M. pour son aide. Voici à quoi ressemblait le dernier bloc de code:

function swapper() {
  toggleClass(document.getElementById('overlay'), 'open');
}

var el = document.getElementById('overlayBtn');
if (el){
  el.addEventListener('click', swapper, false);

  var text = document.getElementById('overlayBtn');
  text.onclick = function(){
    this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
    return false;
  };
}
2
morocklo

C'est juste parce que votre JS est chargé avant la partie HTML et ne peut donc pas trouver cet élément. Il suffit de mettre tout votre code JS dans une fonction qui sera appelée lorsque la fenêtre sera chargée.

Vous pouvez également mettre votre code Javascript sous le code HTML.

1
Ajit Kumar

J'ai simplement ajouté "async" à ma balise de script, ce qui semble avoir résolu le problème. Je ne sais pas pourquoi, si quelqu'un peut expliquer, mais cela a fonctionné pour moi. J'imagine que la page n'attend pas le chargement du script. La page se charge en même temps que le code JavaScript.

Async/Await nous permet d'écrire du code asynchrone de manière synchrone. c’est juste du sucre syntaxique qui utilise des générateurs et des instructions de rendement pour «suspendre» l’exécution, nous permettant ainsi de l’assigner à une variable!

Voici le lien de référence- https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da

1
Andy Smith

Comme d'autres l'ont dit, le script est exécuté avant le chargement de la page (et en particulier de l'élément cible).

Mais je n'aime pas la solution de réorganisation du contenu.

La solution préférée consiste à placer un gestionnaire d’événements sur un événement page onload et à définir l’auditeur à cet endroit. Cela garantira que la page et l'élément cible sont chargés avant l'exécution de l'affectation. par exemple

    <script>
    function onLoadFunct(){
            // set Listener here, also using suggested test for null
    }
    ....
    </script>

    <body onload="onLoadFunct()" ....>
    .....
0
pjm

J'ai une collection de citations avec des noms. J'utilise le bouton de mise à jour pour mettre à jour le dernier devis associé à un nom spécifique, mais en cliquant sur le bouton de mise à jour, il ne se met pas à jour. J'inclus le code ci-dessous pour le fichier server.js et le fichier js externe (main.js).

main.js (js externe)

var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {

  fetch('quotes', {
  method: 'put',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    'name': 'Muskan',
    'quote': 'I find your lack of faith disturbing.'
  })
})var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {

  fetch('quotes', {
  method: 'put',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    'name': 'Muskan',
    'quote': 'I find your lack of faith disturbing.'
  })
})
.then(res =>{
    if(res.ok) return res.json()
})
.then(data =>{
    console.log(data);
    window.location.reload(true);
})
})
}

fichier server.js

app.put('/quotes', (req, res) => {
  db.collection('quotations').findOneAndUpdate({name: 'Vikas'},{
    $set:{
        name: req.body.name,
        quote: req.body.quote
    }
  },{
    sort: {_id: -1},
    upsert: true
  },(err, result) =>{
    if (err) return res.send(err);
    res.send(result);
  })

})
0
Ambreen Fatima