Cannot Access A Value That Was Set Inside of AddEventListener


#1

I set a value inside of a function in AddEventListener then I tried to console log it outside of the function but it is not working. Please click this link https://jsfiddle.net/jQing/s1ykunqb/10 to see my script.

When you click on any of the text on the screen, the outerHTML of element associated with the clicked text is supposed to be logged. Everything works if and only if console log is executed inside of AddEventListener. However, I want to be able to access any value set inside of AddEventListener from outside.


#2

I see two possible problems.

  • querySelector (vs querySelectorAll) gets only the first element it matches
  • the “star” wildcard selector is not selecting the element you need


#3

You want the message to be logged when you click the page. That means that you need to have the console.log statement inside the event listener.

The value of the variable is being updated and you can work with it outside of the event listener (the variable is global, after all), but you’ll need to call a function to do something with the variable from within the listener.

Something like this:

function myFunction(outerHTML){
  console.log("You clicked: " + outerHTML);
}

document.querySelector('body').addEventListener("click", function(e){
  myFunction(e.target.outerHTML); 
});

#4

Hi Pullo,
I don’t understand why I must “call a function to do something with the variable from within the listener”.

Since the variable is global as you say, shouldn’t I be able to update its value in the listener then access its value without having to first put it in a function and then invoke the function from inside the listener?


#5

On the jsfiddle example, your load-type is set to be on load, which contains all of your code inside of an onload function.

Change that to be no wrap bottom of body, and you can then easily globally access the variables.


#6

Yeah, but once you update its value, how do you intend to access that value from elsewhere?

var currentlySelectedObj;
var elements = document.querySelector("*");
elements.addEventListener("click", function(e){ 
  currentlySelectedObj = e.target.outerHTML;      
});
console.log(currentlySelectedObj);
// ^^^ This will run only once, regardless of what the user clicks on

Out of the box, JavaScript isn’t reactive. When you update a variable’s value, other pieces of code that rely on that variable will be not be re-run. You’d need to implement that functionality yourself.

In the above example, the console.log statement will be run only once when the script is parsed. If you want it to be re-run when the user clicks on something, you’d need to do it as I suggested.


#7

Hi Pullo,
Thanks for replying. All I’m trying to do is set the global variable to a value when the user clicks on an element. Then I want to have access to the value of that variable at a later time.

Using your method how can I update a global variable, add it to an array, and then access it at a later time? When using your solution it appears that I can only access the variable inside of the myFunction method when the click happens but that is not what I intended.


#8

How are you intending to do that? You can access the variable from anywhere in your program, but as the value of the variable is set once a user clicks on an element, you’ll have to access it in reaction to a further event.

Here’s a simple example to demonstrate:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Globals</title>
</head>
<body>

  <button class="setValue">Button 1</button>
  <button class="setValue">Button 2</button>
  <button class="setValue">Button 3</button>

  <p>
    <button class="alertValue">Alert value of last pressed button</button>
  </p>

  <script>
    let myGlobal;
    const [...setButtons] = document.querySelectorAll('.setValue');
    const alertValueButton = document.querySelector('.alertValue');

    setButtons.forEach((button) => {
      button.addEventListener('click', (e) =>{
        myGlobal = e.target.innerText;
      });
    });

    alertValueButton.addEventListener('click', () => {
      alert(`The value of myGlobal is ${myGlobal}`);
    });
  </script>
</body>
</html>

#9

From what he said before, I believe that he wants to access it afterwards from the console.


#10

I don’t get it. That code will always log undefined and the updated value won’t be accessible after the event handler fires, unless it is accessed from another (or the same) event handler.


#11

@oangodd - am I correct that you want to:

  • click on an element
  • have the event assign to currentlySelectedObj and log it
  • and also access that currentlySelectedObj variable from the console?

#12

I suppose you could do a settimeout to periodically log whatever the value was. But it makes more sense to me to log the value when it changes. It would be more efficient than a settimeout and there wouldn’t be a risk of not logging a value that got missed because the settimeout was waiting.


#13

Investigating code variables from the console seems to be what this is all about.

With online scripting environments such as jsfiddle or codepen, that’s not easy to achieve.
With single html pages, that’s easy to achieve.


#14

That’s not how I read it. I guess we’ll just have to wait for the OP to let us know.


#15

Hi,
Thank you for replying. My example code in jsfiddle is not clear as to what I’m trying to accomplish. So please let me explain. Basically I would like to be able select any element on the screen using outerHTML and put it in a variable, an array, etc. and store it for later use.

I think I can access the variable inside of another event.


#16

If you are using jQuery then any variable declared with a var statement is not global it is within a jQuery function or variable. To make the variable truely global, declare it without the var.


#17

The problem is that the console.log command runs as soon as the script loads.
Sometime later the event fires and sets the value of the variable.
But the console.log command has already run and will not run again until the whole script is reloaded.


#18

Eh?

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
  var global = "This is global";
  $("body").css("background", "red");
</script>

Unless I’m missing something, one doesn’t have anything to do with the other.