document.querySelector(...) is null error

Viewed 130535

For image upload in a cakephp project I used java-script.I added this js file in app\View\Layouts default.ctp

js code

document.querySelector('input[type=file]').addEventListener('change', function(event){

  var files = event.target.files;

  for (var i = 0; i < files.length; i++) {

    if (files[i].type.match(/image.*/)) {

        var reader = new FileReader();
        reader.onload = function (readerEvent) {
            var image = new Image();
            image.onload = function (imageEvent) {

                var imageElement = document.createElement('div');
                imageElement.classList.add('uploading');
                imageElement.innerHTML = '<span class="progress"><span></span></span>';
                var progressElement = imageElement.querySelector('span.progress span');
                progressElement.style.width = 0;
                document.querySelector('form div.photos').appendChild(imageElement);


                var canvas = document.createElement('canvas'),
                    max_size = 1200,
                    width = image.width,
                    height = image.height;
                if (width > height) {
                    if (width > max_size) {
                        height *= max_size / width;
                        width = max_size;
                    }
                } else {
                    if (height > max_size) {
                        width *= max_size / height;
                        height = max_size;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                canvas.getContext('2d').drawImage(image, 0, 0, width, height);

                var xhr = new XMLHttpRequest();
                if (xhr.upload) {

                    // Update progress
                    xhr.upload.addEventListener('progress', function(event) {
                        var percent = parseInt(event.loaded / event.total * 100);
                        progressElement.style.width = percent+'%';
                    }, false);


                    xhr.onreadystatechange = function(event) {
                        if (xhr.readyState == 4) {
                            if (xhr.status == 200) {

                                imageElement.classList.remove('uploading');
                                imageElement.classList.add('uploaded');
                                imageElement.style.backgroundImage = 'url('+xhr.responseText+')';

                                console.log('Image uploaded: '+xhr.responseText);

                            } else {
                                imageElement.parentNode.removeChild(imageElement);
                            }
                        }
                    }

                    xhr.open('post', 'process.php', true);
                    xhr.send(canvas.toDataURL('image/jpeg'));

                }

            }

            image.src = readerEvent.target.result;

        }
        reader.readAsDataURL(files[i]);
    }

}

event.target.value = '';

I have checked there are no problem.

now in add.ctp file I adder

<input type="file" multiple />

In output I am seeing the file type field.Now when I clicked on this field and upload a image then mojila bug given me a error.That is

document.querySelector(...) is null error

I have no idea about this error.In here why saying queryselector is null?

7 Answers

To make sure that your DOM is ready you could add this to your JS file.

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.querySelector('input[type=file]')
        .addEventListener('change', function(event){
            ...
         }
});

This way you could call your js files from wherever you like. Please take a look to this superb answer to get further insight on these matters.

Also take a look at this other Google rule.

file.js

const heading1 = document.querySelector(".heading1");
console.log(heading1);

Solution 1


Use defer (best & recommended way):

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="./file.js" defer></script>
    <title>Document</title>
</head>
<body>
    <h1 class="heading1">Hello World 1</h1>
</body>
</html>

Solution 2

Place your JavaScript in bottom before closing body tag

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <h1 class="heading1">Hello World 1</h1>

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

I suggest writing your <script type="text/javascript" src="your js file"></script> in body, before the closing tag

There is now another "better" way to address this issue.

put your scripts in the head tag and add the defer attribute.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <script src="main.js" defer></script>
</head>
<body>
  yoyoyo
</body>
</html>

you can read more about it here and here

TLDR (may be inaccurate and misleading so read the sources above!): the defer attribute tells the browser to load the file but hold off its execution until the dom is ready, which is close to the behavior you implicitly get when you put the script tag at the bottom of the body tag, the difference being that in the old way you have to wait for the whole body tag to be parsed until you start downloading the script tag.

I ran into this issue where I was trying to do (slimmed down for simplicity):

<script type="text/javascript">
    var svg = document.querySelector('svg');
    console.log(svg);
</script>

on an element in the <body>:

<svg id="svg" viewBox="0 0 120 120" width="500px" height="500px"></svg>

Once I added jQuery and moved my lines inside of a $(document).ready(), it was fine:

<script type="text/javascript" src="jquery-1.12.4.min.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        var svg = document.querySelector('svg');
        console.log(svg);
    });
</script>

Here's a quick fix. I was trying to effect some changes in my HTML page using DOM and was getting this error. The problem was I linked my Javascript file inside the head tag of the HTML page, when I changed that and linked it at the body just before the closing body tag, it worked!

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Soft dog</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
        integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <link rel="stylesheet" href="landing.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link
        href="https://fonts.googleapis.com/css2?family=Cormorant+SC:wght@300&family=Edu+VIC+WA+NT+Beginner&display=swap"
        rel="stylesheet">
</head>

<body>
    <div class="container">
        <h2 id="newBrand">Welcome to SOFTDOG</h2>
        <p><em>property of soft 6</em></p>
        <a id="ceo" href="home.html"><img src="softdogmerch1.jpg" alt="check network"></a>
        <p id="enterstatement">Please<a href="home.html">
                <P><span>ENTER HERE</span></P>
            </a><span>to feed your eyes and fill your wardrobe</span>
        </p>

        <label for="emailinput">email:</label>
        <input id="emailinput" type="email" name="useremail" placeholder="user@email.com" required>
        <label for="passwordinput">password:</label>
        <input id="passwordinput" type="password" name="userpassword" placeholder="" required>

        <input id="clickme" type="submit" name="login" value="log in">
        <input id="clickme" type="submit" name="signup" value="sign up">
    </div>

    <script src="landing.js"></script>

</body>

</html>
Related