Alimon Karim
Alimon Karim

Reputation: 4469

document.querySelector(...) is null error

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?

Upvotes: 68

Views: 182871

Answers (8)

alboforlizo
alboforlizo

Reputation: 371

Same problem in a typical scenario: Ajax request, on response render some DOM elements and attach addEventListener to them. The last step must come at the end if document.querySelector() must work:

function myFunction()
{
    var elements = document.getElementsByClassName("formVal");
    var formData = new FormData(); 
    for(var i=0; i<elements.length; i++)
    {
        formData.append(elements[i].name, elements[i].value);
    }
    var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function()
        {
            if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
            {
                renderDOM_Elements_With_Response(xmlHttp.responseText);
                addEventListenerTo_DOM_Elements_Now();
            }
        }
        xmlHttp.open("post", "server.php"); 
        xmlHttp.send(formData); 
}

Upvotes: 0

John Obiomah
John Obiomah

Reputation: 31

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/[email protected]/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="[email protected]" 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>

Upvotes: 3

vapcguy
vapcguy

Reputation: 7545

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>

Upvotes: 0

Kheersagar patel
Kheersagar patel

Reputation: 523

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>

Upvotes: 12

Rtzoor
Rtzoor

Reputation: 338

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.

Upvotes: 4

Picker
Picker

Reputation: 786

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

Upvotes: 4

Rodrigo Garc&#237;a
Rodrigo Garc&#237;a

Reputation: 1417

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.

Upvotes: 32

Rajinweb
Rajinweb

Reputation: 1179

document.querySelector() behaves similarly to the jQuery.(document).ready() method. When the DOM is ready, the selector returns the object.

I would suggest you call all JS script bottom of the page.

Upvotes: 112

Related Questions