Hello me need get variable from function
me return in answer undefined
function etr() {
var img = new Image();
img.onload = paramsImg;
img.src = picFile.result;
function paramsImg() {
return img.height;
};
};
var vvvr = etr();
alert(vvvr);
function etr() {
var img = new Image();
img.onload = paramsImg;
img.src = picFile.result;
function paramsImg() {
return img.height;
};
};
In your function, you mentioned paramsImg before its even loaded, so its not visible to img.onload.
paramsImg is declared simply as function, its not have scope outside the object. You need to use this keyword or mention fn with prototype.
function etr(picFile){
this.paramsImg = function(){
return img.height;
};
var img = new Image();
img.onload = this.paramsImg;
img.src = picFile.result;
}
picfile = {
result: 10
}
var vvvr = new etr(picfile);
alert(vvvr.paramsImg());
Your function etr doesn't return anything. I see that you are trying to return from an event handler for onload, but that only returns from the paramsImg function and not from etr (which has already returned before the image loads). You should wither make etr accept a callback function or return a Promise so that you can alert the images height after the image has loaded. Here is an example with a Promise:
function etr() {
return new Promise( ( resolve, reject ) => {
var img = new Image();
img.onload = _ => resolve(img.height);
img.onerror = reject;
img.src = picFile.result;
} );
};
var picFile = { result: 'https://dummyimage.com/600x1234/000/fff' };
(async function ( ) {
var vvvr = await etr();
alert(vvvr);
})( );
Related
I am working with FileReader and I have come across an issue with the onLoad method of FileReader not being executed synchronously with the rest of the code. Basically I have 2 functions like these:
imageExists(url, callback) {
var img = new Image();
img.onload = function () { callback(true); };
img.onerror = function () { callback(false); };
img.src = url;
}
isImageCorrupt(file): boolean {
var reader = new FileReader();
var isCorrupt = false;
reader.readAsDataURL(file);
reader.onload = (e) => {
this.imageExists(e.target.result, (exists) => {
if (exists) {
isCorrupt = false;
// Image is not corrupt
} else {
isCorrupt = true;
//Image is corrupt
}
});
};
return isCorrupt;
}
The isImageCorrupt() function calls the reader.onLoad which calls the imageExists callback function, which also contains a image onload method.
The problem is that during the execution of the isImageCorrupt() function, the reader.onLoad has not changed the value of isCorrupt yet but the function has returned the value in the last line which is always false.
I want my function to wait for the reader.onLoad to finish its execution before the function returns the value.
maybe something like this?
isImageCorrupt(file): Promise<Boolean> {
return new Promise((resolve) => {
var reader = new FileReader();
reader.onload = (e) => {
var img = new Image();
img.onload = function () {
resolve(false);
};
img.onerror = function () {
resolve(true);
};
img.src = <string>e.target.result;
}
reader.readAsDataURL(file);
});
}
*disclaimer: I did not test it
You could use Promises. The code could be still refactorized using async/await
isImageCorrupt(file): Promise<boolean> {
return new Promise<boolean>((resolve,reject)=>{
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = ()=>{
var img = new Image();
img.src = reader.result;
img.onload = function () {
resolve(false);
};
img.onerror = function () {
resolve(true);
};
}
reader.onerror=()=>{reject(true)}
});
};
isImageCorrupt(yourFile).then((result)=>{/*HERE USE RESULT*/},(error)=>{HERE USE ERROR RESULT})
However you shouldn't return true o false, but resolve if it's ok and reject otherwise, whithout a boolean value in this way
isImageCorrupt(file): Promise<void> {
return new Promise<void>((resolve,reject)=>{
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = ()=>{
var img = new Image();
img.src = reader.result;
img.onload = function () {
resolve();
};
img.onerror = function () {
reject();
};
}
reader.onerror=()=>{reject()}
});
};
isImageCorrupt(yourFile).then(()=>{/*HERE OK*/},()=> {HERE
THERE WAS SOME ERROR/PROBLEM})
This question already has answers here:
Arrow Functions and This [duplicate]
(5 answers)
Closed 3 years ago.
I got this code:
_getWidthAndHeight = (ImageURL) => {
var img = new Image();
img.onload = () => {
alert(JSON.stringify(img));
alert(this.height);
alert(this.width);
};
img.src = ImageURL;
}
It is supposed to load the image in google chrome, and get image height and width. Why the object returns empty?
this is not pointing at what you need in arrow functions
_getWidthAndHeight = (ImageURL) => {
var img = new Image();
img.onload = function() { // now "this" will be what you think it is
console.log(this.height,this.width);
};
img.src = ImageURL;
}
_getWidthAndHeight("https://via.placeholder.com/500x400?text=500x400")
With arrow:
_getWidthAndHeight = (ImageURL) => {
var img = new Image();
img.onload = (e) => { // now you can use e.target
console.log(e.target.height,e.target.width);
};
img.src = ImageURL;
}
_getWidthAndHeight("https://via.placeholder.com/500x400?text=500x400")
The problem is that you're using this inside an ES6 arrow function. It has a different context from classic JS functions. You'll have to use this code for it to work:
_getWidthAndHeight = (ImageURL) => {
var img = new Image();
img.onload = function () {
alert(JSON.stringify(img));
alert(this.height);
alert(this.width);
};
img.src = ImageURL;
}
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
this.color = img_Color.getDominantColor(); //this doesnt work
this.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
this.init();
}
With this example, how can i save those variables as InfoImage variable? I know that using this there will affect Image and not InfoImage...
If I'm understanding you right, the usual answer is to use a variable to refer to this, which init then closes over:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
var infoimg = this; // <===
img.onload = function () {
img_Color.init(img);
infoimg.color = img_Color.getDominantColor(); // <===
infoimg.maxPixels = img_Color.getDominantColorPixels(); // <===
};
img.src = path;
};
}
You can also use Function#bind:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
this.color = img_Color.getDominantColor();
this.maxPixels = img_Color.getDominantColorPixels();
}.bind(this); // <===
img.src = path;
};
}
With ES6, the next version of JavaScript, you'll be able to use an arrow function, because unlike normal functions, arrow functions inherit their this value from the context in which they're defined:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = () => { // <===
img_Color.init(img);
this.color = img_Color.getDominantColor();
this.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
}
You need the this and that pattern:
function InfoImage(path, title) {
var _this = this;
this.init = function(){
var img = new Image();
img.onload = function () {
_this.color = img_Color.getDominantColor();
};
};
};
function InfoImage(path,title){
var self = this;
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
self.color = img_Color.getDominantColor(); //this doesnt work
self.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
this.init();
}
It's that easy. this is a keyword and depends on the function's binded calling context, but it can be stored to a variable just like anything else in JavaScript.
I try to get height/width from some background images, but how to get these values into some variables?
var bgobj = jQuery(this); // assigning the object
var url = bgobj.css('background-image').replace(/url\(|\)$|"/ig, '');
var img = new Image();
img.src = url;
Option 1:
alert('img.width: ' + img.width); // alert: " img.width: 0 "
Probably, the image hasn't loaded. So I try onload:
Option 2:
jQuery(bgimg).on('load', function() {
height = jQuery(bgimg).height();
//alert('height ' + height); //'480px' which is correct!
});
No way to get the value out for further use!? So I try callback:
Option 3:
var imageSize = function(url, callback) {
var img = new Image();
img.onload = function(){
var response = {};
var img = new Image();
img.onload = function() {
var x = img.width;
var y = img.height;
var z = y/x;
response = {width:x,height:y};
if(callback) callback(response);
}
img.src = url;
}
img.onload();
}
var getSize = function(url, callback) {
imageSize(url, function(response) {
var dim = response;
})
callback(dim);
}
var h;
imageSize(img.src, function(response) {
h=response.height;
//alert(h); // 800px (OK))
})
//alert(h); //undefined
//alert(imageSize.height); //undefined
//alert(imageSize.h); //undefined
//alert(imageSize.response.h); //undefined
Still no way to get the value into an ordinary variable.
Where did I go wrong?
You've overcomplicated it, but option 3 is one way to do it.
var imageSize = function(url, callback) {
var img = new Image();
img.onload = function(){
if(callback) callback(img.width,img.height);
}
img.src = url;
}
$(function(){
var url = $('#foo').css('background-image').replace(/url\(|\)$|"/ig, '');
imageSize(url,function(w,h){
alert("width=" + w + ", height=" + h);
})
});
#foo{
background-image:url(http://lorempixel.com/100/100/)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">test</div>
The thing to remember is that the method imageSize is asynchronous, so you must pass it a callback which will be called when the image has loaded. You cant have another method where you treat it as a synchronous call, that just wont work.
Objekt.prototype.loadImg = function(pImg){
if(pImg!=null){
this.imgLoaded=false;
this.img = null;
this.img = new Image();
this.img.src = pImg;
this.img.onload = function(){
alert("!");
this.autoSize();
this.imgLoaded=true;
};
}
}
My Problem is that "this" is invalid in the "onload = function()"-function!
alert("!"); is executed, but not the Objekt.prototype.autoSize()-function for example!
What do I have to do to call my "class-intern"-functions (e.g. autoSize) ???
That's because the onload function isn't called with your objekt as receiver. So this, inside this callback, isn't the desired object.
You can do this to transmit this to the onload callback :
Objekt.prototype.loadImg = function(pImg){
if(pImg!=null){
this.imgLoaded=false;
this.img = null;
this.img = new Image();
this.img.src = pImg;
var _this = this;
this.img.onload = function(){
alert("!");
_this.autoSize();
_this.imgLoaded=true;
};
}
}