2014-09-29 8 views
44

Ich muss Vanilla JavaScript für ein Projekt verwenden. Ich habe ein paar Funktionen, von denen eine eine Schaltfläche ist, die ein Menü öffnet. Es funktioniert auf Seiten, auf denen die Ziel-ID existiert, verursacht jedoch einen Fehler auf Seiten, auf denen die ID nicht existiert. Auf den Seiten, auf denen die Funktion die ID nicht finden kann, erhalte ich die Fehlermeldung "Ich kann die Eigenschaft 'addEventListener' von null nicht lesen" und keine meiner anderen Funktionen.Kann Eigenschaft 'addEventListener' von Null nicht lesen

Unten ist der Code für die Schaltfläche, die das Menü öffnet.

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; 
}; 

Wie gehe ich damit um? Wahrscheinlich muss ich diesen Code in eine andere Funktion schreiben oder eine if/else-Anweisung verwenden, damit nur auf bestimmten Seiten nach der ID gesucht wird, aber nicht genau.

+1

können Sie den HTML-Code anzeigen. es scheint, dass Element mit der ID 'overlayBtn' nicht finden kann – BlaShadow

+1

Auf den Seiten, auf denen die Funktion die ID nicht finden kann, erhalte ich eine "Kann nicht lesen Eigenschaft 'addEventListener' von null" Fehler und keine meiner anderen Funktionen funktionieren. Ich denke, die Antwort war ziemlich in der Frage. Sie konnten das Element nicht finden, daher können Sie ihm keinen Ereignis-Listener hinzufügen ... – Etai

+1

Es kann einfach passieren, wenn Sie 'class' in Ihrem HTML anstelle von' id' verwendet haben und Sie ein 'getElementById' aufrufen in deinen Skripten. – Deke

Antwort

89

Ich denke, der einfachste Ansatz nur wäre zu prüfen, ob el einen Ereignis-Listener nicht null ist vor der Zugabe:

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

genial. Das hat den Trick gemacht. Ich habe auch die onclick-Funktion in die if-Anweisung verschoben. Ich habe den letzten Code unten veröffentlicht. – morocklo

+1

wird es 'null' sein, bevor die reagierende Komponente geladen wurde! –

2

Dank @ Rob M. für seine Hilfe. So sah der letzte Code-Block aus:

11

Ich bekam den gleichen Fehler, aber das Ausführen eines Null-Checks schien nicht zu helfen.

Die Lösung, die ich fand, bestand darin, meine Funktion innerhalb eines Ereignis-Listeners für das gesamte Dokument zu verpacken, um zu überprüfen, wann das DOM fertig geladen wurde.

Ich denke, das liegt daran, dass ich ein Framework (Angular) verwende, das meine HTML-Klassen und IDs dynamisch ändert.

10

Ich konfrontiert eine ähnliche Situation. Dies liegt wahrscheinlich daran, dass das Skript vor dem Laden der Seite ausgeführt wird. Indem ich das Skript am Ende der Seite platziert habe, habe ich das Problem umgangen.

+1

Ja, ich denke, dass es je nach Szenario mehrere Lösungen für dieses Problem gibt. – rpeg

0

Wie andere gesagt haben, ist das Problem, dass Skript ausgeführt wird, bevor die Seite (und insbesondere das Zielelement) geladen wird.

Aber ich mag die Lösung nicht, den Inhalt neu zu ordnen.

Die bevorzugte Lösung besteht darin, einen Event-Handler auf das Onload-Ereignis der Seite zu setzen und den Listener dort einzustellen. Dadurch wird sichergestellt, dass die Seite und das Zielelement geladen werden, bevor die Zuweisung ausgeführt wird.

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

    <body onload="onLoadFunct()" ....> 
    ..... 
46

Es scheint, dass document.getElementById('overlayBtn');null zurückkehrt, da es vor dem DOM Lasten vollständig ausführt.

Wenn Sie diese Codezeile setzen unter

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

dann wird es ohne Probleme laufen.

Beispiel:

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>"); 
} 
0

Ich habe eine Sammlung von Zitaten zusammen mit Namen. Ich benutze Update-Taste, um das letzte Zitat zu einem bestimmten Namen zu aktualisieren, aber beim Klicken auf Update-Taste wird nicht aktualisiert. Ich schließe Code für server.js-Datei und externe js-Datei (main.js) ein.

main.js (externe js)

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); 
}) 
}) 
} 

server.js Datei

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); 
    }) 

}) 
-1

Dies ist, weil das Element nicht zu dem Zeitpunkt geladen worden war, wenn das Bündel js ausgeführt wurde.

Ich würde die <script src="sample.js" type="text/javascript"></script> auf den Grund der index.html Datei verschieben. Auf diese Weise können Sie sicherstellen, dass das Skript ausgeführt wird, nachdem alle HTML-Elemente analysiert und gerendert wurden.

+0

Falsch. Das ist Old-School-Denken. Laden am Ende verzögert das Laden, wie Sie angegeben haben, aber es ** stellt nicht sicher, dass das DOM vollständig gezogen wird **. Ich hatte ältere Seiten, die diesen Hack verwendeten, fehlgeschlagen, weil das DOM-Zeichnen langsamer als die Last war. [Diese Antwort] (https://stackoverflow.com/a/30063375/2370483) ** stellt sicher, dass ** das DOM vor der Ausführung gezeichnet wird. – Machavity

-2

Fügen Sie alle Ereignis-Listener hinzu, wenn ein Fenster geladen wird. Funktioniert wie ein Charm, egal, wo Sie Skript-Tags platzieren.

window.addEventListener("load", startup); 
function startup() { 
document.getElementById("el").addEventListener("click", myFunc); 
document.getElementById("el2").addEventListener("input", myFunc); 
} 
myFunc(){ 
} 
+0

Das Zeichnen der Seite kann manchmal länger dauern als das Laden des Skripts, daher ist die Position nicht in allen Fällen so wichtig. Das Hinzufügen eines Listeners ist der bevorzugte Weg, aber "Laden" ist aus demselben Grund auch veraltet. [DOMContentLoaded] (https://StackOverflow.com/questions/2414750/difference-between-domcontentloaded-and-load-events) ist der bevorzugte Weg, da er nur ausgelöst wird, nachdem das DOM vollständig gezeichnet wurde. – Machavity

+0

Es war ein sehr guter Versuch, du. – statosdotcom

+0

Danke ich werde es versuchen. Ich habe meine Antwort vom Mozilla-Netzwerk erhalten. Ich dachte, es wäre eine vertrauensvolle Quelle. –