Cannot read property 'complete' of null - complete - javascript

I would like to get this effect working on my webpage.
But I already tried this multiple times and failed every time. So, this is the reason why I am going to try it first on a local level. I copied everything you can see on the codepen.io webpage and replaced the both images with my pictures. Further, I added the id id="coverart" to the img and thats it.
But I get an error on this:
if (image.complete) {
The reason for it is:
Cannot read property 'complete' of null
But if I type this in my console:
document.getElementById('coverart');
I get the element back:
<img id="coverart" src="https://gamekeys-shop.de/wp-content/uploads/2017/01/coverart.png">
So, it cannot be null... What could be the reason for it and how can I fix it?
Here you can download the little html, css and js files.
EDIT:
If you insert alert(image), you will get null. If you replace this
if (image.complete) {
start();
} else {
image.onload = start;
}
with this
image.onload = start;
You will get the same null error... Why do I get null... It cannot be null?

There are few possible ways to improve it:
1) Just put your javascript file after the img tag.
2) Or run you code only when document will be loaded.

You can put your jquery definition onto bottom of body tag and use jquery $(document).ready() event like following.
$(document).ready(function(){
var image = document.getElementById("coverart");
if(image.complete){
console.log("loaded");
}
})
<img id="coverart" src="http://via.placeholder.com/350x150"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Since there is no need to wrap your code within a $(document).ready(function(){...}); or $(function(){...}); on codepen.So try doing that. You need jQuery to do that. So just add
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">
to your HTML head.
$(document).ready(function(){
var image = document.querySelector('img');
var imageCanvas = document.createElement('canvas');
var imageCanvasContext = imageCanvas.getContext('2d');
...
imageCanvasContext.drawImage(image, 0, 0, width, height);
imageCanvasContext.globalCompositeOperation = 'destination-in';
imageCanvasContext.drawImage(lineCanvas, 0, 0);
}
});
Tried that for myself on localhost and it's working fine

Related

Why my var is null and the code doesn't work

I'm starting with the basics in JS and I try to make my first event, change the image if it clicked but it's not working, where's the prob?
let myImage = document.querySelector('img');
myImage.onclick = function() {
let mySrc = myImage.getAttribute('src');
if(mySrc === 'images/coding_icon.png') {
myImage.setAttribute ('src','images/coding2.png');
} else {
myImage.setAttribute ('src','images/coding_icon.png');
}
}
My var myImage return NULL and nothing happen when I click on my image. It seems that the doc...selector don't select the first occur of img. Sorry if I did something wrong with the post, it's my first time posting here.
Thanks
You are probably using querySelector on img before it really loaded into DOM.
Possible solutions:
1) move your script in the body tag after the img tag declaration.
2) use code on event of other tags, for e.g. on a button click
3) you can put a timeout surrounding script so that it run delayed and DOM can be loaded meanwhile

Jquery and canvas code not working on same external file

I have been mucking about with a little bit coding using jquery and canvas (not together).
I have an external javascript file and in it contains;
$(document).ready(function() {
/*
NAME CHOOSER
*/
var carl = ['Sha', 'Shads', 'Cai', 'Moon', 'Sun', 'Staffy',];
var rosie = ['Mum',];
var prev;
$('button').click(function() {
prev = $('h2').text();
$('h2').empty().text(carl[Math.floor(Math.random() * carl.length)] + rosie[Math.floor(Math.random() * rosie.length)]).after('<p>' + prev + '</p>');
});
});
I also have some inline javascript which is for the canvas element;
<script>
var canvas = document.getElementById('draw');
if(canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 800, 500);
}
</script>
When separated by using inline javascript for the canvas and an external file for the jquery everything works fine and as expected.
When adding the inline canvas javascript to the external file the canvas element is not working but the jquery is. The javascript is loaded after the canvas element as my external javascript is linked just before the closing body tag and furthermore if I remove all jquery from the external file the canvas element begins to work again.
Why is this?
Thanks
EDIT
I have also now tried putting the canvas code inside jquerys document ready function and outside of it and it is still not working. I have wrapped the canvas code in an anonymous function still to no avail and have even tried selecting the canvas element with jquery itself like below;
var canvas = $('canvas')[0];
But it still doesn't want to know. Putting the canvas code before all the jquery then the canvas code executes but the jquery doesn't, I really am baffled! It doesn't bother me keeping it seperate but I would like to know why it is happening.
Thanks again.
This simple problems could be noted if you use the Browser Console. That's it! You can open the console pressing Ctrl+Shift+J:
In home page:
Error: Uncaught ReferenceError: $ is not defined
Solution: Link jQuery in your source
In namechooser page:
Error: Uncaught TypeError: Cannot read property 'getContext' of null
The problem:
You are trying to manipulate a div as it was a canvas, and you can't get the context of a div element. So this is your HTML:
<div id="wrap">
<h1>PORTFOLIO PROJECT :)</h1>
<button>Click here to generate a company name!</button>
</div>
Solution:
Change <div> for <canvas>
How to avoid future problems like this?
Use the browser console, that's it!
Ok, if I combine the code you have, above, it should look something like this: (see my jsFiddle for full context : http://jsfiddle.net/mori57/TqamB/ )
$(document).ready(function () {
/*
NAME CHOOSER
*/
var carl = ['Sha', 'Shads', 'Cai', 'Moon', 'Sun', 'Staffy'];
var rosie = ['Mum'];
var prev;
$('button').click(function () {
prev = $('h2').text();
$('h2').empty().text(carl[Math.floor(Math.random() * carl.length)] + rosie[Math.floor(Math.random() * rosie.length)]).after('<p>' + prev + '</p>');
});
var canvas = document.getElementById('draw');
if(canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 800, 500);
}
});
And, running within the context of jsFiddle, this works perfectly.
So, either you're not combining the two scripts properly (putting the canvas outside the document-ready block, for example, or somehow missing a closing brace), or there's something else amiss in your script file or markup.

Javascript slowly "flush" DOM Tree

I have really strange problem. I'm trying to get width and height of an image using following way:
Create a image tag and add .src to it.
add this image tag to document.body.
making this image tag visible (display:inline).
getting .offsetWidth and .offsetHeight of element.
hidding image tag(display:none);
all this is done using JS and it all work really well on my localhost, but when I uploaded a site to my client hosting provider I was amazed. offsetWidth and .offsetHeight was 0 in step 4. Why do that happen? I think that I need some kind of "flush" after step 3 before step 4, but I'm not exactly sure. Any suggestions ? Thank you.
You have to wait for the image to actually load over the network. You don't need to add the thing to the DOM either:
var img = new Image();
img.onload = function() {
handleImageSize(this.width, this.height);
};
img.src = "http://whatever.com/your/img.jpg";
Here, "handleImageSize" would be a function you write to do whatever it is you need to do with the image dimensions.
This was probably caused by the image not being loaded yet. Try something like this:
img.onload = function() {
// get the offsetWidth and offsetHeight
}
As other answers suggest, is due to the image not being fully loaded by the DOM. This was working fine on your local server as I suspect you were loading images locally, meaning they were almost instantaneous; however after moving them to the server there is a slight delay. It's an easily overlooked problem, that is easily fixed.
Other answers will do the trick; but here's the jQuery version for sake of argument
var img = $('<img>', {
src: 'http://dummyimage.com/150/000/fff.gif'
}).one('load', function() {
var offsets = $(this).offset();
});
$('body').append(img);
jsFiddle

How to get the true image height using JQuery?

I want to load html , and then get the true image height.
$("#cover").html(stuff); //this has the image inside it
$(function(){
console.log($("#cover img").height()); //sometimes it's 0
});
For some reason, height is sometimes 0. Could it be because the image hasn't been fully loaded yet, and JQuery sees it as 0? If so, how do I overcome this? Is there a callback or something when the image is loaded?
You can use the .load() method of jQuery
$('#cover').html(stuff);
$('#cover img').load(function () {
console.log($(this).height());
};
Why do the console.log inside an anonymous function? Have you tried this?
$("#cover").html(stuff); //this has the image inside it
console.log($("#cover img").height());
//locate the image(s)
$("#cover img").each(function(){
//Build a new Image Object outside the DOM
//that way, CSS won't affect it
var img = new Image();
//add a callback when loaded
img.onload = function(){
//your width and height
//img.width
//img.height
}
//use the image src to load
//use attr() to resolve path issues across browsers
img.src = $(this).attr('src');
});
try to using load method method that we can take advantage of to make this work the way we want it too.
The problem we have right now is that, in the Webkit browsers, the jQuery code runs when the DOM is ready and the DOM is ready before the image has been loaded. So the code runs but since there’s no image to get a width of, we get 0 for the image’s width. We can use the load method to make the code wait until the window has loaded entirely before it runs.
$(window).load(function() {
console.log($("#cover img").height());
});
try using attr() to get the height:-
$("#yourElemengtID").attr('height')
Here is a piece of small code i used before hope this will help you
On my displayed image when mouse is in call this function
function MouseIn()
{
var src;
//to get original image size
var img =$(this);// displayed image
var theImage = new Image();// create a cache image
var imgsource =img.attr("src");// take the src of displayed image
theImage.src = imgsource;// give cached image the source of displayed image
var original_height = theImage.height// take height of image from the source
var original_width = theImage.width;//take width of image from the source
// to get the displayed image size
var Image_displaysize_width= img.width();
var Image_displaysize_height= img.height();
}
Don't you mean to do something like this?
jQuery("#myImg")[0].naturalHeight
better still don't use overhead of jQuery when possible.
document.getElementById('myImg').naturalHeight

Image width traces zero with onload when cached

I'm building a Javascript lightbox and I'm trying to adjust the size once the image has loaded. I'm using the code below, which works fine - it outputs the correct width once loaded.
My problem:
When I refresh, it will load the image instantly from the cache, and it seems to bypass the load. I get an instant zero for the width. Why does this happen?
My code:
var oImage = new Image();
oImage.src = 'http://mydomain.com/image.png';
container.html(oImage);
oImage.onload = function(){
alert(this.width);
}
** Update **
#Alex: This is the code I've tried with your plugin, I assume I'm probably doing something wrong. I'd be eager to get this working because your plugin looks quite good.
container.waitForImages(function() {
var cWidth = $(this).width();
alert("width: "+cWidth); // returns 0 - works first time but not cached
});
// Adding the image to the container for preload
container.html('<img src="mygraphic.png" />');
You need to do a few things...
Check the complete property of the img element.
Attach the load event before setting the src property.
Also, I found creating a new Image and assigning the src there is the best way to determine if the image has loaded or not.
You may want to switch the .html() and the .onload() calls.
If the image is loading from cache, I'm imagining that the .html() call completes before the script has had a chance to attach a function handler to the image's onload event. Therefore, effectively bypassing the load event itself (as the image has already loaded).
If it's still downloading the image (i.e. not cached), there will be more than enough time to call the .onload attach before the image completely finishes rendering.
While you're at it, you may want to do this the jQuery way, just so you're attaching events more similarly to DOM2 than DOM0.
var image = $('<img/>', {
src : 'http://mydomain.com/image.png'
}).load(function () {
alert(this.width);
})
// maybe clear container before if you want
.appendTo(container);
If we're going to have to set the src after the onload, we might as well do this instead:
var image = $('<img/>')
.load(function () {
alert(this.width);
})
.attr('src','http://mydomain.com/image.png')
.appendTo(container)
;
Hopefully that works cleanly.
This answer JavaScript: Know when an image is fully loaded suggests that you should set onload before setting src

Categories

Resources