web-dev-qa-db-ja.com

nullのプロパティ 'addEventListener'を読み取れません

プロジェクトにはVanilla JavaScriptを使用する必要があります。いくつかの機能がありますが、そのうちの1つはメニューを開くボタンです。ターゲットIDが存在するページでは機能しますが、IDが存在しないページではエラーが発生します。関数がIDを見つけられないページでは、 "nullのプロパティ 'addEventListener'を読み取れません"というエラーが表示され、他の関数は機能しません。

以下はメニューを開くボタンのコードです。

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のみを検索する必要があるかもしれませんが、必ずしも正確ではありません。

66
morocklo

最も簡単な方法は、イベントリスナを追加する前にelがnullではないことを確認することです。

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

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

私は同じような状況に直面しました。これはおそらく、ページが読み込まれる前にスクリプトが実行されるためです。スクリプトをページの下部に配置することで、私は問題を回避しました。

16
sridhar

同じエラーが表示されましたが、nullチェックを実行しても意味がないようです。

私が見つけた解決策は、DOMがいつロードを終了したかをチェックするためにドキュメント全体のためにイベントリスナーの中に私の関数をラップすることでした。

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

これは、私のHTMLクラスとIDを動的に変更しているフレームワーク(Angular)を使用しているためだと思います。

13
MattSidor

@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;
  };
}
3
morocklo

スクリプトタグに 'async'を追加しただけで、問題は解決したようです。誰かが説明することができる場合、私はなぜわからないが、それは私のために働いた。私の推測では、ページはスクリプトのロードを待っていないので、ページはJavaScriptと同時にロードされます。

Async/Awaitを使うと、非同期コードを同期的に書くことができます。ジェネレータを使用して文を実行し、実行を「一時停止」するステートメントを生成するだけで、変数に代入することができます。

これが参照リンクです - https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da

1
Andy Smith

他の人が言っているように、問題はページ(そして特にtarget要素)がロードされる前にスクリプトが実行されることです。

しかし、コンテンツを並べ替えるという解決策は好きではありません。

推奨される解決策は、ページonloadイベントにイベントハンドラを置き、そこにListenerを設定することです。これにより、割り当てが実行される前にページとターゲット要素が確実にロードされます。例えば

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

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

名前と一緒に引用符を集めました。特定の名前に関連付けられた最新の見積もりを更新するために更新ボタンを使用していますが、更新ボタンをクリックしても更新されません。以下に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
Ambreen Fatima