Reputation: 4469
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
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
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
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
Reputation: 523
file.js
const heading1 = document.querySelector(".heading1");
console.log(heading1);
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>
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
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
Reputation: 786
I suggest writing your <script type="text/javascript" src="your js file"></script>
in body, before the closing tag
Upvotes: 4
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
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