1

I have a JS function called isPortrait, to determine the orientation of a given photo. The problem is, when I call it, it always returns false. However, the alert() is works perfectly, and returns the resolution of the photo. How can I fix it?

function isPortrait(src) {
    var is  = false;
    var img = new Image();
    img.src = src;
    img.onload = function() {
        alert(img.width+"x"+img.height);
        if(img.height>img.width)
        {
            is = true;
        }
    }
    return is;
}

My solution (using a global variable):

window.isportrait = false;
function isPortrait(src) {
    var img = new Image();
    img.src = src;
    img.onload = function() {
        if(img.height>img.width)
        {
            window.isportrait = true;
        }
        else
        {
            window.isportrait = false;
        }
    }
}
1
  • Your question is about JavaScript, and I have answered down. However, using Jquery will make it extremely easier for you to perform what you want. Try to consider it if possible Commented Jul 23, 2014 at 10:31

3 Answers 3

4

Your function will always return false because onload event is called asynchronously, which basically means that the function will return the value of is before the onload function is executed. That's why to make it working it is suggested to use callbacks:

function do_something() {
   // do something
}

function isPortrait(src) {
    var img = new Image();
    img.src = src;
    img.onload = function() {
        if (img.height > img.width) {
            do_something();
        }
    };
}
Sign up to request clarification or add additional context in comments.

4 Comments

Now it returns undefined.
@BalázsVarga You can't return the value from the asynchronous call. In your case onload is not able to return a value back to isPortrait function.
I've solved it with setting up a global variable (window.isportrait), and set its value in the function. Then check it in a timeout (which i already has in my background rotator code).
@BalázsVarga This seems to be a poor implementation to me, since the image loading may take any amount of time. Hence, you need to set interval to constantly check if the value of isportrait is changed, which may be an overkill, when you may simply put all required actions in a callback.
1

the function returns false before the async call is finisshed !!

the best implementation i could reach to is here JSBIN example

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
 <h1 id="heading">? </h1>
</body>
</html>
  • and javasScript code is:

    var is  = false;
    
    function isPortrait(src) {
    
    var img = new Image();
    img.src = src;
     var  here = img.onload = function() {
    
        alert(img.width+"x"+img.height);
        if(img.height>img.width)
        {
            is = true;
    
    
        }
      // it is here at this moment where you can get result of the 
     // awaited async function onload() 
     document.getElementById("heading").innerHTML = "is it Portrait ? " + is;
    
        };
    
    
    
    }
    
    
       isPortrait("http://blogs.smithsonianmag.com/aroundthemall/files/2009/01/npg_portraits_nicholson_jack_2002-244x300.jpg");
    

Edit [ Another better impleentation using the 'setInterval`

     var is  = false;
     var notYetLoaded = true;


   function isPortrait(src){
      tryLoadImage(src);

    var myWaiting = setInterval(function(){
    if(notYetLoaded === false){


     // use the "is" boolean here

     document.getElementById("heading").innerHTML = "is it Portrait ? " + is;
     clearInterval(myWaiting);
     }
     }, 1000);
     }


     function tryLoadImage(src) {

    var img = new Image();
    img.src = src;
     var  here = img.onload = function() {

        alert(img.width+"x"+img.height);
        if(img.height>img.width)
        {
            is = true;


        }
      notYetLoaded = false;
      };



     }


       isPortrait("http://blogs.smithsonianmag.com/aroundthemall/files/2009/01/npg_portraits_nicholson_jack_2002-244x300.jpg");

code here: http://jsbin.com/qodefuhe/1/edit

I hope that helps :)

5 Comments

1. There are no Ajax calls here. 2. This will never work. It may work in your case, as the image was cached in your browser and is already loaded when you run the script.
thank you for the correction it is async not ajax call [i edited it]:P but would you please tell me why it will never work?? i mean why won't load event work when I supply an Img.src??
by the way i tested it after flushing the browser cache and it works !!
This was my bad, I was mislead with your indentation. Of course it will work, as you check for is value inside the onload callback. However, that doesn't make sense for is variable to be defined outside the callback, as it will never be used there.
agree with you, but I put "var is" as a global variable while i was debugging, and I forgot it there lol
0

This is happening because isPortrait() is returning the value of 'is' before the complete execution of the onload function.

You can try out the following, in which you declare the variable 'is' globally and call another function onload and return the value of is from the new function.

var is  = false;
var img = new Image();
function isPortrait(src) {
    img.src = src;
    img.onload = temp(src);
}

function temp(src) {
    is = test(src);
}

function test(src) {
        alert(img.width+"x"+img.height);
        if(img.height>img.width)
        {
            is = true;
        }
        return is;
}

2 Comments

To return the value of is to where?
Yes it is a miss from my side :) In this case we would need one more function to receive the value of 'is'! Editing the answer to show the same, since code looks unintended and cluttered in comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.