yuji_sakai
@yuji_sakai (酒井 悠治)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ハンバーガーメニュー実装中 JavaScriptエラー

解決したいこと

【JS】addEventListenerが機能しない理由について。
モバイルメニューをクリックすることで、javascriptのclickイベントを発火させたいが、(Uncaught TypeError:nullのプロパティ 'addEventListener'を読み取れません)とエラーがでます!
初歩的なミスかと思いますが原因が分からず
どこにミスがあるのかご教示いただけないでしょうか。
よろしくお願いします。

発生している問題・エラー

Uncaught TypeError: Cannot read property 'addEventListener' of null

https://gyazo.com/461f43de6e7fa31cca73fd2bc5055aa7

該当するソースコード

app > javascript > packs > application.js


require("@rails/ujs").start()
// require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("../main.js")


app > javascript > main.js


class MobileMenu {
    constructor() {
        this.DOM = {};
        this.DOM.btn = document.querySelector('.mobile-menu__btn');
        this.DOM.cover = document.querySelector('.mobile-menu__cover');
        this.DOM.container = document.querySelector('#global-container');
        this.eventType = this._getEventType();
        this._addEvent();
    }

    _getEventType() {
        return window.ontouchstart ? 'touchstart' : 'click';
    }

    _toggle() {
        this.DOM.container.classList.toggle('menu-open');
    }

    _addEvent() {
        this.DOM.btn.addEventListener(this.eventType, this._toggle.bind(this));
      ↑ここでエラーが起こっています!
        this.DOM.cover.addEventListener(this.eventType, this._toggle.bind(this));
    }
}

new MobileMenu();
app > views > tweets > index.html.erb


<div id="global-container">
    <div id="container">
        <header class="header">
            <button class="mobile-menu__btn">
                <span></span>
                <span></span>
                <span></span>
            </button>
        </header>
    </div>
    <nav class="mobile-menu">
        <ul class="mobile-menu__main">
            <li class="mobile-menu__item">
                <a href="#">
                    <span class="main-title">Login</span>
                    <span class="sub-title">ログイン</span>
                </a>
            </li>
            <li class="mobile-menu__item">
                <a href="#">
                    <span class="main-title">Sign Up</span>
                    <span class="sub-title">新規登録</span>
                </a>
            </li>
        </ul>
    </nav>
</div> 


app > views > layouts > application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>FruitStore</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all' %>
    <%= javascript_pack_tag 'application' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
app > assets > stylesheets > tweets.scss


$cBlack: black;
$cWhite: white;

.mobile-menu__btn {
    background-color: unset;
    border: none;
    outline: none !important;
    cursor: pointer;

    & > span {
        background-color: $cBlack;
        width: 35px;
        height: 2px;
        display: block;
        margin-bottom: 9px;
        transition: transform 0.7s;

        &:last-child {
            margin-bottom: 0;
        }
    }
}

.menu-open {
    background-color: $cBlack;

    & .mobile-menu__btn {
        & > span {
            background-color: $cWhite;

            &:nth-child(1) {
                transition-delay: 70ms;
                transform: translateY(11px) rotate(135deg);
            }
            &:nth-child(2) {
                transition-delay: 0s;
                transform:  translateX(-18px) scaleX(0);
            }
            &:nth-child(3) {
                transition-delay: 140ms;
                transform: translateY(-11px) rotate(-135deg);
            }
        }
    }
}


1

1Answer

DOMの要素の検索はDOMの生成が終わったあとにしないといけません。
提示いただいたコードはDOMの生成が終わってないのにquerySelectorでDOMの検索を行っているため、nullが帰ってきてることがエラーになってます。
つまりdocument.querySelectorはdocument.addEventListener 'DOMContentLoaded' 内に書かないといけません。

0Like

Comments

  1. @yuji_sakai

    Questioner

    document.addEventListener("DOMDontentLoaded, function() {
    js のソースコード
    });
    で囲ったら無事に読み込まれました!ちゃんと基礎を学ぼうと思いました!
    コメントありがとうございました。助かりました!

Your answer might help someone💌