0

I have a html file and has a div containing a image src

<div id="imageoutput"><img id="imgoutput" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA"></div>

I ignored some of the Base64 data here because it is too long, just for your convenience to read the code.

So I have a javascript file included in the HTML.

document.onload = function () {
    var existingData = document.getElementById('imgoutput').src;
}

I wanna get the src for this image when the page is loaded, but seems like when I

console.log(existingData)

it will give me this error all the time

Uncaught ReferenceError: existingData is not defined

but if I do

console.log(document.getElementById('imgoutput').src)

It will give me the image src

EDIT

If I did this all wrong, what is the possible way to get the image src out and store it in a variable?

lilixiaocc
  • 333
  • 1
  • 15
  • 1
    where are you adding that console.log(), is it inside your onload function? – StackOverMySoul Oct 04 '16 at 15:36
  • is existingData in the same scope ? – Béranger Oct 04 '16 at 15:36
  • 1
    And you did *of course* place that console.log inside the `onload()` function? – adeneo Oct 04 '16 at 15:36
  • I did the console.log in chrome's developer tool – lilixiaocc Oct 04 '16 at 15:40
  • Define `var existingData` outside of the onload function, and then set it inside of the function. This way the variable is global – Spencer May Oct 04 '16 at 15:41
  • @War10ck it is that simple. Defining the global variable is asynchronous just like the DOM being ready...no matter what, the author will need to run his function after these events have been fired. All in one `async` module. – Spencer May Oct 04 '16 at 15:50
  • I tried put a global `var existingData` before the `document.onload`, but have the same problem – lilixiaocc Oct 04 '16 at 15:51
  • @War10ck, I will try this answer! – lilixiaocc Oct 04 '16 at 16:01
  • 1
    *"If I did this all wrong, what is the possible way to get the image src out and store it in a variable?"* You did that correctly (although I wouldn't use `onload`, I'd just put the script at the end of the document; and I'm not 100% certain `document.onload` is reliable cross-browser vs. `window.onload`). The real question is where and how you want to *use* that variable (and where and how you *can* use it). – T.J. Crowder Oct 04 '16 at 16:15

3 Answers3

4

If you did console.log(existingData) just by going to your page, opening dev tools, and typing it, then the reason for the error is simple: It will be looking for a global variable, and existingData isn't a global, you've defined it as local within your onload function.

If you put a breakpoint in your onload function in dev tools, reload the page so that it stops on that breakpoint, and run the console.log, at that point the console will have access to the things in scope for the code where the breakpoint is and you'll see the value.

If you actually write the console.log in your onload function — more generally, if you only use existingData within that function — it'll be defined and (after the assignment) have a value.

Depending on how/where you want to use it, the answers to this question may be useful as well: How do I return the response from an asynchronous call?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I did the first one, and then I tried to put the variable before the `onload` function, but still have the same issue. – lilixiaocc Oct 04 '16 at 15:52
  • quick note: another way to make this work is to set the variable with `window.existingData = ...` that will put it in the global scope so you can reach it from the console without adding any breakpoints. – Robert Parham Oct 04 '16 at 15:59
  • 1
    @RobertParham This is true but the `console.log` statement would still need to occur after the `async` onload function completes. – War10ck Oct 04 '16 at 16:00
  • @War10ck - The callback would need to be called first, but it's not async as far as I can tell. It's just a callback. JS is single threaded. – Robert Parham Oct 04 '16 at 16:15
0

As others have mentioned in the comments/answers already posted, the problem with your approach is both scope and timing. JavaScript is function scoped, meaning the variable existingData will not be available outside of the window.onload function scope. You can get around this by elevating the variable to the global scope by moving the var existingData; declaration outside of the function.

The second problem is timing. The onload function is an async operation meaning a simple console.log outside of the window.onload function declaration will still yield a result of undefined because the async operation has not completed. To get around this, you can use the native implementation of Promise and the provided .then() callback to accomplish what you're looking for.

DEMO:

var existingData; 

function load(){
    return new Promise(function(resolve) {
        if (document.readyState === "complete") {
            existingData = document.querySelectorAll("img")[0].src;
            return resolve();
        }
        document.addEventListener("DOMContentLoaded", function () {
            existingData = document.querySelectorAll("img")[0].src;
            return resolve();
        }, false);
    });
}

load().then(function () {
    alert(existingData);
});
<img src="http://stackexchange.com/content/img/hero/vote.png" />

NOTE: Promises are not supported in IE so you may need to use a library that abstracts this functionality safely and provides a fallback for browsers with non-native support.

War10ck
  • 12,387
  • 7
  • 41
  • 54
-1

Probably the error comes from somewhere else, because you're using the existingData variable but the variable is set in the onload scope, so is not reachable.

You should put the var declaration on the root:

var existingData
document.onload = function () {
    existingData = document.getElementById('imgoutput').src;
}

EDIT

This allows you to reach the variable, you should call your method inside the onload:

   var existingData
    document.onload = function () {
        existingData = document.getElementById('imgoutput').src;
        callmMyMethod();
    }
Roberto Lonardi
  • 569
  • 2
  • 10
  • 2
    How does that help, it would still be `undefined` seeing as `onload` is async – adeneo Oct 04 '16 at 15:37
  • Edited, is async but you need to change the scope of the variable anyway, or it never be see by any function outside it. – Roberto Lonardi Oct 04 '16 at 15:43
  • What is `callmMyMethod()`? This makes no sense... – War10ck Oct 04 '16 at 15:45
  • Cause you have to call your function inside the onload, the error is not thrown inside the onload but somewhere else. He didn't specify where the function is called so i just set a placeHolder name, of course is not the real method. – Roberto Lonardi Oct 04 '16 at 15:51