null의 'addEventListener'속성을 읽을 수 없습니다.


106

프로젝트에 바닐라 자바 ​​스크립트를 사용해야합니다. 몇 가지 기능이 있는데 그중 하나는 메뉴를 여는 버튼입니다. 대상 ID가있는 페이지에서는 작동하지만 ID가없는 페이지에서는 오류가 발생합니다. 함수가 ID를 찾을 수없는 페이지에서 "Cannot read property 'addEventListener'of null"오류가 발생하고 다른 함수가 작동하지 않습니다.

다음은 메뉴를 여는 버튼의 코드입니다.

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

어떻게 처리합니까? 이 코드를 다른 함수로 모두 래핑하거나 if / else 문을 사용하여 특정 페이지에서만 ID를 검색하지만 정확히 확실하지는 않습니다.


1
html 코드를 보여줄 수 있습니까? ID가 'overlayBtn'인 요소를 찾을 수없는 것 같습니다
BlaShadow

2
함수가 ID를 찾을 수없는 페이지에서 "Cannot read property 'addEventListener'of null"오류가 발생하고 다른 함수가 작동하지 않습니다. 대답은 거의 질문에 있다고 생각합니다. 당신이 그것을에 이벤트 리스너를 추가 할 수 있도록 ... 요소를 찾을 수 없습니다
Etai

1
class대신 html에서 사용 하고 스크립트에서 ida를 호출 하면 간단하게 발생할 수 있습니다 getElementById.
Deke 2016-06-25

답변:


198

가장 쉬운 방법은 el이벤트 리스너를 추가하기 전에 null이 아닌지 확인하는 것 입니다.

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

대박. 그게 트릭을했습니다. 또한 onclick 함수를 if 문으로 옮겼습니다. 아래에 최종 코드를 게시했습니다.
morocklo 2014 년

3
그것은 될 것입니다 null전에 마운트 않았다 구성 요소 반응!

고마워요 : D 정확히 내가 찾던 것 .... 내 앱에는 여러 명의 청취자가 있고 청취자는 다른 시각으로 분산되어 있습니다. 요소가 페이지에있는 경우, 내 JS를 비료를했다
VegaStudios

매우 유용합니다. 감사합니다!
sc_props

113

DOM이 완전히로드되기 전에 실행되기 때문에 document.getElementById('overlayBtn');반환 되는 것 같습니다 null.

이 코드 줄을 아래에 넣으면

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

그러면 문제없이 실행됩니다.

예:

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

23

비슷한 상황에 직면했습니다. 페이지가로드되기 전에 스크립트가 실행되기 때문일 수 있습니다. 페이지 하단에 스크립트를 배치하여 문제를 피했습니다.


1
예, 시나리오에 따라이 문제에 대한 여러 솔루션이 있다고 생각합니다.
rpeg

16

동일한 오류가 발생했지만 null 검사를 수행해도 도움이되지 않는 것 같습니다.

내가 찾은 해결책은 DOM이로드를 마칠 때 확인하기 위해 전체 문서에 대한 이벤트 리스너 내부에 함수를 래핑하는 것입니다.

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

HTML 클래스와 ID를 동적으로 변경하는 프레임 워크 (Angular)를 사용하고 있기 때문이라고 생각합니다.


1
Electron을 사용할 때 동일한 문제가 발생합니다. 같은 방법으로 저장했습니다.
Charles

9

JS가 HTML 부분 이전에로드되는 bcz 일 뿐이므로 해당 요소를 찾을 수 없습니다. 윈도우가로드 될 때 호출 될 함수 안에 전체 JS 코드를 넣으십시오.

html 아래에 Javascript 코드를 넣을 수도 있습니다.


8

스크립트가 본문보다 먼저로드되고 내용 후에 스크립트 유지


5

본문 태그 끝에 스크립트를 넣습니다.

<html>
    <body>
        .........
        <script src="main.js"></script>
    </body>
</html>

3

도움을 주신 @Rob M.에게 감사드립니다. 최종 코드 블록은 다음과 같습니다.

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

단순히 스크립트 태그에 '비동기'를 추가했는데 문제가 해결 된 것 같습니다. 누군가가 설명 할 수 있다면 왜 그런지 모르겠지만 그것은 나를 위해 일했습니다. 내 생각 엔 페이지가 스크립트가로드되기를 기다리지 않기 때문에 페이지가 JavaScript와 동시에로드됩니다.

Async / Await를 사용하면 동기식으로 비동기 코드를 작성할 수 있습니다. 그것은 단지 제너레이터와 yield 문을 사용하여 실행을 "일시 중지"하는 구문 설탕 일 뿐이며, 변수에 할당 할 수있는 기능을 제공합니다!

다음은 참조 링크입니다. https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da


2

나는 같은 문제가 발생하여 null을 확인했지만 도움이되지 않았습니다. 페이지로드 전에 스크립트가로드 되었기 때문입니다. 따라서 end body 태그 앞에 스크립트를 배치하는 것만으로 문제가 해결되었습니다.


0

다른 사람들이 말했듯이 문제는 페이지 (특히 대상 요소)가로드되기 전에 스크립트가 실행된다는 것입니다.

하지만 콘텐츠 순서를 변경하는 솔루션이 마음에 들지 않습니다.

선호하는 솔루션은 페이지 onload 이벤트에 이벤트 핸들러를 배치하고 거기에 리스너를 설정하는 것입니다. 그러면 할당이 실행되기 전에 페이지와 대상 요소가로드됩니다. 예 :

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

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

0

이름과 함께 인용문 모음이 있습니다. 특정 이름과 관련된 마지막 견적을 업데이트하기 위해 업데이트 버튼을 사용하고 있지만 업데이트 버튼을 클릭하면 업데이트되지 않습니다. 아래에 server.js 파일 및 외부 js 파일 (main.js)에 대한 코드가 포함되어 있습니다.

main.js (외부 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 파일

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

감사합니다. 모든 페이지가 아니라 사용하는 특정 페이지에 스크립트를로드합니다. 때로는 swiper.js 또는 기타 라이브러리를 사용하면이 오류 메시지가 표시 될 수 있습니다.이 문제를 해결하는 유일한 방법은 특정 페이지에 JS 라이브러리를로드하는 것입니다. 해당 ID가 존재하고 모든 페이지에서 동일한 라이브러리가로드되지 않도록합니다.

도움이 되었기를 바랍니다.


0

나도 같은 문제가 있었지만 내 아이디가 있었다. 그래서 "window.onload = init;"를 추가해 보았습니다. 그런 다음 원래 JS 코드를 init 함수로 래핑했습니다 (원하는대로 호출). 이것은 효과가 있었으므로 적어도 내 경우에는 문서가로드되기 전에 이벤트 리스너를 추가했습니다. 이것은 당신이 경험하고있는 것일 수도 있습니다.


-1

이는 번들 js가 실행될 때 요소가로드되지 않았기 때문입니다.

파일의 <script src="sample.js" type="text/javascript"></script>맨 아래 로 옮길 것 index.html입니다. 이렇게하면 모든 html 요소가 구문 분석되고 렌더링 된 후에 스크립트가 실행되도록 할 수 있습니다.


틀 렸습니다. 이것은 구식 생각입니다. 마지막에로드하면 언급했듯이로드가 지연되지만 DOM이 완전히 그려지는 것은 아닙니다 . 이 해킹을 사용하는 이전 페이지가 DOM 그리기가로드보다 느리기 때문에 실행에 실패했습니다. 이 답변 실행 전에 DOM이 그려 지도록 합니다.
Machavity

-3

윈도우가로드 될 때 모든 이벤트 리스너를 추가하고 스크립트 태그를 어디에 두든 매력처럼 작동합니다.

window.addEventListener("load", startup);

function startup() {

  document.getElementById("el").addEventListener("click", myFunc);
  document.getElementById("el2").addEventListener("input", myFunc);

}

myFunc(){}

페이지 그리기는 스크립트로드보다 시간이 더 오래 걸릴 수 있으므로 모든 경우에 위치가 그다지 중요하지는 않습니다. 리스너를 추가하는 것이 선호되는 방법이지만 load같은 이유로 더 이상 사용되지 않습니다. DOMContentLoaded 는 DOM이 완전히 그려진 후에 만 ​​실행되기 때문에 선호되는 방법입니다.
Machavity

감사합니다. Mozilla 네트워크에서 답변을 받았습니다. 믿을 수있는 출처라고 생각했습니다.
Natalie Jimenez
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.