1

I created a div (variable "box") using document.createElement inside of a function. I then need to use that variable inside other functions. Is it possible to access this variable outside the function or assign it globaly after it has been created?

My code is supposed to do 3 things (its the etch a sketch project for Odin Project).

  • generate a grid of 16x16 boxes.
  • let user input a number of boxes and create new grid based off of the users input.
  • on mouseOver manipulate the color of the boxes in different ways (labeled "black" "color" and "psych".

Things I have tried (but failed at).

  • put all functions inside the "initGrid" function. This reguired me to move the eventListeners for buttons inside as well and then they would not work.

  • use container.childNodes to try and assign a variable after those nodes where created.

  • adding another "let box = document.createElement("div");" outside of the variable in an attempt to name it globaly.

  • I dont know how many other things I have tried, I've lost count.

Please note that the only button functionality I am trying to get to work at this point is the "color" option. I have the others working but they are in other html files.

Any help would be amazing, I am lost with it. Let me know if I can clarify on anything.

* {
 padding: 0;
 margin: 0;
}

header {
 text-align: center;
 background-color: maroon;
 padding:10px;
 margin: 10px 10px 20px 10px;
}

.title {
 font-family: sans-serif;
 font-size: 50px;
 color: white;
}

#wrapper{
 text-align: center;
 margin: 0px 0px 15px 0px;
}

#btn{
 color:red;
}

#container{
 margin:0 auto;
 display: flex;
    justify-content: center;
    flex-wrap: wrap;
 max-width:700px;
 max-height:700px;
 min-width: 700px;
 min-height: 700px;
 padding:10px;
 border:1px solid black;
}

.boxes{
 background-color: red;
 border: 0.125px solid white;
 box-sizing: border-box;
}
<!DOCTYPE html>
<html>

<head>
 <title>sketch</title>
 <link href="style.css" rel="stylesheet" type="text/css">
</head>

<body>
 <header>
  <h1 class="title">Etch-A-Sketch</h1>
 </header>
 <div id="wrapper">
  <button id="btn">Reset Grid</button>
    </div>
   <div id=btns>
    <button id="black">Paint it Black</button>
    <button id="color">Rainbow</button>
    <button id="psych">Psychedelic Disco</button>
   </div>
 <div id="container">
 </div>
 <div id="prompt">
 </div>


 <script type="text/javascript">
  const container = document.getElementById("container");
  const rstbtn = document.getElementById("btn");
  const btns = document.getElementById("btns");
  const black = document.getElementById("black");
  const color = document.getElementById("color");
  const psych = document.getElementById("psych");
  let box = document.createElement("div");

  black.addEventListener("click",function(){
   option("black");
  });
  color.addEventListener("click",function(){
   option("color");
  });
  psych.addEventListener("click",function(){
   option("psych");
  }); 


  initGrid(16);

  function initGrid(num){
   for (let i=0; i<num; i++){
    for (let j=0; j<num; j++){

     let box = document.createElement("div");
            let boxSize = (690/num) + "px";
            box.style.height = boxSize;
            box.style.width = boxSize;
     box.classList.add("boxes");
     container.appendChild(box);

     box.addEventListener ("mouseover",function(){
     console.log("hover, hover, hover, hover");
     });
    }
   } 
  };


   function option(input){
    if (input == "color"){
     console.log("color picked is " + rainbow())
     box.style.backgroundColor = rainbow()
    }else if (input == "psych"){
     console.log("psych")
    }else{
     console.log("black")
    }
   };


  rstbtn.addEventListener("click", function(){
   let newNum = window.prompt ("Enter how many tiles you would like the new grid to be.", "16");
   container.innerHTML="";
   initGrid(newNum);

  });


  //color function
  function rainbow() {
   let randomNum = Math.floor(Math.random() * 10);
   if (randomNum == 0){
    return "yellow";
   }else if(randomNum == 1){
    return "orange";
   }else if(randomNum == 2){
    return "red";
   }else if(randomNum == 3){
    return "maroon";
   }else if(randomNum == 4){
    return "blue";
   }else if(randomNum == 5){
    return "indigo";
   }else if(randomNum == 6){
    return "pink";
   }else if(randomNum == 7){
    return "purple";
   }else if(randomNum == 8){
    return "green";
   }else if(randomNum == 9){
    return "lime";
   }else{
    return "black";
   }
  };
   
 </script>
   

</body>

</html>
cнŝdk
  • 31,391
  • 7
  • 56
  • 78

2 Answers2

2

Problem:

Your actual problem is that you are declaring box twice, one globally and another inside the function, so the first declaration will be hoisted because of the one in the function.

In your actual code, just remove let box = document.createElement("div"); from the function, and it will be accessed as a global varaible inside the function.

Demo:

This is how should be your final code:

const container = document.getElementById("container");
const rstbtn = document.getElementById("btn");
const btns = document.getElementById("btns");
const black = document.getElementById("black");
const color = document.getElementById("color");
const psych = document.getElementById("psych");
let box = document.createElement("div");

black.addEventListener("click", function() {
  option("black");
});
color.addEventListener("click", function() {
  option("color");
});
psych.addEventListener("click", function() {
  option("psych");
});


initGrid(16);

function initGrid(num) {
  for (let i = 0; i < num; i++) {
    for (let j = 0; j < num; j++) {

      let boxSize = (690 / num) + "px";
      box.style.height = boxSize;
      box.style.width = boxSize;
      box.classList.add("boxes");
      container.appendChild(box);

      box.addEventListener("mouseover", function() {
        console.log("hover, hover, hover, hover");
      });
    }
  }
};


function option(input) {
  if (input == "color") {
    console.log("color picked is " + rainbow())
    box.style.backgroundColor = rainbow()
  } else if (input == "psych") {
    console.log("psych")
  } else {
    console.log("black")
  }
};


rstbtn.addEventListener("click", function() {
  let newNum = window.prompt("Enter how many tiles you would like the new grid to be.", "16");
  container.innerHTML = "";
  initGrid(newNum);

});


//color function
function rainbow() {
  let randomNum = Math.floor(Math.random() * 10);
  if (randomNum == 0) {
    return "yellow";
  } else if (randomNum == 1) {
    return "orange";
  } else if (randomNum == 2) {
    return "red";
  } else if (randomNum == 3) {
    return "maroon";
  } else if (randomNum == 4) {
    return "blue";
  } else if (randomNum == 5) {
    return "indigo";
  } else if (randomNum == 6) {
    return "pink";
  } else if (randomNum == 7) {
    return "purple";
  } else if (randomNum == 8) {
    return "green";
  } else if (randomNum == 9) {
    return "lime";
  } else {
    return "black";
  }
};

Is it possible to access this variable outside the function or assign it globaly after it has been created?

Yes, of course it's possible, in fact there's a big difference between declaration and initialization, what you need to do is to declare it globally outside of your functions and initialize it in the function.

Declare it globally like this:

let box;

Then initialize it inside your function

box = document.createElement("div");
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • Thanks for clarifying on declaration vs. initialization of a variable. That helped me understand what is going on. Your first answer (with code snippet) breaks the function from generating the grid in the first place so unfortunately that wont work. However, the second part of your answer about declaring it outside the function then initializing it inside seems to work a little better and will give me something o work with. Thanks. – CaptainSensible Oct 30 '18 at 20:21
  • @CaptainSensible You are welcome, glad it helps. It's the same thing in both suggestion, if you post what's going wrong with the first code, may be we can help. – cнŝdk Oct 30 '18 at 20:33
  • 1
    Hi thanks, yeah its just that removing anything in regards to "let box = document.createElement("div"); from the initGrid function stops it from generating the grid that it was designed to do. If I declare the "box" variable outside of the function with "let box;" then inside the function have "box = document.createElement("div");" it still works fine. I think I was just confused with your initial statement. If I hit another wall I will come back but for now I kinda want to see if I can fumble through it on my own. Thanks again for your help! – CaptainSensible Oct 31 '18 at 15:37
1

Create the variable outside every function to make it global (use var or let) and don't assign any data to it, then use it inside any function. Example:

let tokenSoundTrack;

function sound() {
tokenSoundTrack = 4;
}

function sound2() {
tokenSoundTrack = 2;
}
XaelGa
  • 140
  • 2
  • 10
  • Thanks for the response. I have updated my code and it has helped me get a little closer to the finish line with this. Thanks again! – CaptainSensible Oct 30 '18 at 20:25