0

I'm trying to grab an element in my DOM with getElementByID but I keep getting an error message in the dev console saying Cannot read property 'addEventListener' of null.

I'm using webpack to bundle my code. I originally thought it was because webpack was injecting the script tag in the head of my html but have since sorted that problem by getting webpack to inject it at the end of the body of my html. Doing this I still have the problem reoccurring.

I've recreated what I expect to happen in codepen which is when the hamburger on my page is clicked a nav-list will be displayed. Basically, I just made a red box and a blue box, and when the red box was clicked the blue box would either appear or disappear. It worked the way I want it too so I know it is to do with my webpack setup.

Here is my code.

Html

<header>
    <div class="header__container">
      <nav class="nav">
        <div class="nav_items_left">
          <svg class="blogr__logo"></svg>
        </div>
        <div class="nav_items_right">
          <svg class="hamburger__img" id="hambuger"></svg>
          <div class="nav__bar" id="nav_bar">
            <div class="nav__item" id="nav_item">
              <p class="nav_head_title">Product<i class="fas fa-chevron-down"></i></p>
              <div class="sub_item" id="sub_item">
                <a href="#">Overview</a>
                <a href="#">Pricing</a>
                <a href="#">Marketplace</a>
                <a href="#">Features</a>
                <a href="#">Integrations</a>
              </div>
            </div>
            <div class="nav__item" id="nav_item">
              <p class="nav_head_title">Company<i class="fas fa-chevron-down"></i></p>
              <div class="sub_item" id="sub_item">
                <a href="#">About</a>
                <a href="#">Team</a>
                <a href="#">Blog</a>
                <a href="#">Careers</a>
              </div>
            </div>
            <div class="nav__item" id="nav_item">
              <p class="nav_head_title">Connect<i class="fas fa-chevron-down"></i></p>
              <div class="sub_item" id="sub_item">
                <a href="#">Contact</a>
                <a href="#">Newsletter</a>
                <a href="#">LinkedIn</a>
              </div>
            </div>
            <hr class="line__break">
            <div class="mobile_buttons">
              <a href="" class="mobile_login">Login</a>
              <a href="" class="mobile_sign_up">Sign Up</a>
            </div>
          </div>
        </div>
      </nav>

      <div class="hero__section">
        <div class="headers">
          <h1>A modern publishing platform</h1>
          <h3>Grow your audience and build your online brand</h3>
        </div>
        <div class="main__buttons">
          <button href="#" class="start_for_free">Start for Free</button>
          <button href="#" class="learn_more">Learn More</button>
        </div>
      </div>
    </div>
  </header>

JS

document.getElementById('hamburger').addEventListener('click', showNav);

function showNav() {
    
    const navMenu = document.getElementById('nav_bar');

    if(navMenu.style.display == 'none') {
        navMenu.style.display = 'block';
    } else {
        navMenu.style.display = 'none'
    }

}

export { showNav }

webpack.dev

const path = require("path");
const common = require("./webpack.common")
const { merge } = require("webpack-merge");
const HtmlWebpackPlugin = require("html-webpack-plugin");


module.exports = merge(common, {
    mode: 'development',
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, "dist")
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html",
            filename: "./index.html",
            inject: 'body'
        }),
    ],
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            }
        ]
    }
});

webpack.prod

const path = require("path");
const common = require("./webpack.common")
const { merge } = require("webpack-merge");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");



module.exports = merge(common, {
    mode: 'production',
    output: {
        filename: '[name].[contenthash].bundle.js',
        path: path.resolve(__dirname, "dist")
    },
    optimization: {
        minimizer: [
            new OptimizeCssAssetsPlugin(), new TerserPlugin(), new HtmlWebpackPlugin({
                template: "./src/index.html",
                filename: "./index.html"
            }),
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({ filename:"[name].[contenthash].css" }),
        new CleanWebpackPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
            }
        ]
    }
});

webpack.common

const path = require("path");
const webpack = require("webpack");


module.exports = {
    output: {
        filename: 'main.[contentHash].js',
        path: path.resolve(__dirname, "dist")
    },
    devtool: 'source-map',
    entry: {
        main: "./src/js/index.js",
        vendor: "./src/vendor.js"
    },
    module: {
        rules: [
            {
                test: '/\.js$/',
                exclude: /node_modules/,
                loader: "babel-loader"
            },
            {
                test: /\.html$/,
                use: ["html-loader"]
            },
            {
                test: /\.(svg|png|jpeg|gif)$/,
                use: {
                    loader: "file-loader",
                    options: {
                        name: "[name].[hash].[ext]",
                        outputPath: "imgs"
                    }
                }
            }
        ]
    }
}

1 Answers1

0

getElementById means:

  • It creates a variable with the id given.
  • If multiple elements have the same ID (this is really bad practice, don't do this), it selects the first item.
  • If no element has the ID, it is equal to null.

Click the "Run Code Snippet" button, and then "Test", to see an example of this error.

<p id="dontchangeme">Click the button!</p>
<button onclick="document.getElementById('changeme').innerHTML='done!';">Test</button>

You get the error thrown in the console.

So, make sure the "hamburger" id is present.

If the id is present, everything works:

<p id="changeme">Click the button!</p>
<button onclick="document.getElementById('changeme').innerHTML='done!';">Test</button>

You don't have an id hamburger, you only have id hambuger. Change hambuger to hamburger and it should work fine.