1

I have some javascript code to change an element of text within a webpage to a random color. I'm new to this, but the code does work. Every three seconds the text color of a specific element changes to a new random color.

const handler = function() {
    const genselector = "div.tw-c-text-alt-2.tw-flex > span";
    const genel = document.querySelector(genselector);
    var randcolor = Math.floor(Math.random()*16777215).toString(16);
    genel.style.color = "#" + randcolor;
}
setInterval(handler, 3000);

If I move both const variables outside the function the program no longer works, which makes sense because the variables are defined outside of the function and they are not global variables.

const genselector = "div.tw-c-text-alt-2.tw-flex > span";
const genel = document.querySelector(genselector);

const handler = function() {
    const specel = document.querySelector(specselector);    
    var randcolor = Math.floor(Math.random()*16777215).toString(16);
    genel.style.color = "#" + randcolor;
}
setInterval(handler, 3000);

However if I move only the first variable outside of the function the code still works, even though I don't think it should.

const genselector = "div.tw-c-text-alt-2.tw-flex > span";

const handler = function() {
    const genel = document.querySelector(genselector);
    var randcolor = Math.floor(Math.random()*16777215).toString(16);
    genel.style.color = "#" + randcolor;
}
setInterval(handler, 3000);

How is the genselector variable being accessed by the function when it was defined outside the function, and for whatever is causing it to work why doesn't the same thing happen when I move out the genel variable.

  • Most likely the element doesn't exist at the time you query for it . The variable scope is not the issue. – charlietfl Apr 04 '21 at 23:03
  • Have a google for `block scope` and `scope` in general. And lastly google `function hoisting` in js for general answers here. I assume the issue here is the time your running your js – Dominik Apr 04 '21 at 23:03
  • 1
    See [What is the scope of variables in JavaScript?](/q/500431/4642212). Variables defined outside of a function are still accessible inside a function; this is not the reason your script stops working. Use the [browser console (dev tools)](https://webmasters.stackexchange.com/q/8525) (hit `F12`) and read any errors. Is `document.querySelector(genselector) === null`? Is your ` – Sebastian Simon Apr 04 '21 at 23:03
  • Also in your case that didn't work, if you don't have specselector defined anywhere then that line will also prevent the code from running. – kaladin_storm Apr 04 '21 at 23:17

2 Answers2

1

When the web browser executes your javascript the DOM and elements of the web page are not ready yet. That means document.querySelector(genselector) can't find the element and genel is null. This is not a problem in scenarios 1 and 3 because 3 seconds later the handler function is executed again. But in scenario 2 the value of genel is being assigned only once.

Egan Wolf
  • 3,533
  • 1
  • 14
  • 29
1

So if this is (almost) the only JS code you have then this is normal behavior. Why does your code crash with the second example is because if you don't use an event listener your code is executed before your DOM is loaded. So basically you are trying to do an docuement.queryselector on something that is not yet rendered. With the last example you do the query when executing your function and this is probably a point where all your HTML elements are created so the query will find the element.

Now extra for how to solve this. You can set an event listener on your document that waits for the moment all of your HTML code is loaded:

window.addEventListener('load', (event) => {
  <<< Add your code here >>> 
});

And then it won't trow an error when using the second example of your code.

Seppe Mariën
  • 355
  • 1
  • 13