NaN return value from function Javascript || Function Execution Order -


newbie in javascript here, , after hours digging trough other questions i'm not quite sure how explain honest, i'll give best, you'll able me.

html:

<div id='header'> <h1> pastel land </h1> </div>      <div id='container'>          <div id='readycontainer'>               <h3> game start in </h3>             <h1 id='readyseconds'> </h1>          </div>          <div id='shape'> </div>      </div>      <div id='features'>          <button id='start'> start </button>          <button id='stop'> stop </button>          <p id='timebox'></p>         <p id='timeaveragebox'></p>     </div>      <div id='testbox'> </div> 

full script:

document.getelementbyid('start').onclick = function () {          document.getelementbyid('readycontainer').style.display = 'block';         document.getelementbyid('readyseconds').innerhtml = '3'         settimeout(function() {document.getelementbyid('readyseconds').innerhtml = '2'}, 1000);         settimeout(function() {document.getelementbyid('readyseconds').innerhtml = '1'}, 2000);           settimeout(readyalert,3000);         settimeout(displayshape, 3000);           var style = document.getelementbyid('shape').style;          var el = document.getelementbyid('shape');          el.addeventlistener("click", a, false);         el.addeventlistener("click", b, false);          function a() {              style.display = "none";             displayshapedelay(); // calls delay function         }          function b() {               end = new date().gettime();  // saves time when clicked              var time = (end - start)/1000 ; // calculates interval shape creation until click              document.getelementbyid('timebox').innerhtml = time + 's';              return time;          }          document.getelementbyid('testbox').innerhtml = b();           function readyalert() {                 document.getelementbyid('readycontainer').style.display = 'none';          }             function getrandomcolor() {          var hex = ["#96ceb4", "#ffeead", "#ff6f69", "#ffcc5c", "#88db8b0", "#528491"];          var color = hex[math.floor(math.random() * 6)]; // generates integer numbers [0,5], selects indexed item hex          return color;          }            function displayshape () {              var percentages = [];              (var i=0; i<4; i++){ // generates list 4 different random integer values [5,60]                  percentages.push((math.floor(math.random() * 61) + 5));              }              var width = (math.floor(math.random() * 61) + 5); // generates integer numbers [5,60]              var shaperand = math.random()              if (shaperand < 0.3) { // circle                 style.borderradius = "50%";              } else if (shaperand >= 0.3 && shaperand < 0.6) { // random shape                 style.bordertopleftradius = percentages[0] + "%";                 style.borderbottomrightradius = percentages[1] + "%";                 style.bordertoprightradius = percentages[2] + "%";                 style.borderbottomleftradius = percentages[3] + "%";             } else { // square                 style.borderradius = "0%";             }              //general shape styles             style.width = width + "%";             style.height = width + "%";             style.display = "block";             style.backgroundcolor = getrandomcolor();             style.top = percentages[0] + "%";             style.left = percentages[3] + "%";              start = new date().gettime(); // saves time when shape created              console.log(width);             console.log(getrandomcolor());             console.log(shaperand);             console.log(percentages);           }          function displayshapedelay () { // calls main function delay between ]0s,2s[             settimeout(displayshape, math.random() * 2000);         }           document.getelementbyid('stop').onclick = function() {           }      } 

before had this:

my goal return var 'time' global scope, use create array of each value created each click. i've realised not possible anonymous function.

document.getelementbyid('shape').onclick = function() { // calls delay function              style.display = "none";              displayshapedelay();              end = new date().gettime();              time = (end - start)/1000 ;              document.getelementbyid('timebox').innerhtml = time + 's';              return time          } 

so code have :

var shapeclick = document.getelementbyid('shape');          shapeclick.addeventlistener("click", a, false);         shapeclick.addeventlistener("click", b, false);          function a() {              style.display = "none";             displayshapedelay(); // calls delay function         }          function b() {               end = new date().gettime();  // saves time when clicked              var time = (end - start)/1000 ; // calculates interval shape creation until click              document.getelementbyid('timebox').innerhtml = time + 's';              return time;          }          document.getelementbyid('testbox').innerhtml = b(); 

now, there's couple of issues this:

1- can't seem understand why 2 "time divs" assigned values after pressing start button. means function b running, shouldn't running after onclick event?

2- in 'first-round' understand why both values show nan, since there's no value assigned variable "time" yet. after onclick event executes, 'time' value assigned inside 'timebox' works fine, 1 called outside function doesn't. isn't "return time" inside function b, supposed returning value of "time" variable?

thanks in advance!

pastel land

the onclick function serving outer function of whole lot of code execute when start button clicked. of runs every time start button clicked: click start multiple times see problem. .

inside #start.onclick() have

document.getelementbyid('testbox').innerhtml = b(); 

in mainline click handler code: not inside function , runs when start button clicked. since end has not been set yet, result time nan. code inside function b set content of #timebox well.

if run code in strict mode javascript engine tell end has not been declared. should - if requred in global scope.

as aside, fyi, date.now() avoids need create , discard date object , equivalent new date().gettime().

i suggest reworking code move logic of pastel land outside start button click handler, , have click handler call main application code needed contain logic specific start action itself. if want avoid polluting global scope can include code in iife (immediately invoked function expression) serve same scope containment provision click handler providing. kindly, think code in current state presenting x-y problem :-)


the game

a restructured version of pastel land shown below several reasons: you've had time try yourself, of code yours , remainder demonstrates meant suggestion. , it's silly game deserves played!

<!doctype html> <html> <head> <title>pastelland</title> <meta charset="utf-8"> <script>  window.addeventlistener("load", function() // iife {"use strict"     // pastel land      var running = false;     var start = 0;     var end = 0;     var times = []; // calculating average still     var el, style;      function getrandomcolor() {         var hex = ["#96ceb4", "#ffeead", "#ff6f69", "#ffcc5c", "#88db8b0", "#528491"];         var color = hex[math.floor(math.random() * 6)]; // generates integer numbers [0,5], selects indexed item hex         return color;     }      function displayshape () {         var percentages = [];          (var i=0; i<4; i++){ // generates list 4 different random integer values [5,60]             percentages.push((math.floor(math.random() * 61) + 5));         }         var width = (math.floor(math.random() * 61) + 5); // generates integer numbers [5,60]         var shaperand = math.random()          if (shaperand < 0.3) { // circle             style.borderradius = "50%";          } else if (shaperand >= 0.3 && shaperand < 0.6) { // random shape             style.bordertopleftradius = percentages[0] + "%";             style.borderbottomrightradius = percentages[1] + "%";             style.bordertoprightradius = percentages[2] + "%";             style.borderbottomleftradius = percentages[3] + "%";         } else { // square             style.borderradius = "0%";         }          //general shape styles         style.width = width + "px";         style.height = width + "px";         style.position = "absolute"         style.display = "block";         style.backgroundcolor = getrandomcolor();         style.top = percentages[0] + "%";         style.left = percentages[3] + "%";          start = date.now(); // saves time when shape created          console.log(width);         console.log(getrandomcolor());         console.log(shaperand);         console.log(percentages);     }      function displayshapedelay () { // calls main function delay between ]0s,2s[         settimeout(displayshape, math.random() * 2000);     }      function readyalert() {             document.getelementbyid('readycontainer').style.display = 'none';     }      function userfound() {         style.display = "none";         end = date.now();          var time = (end - start)/1000 ; // calculates interval shape creation until click         document.getelementbyid('timebox').innerhtml = time + 's';         displayshapedelay(); // calls delay function         times.push( time); // saves time user took find shape     }      function userstart() {          if( running)             return;         running = true;         document.getelementbyid('readycontainer').style.display = 'block';           document.getelementbyid('readyseconds').innerhtml = '3'         settimeout(function() {document.getelementbyid('readyseconds').innerhtml = '2'}, 1000);         settimeout(function() {document.getelementbyid('readyseconds').innerhtml = '1'}, 2000);         settimeout(readyalert,3000);         settimeout(displayshape, 3000);         times.length = 0;  // reset times array     }      function userstop() {         running = false;         style.display="none"     }     function init() {         el = document.getelementbyid('shape');         style = el.style;         el.addeventlistener("click", userfound, false);         document.getelementbyid('start').onclick=userstart;         document.getelementbyid('stop').onclick=userstop;         }     return init; // window load listener }()); </script> </head> <body> <div id='header'> <h1> pastel land </h1> </div> <div id='container'>     <div id='readycontainer'>         <h3> game start in </h3>         <h1 id='readyseconds'> </h1>     </div>     <div id='shape' style="height:40px;width:40px;"></div> </div> <div id='features'>     <button id='start'> start </button>      <button id='stop'> stop </button>     <p id='timebox'></p>     <p id='timeaveragebox'></p> </div> <div id='testbox'> </div> </body> </html> 

calculation , display of averages , minor changes page presentation remain done (i'm not coding them!). units width , height changed "%" "px" (pixels) , "position: absolute;" added shape.style. functions a , b combined function userfound. code involving "testbox" omitted. iief returns initialization function executed after window load.


notes

userstart , userstop click event handlers defined using named function declarations instead of coding them anonymous functions in parameter lists of calls other functions.

declared function names refer function object created declaration. hence setting value of element's onclick attribute function name works because attribute requires function object value. setting onclick undefined value returned calling 1 of handlers not work.

the start/stop handlers have been registered "click" event listeners, using addeventlistener instead of element onclick values.

the init function not called iife. iife called when the

window.addeventlistener("load", function() { // iife code }() ); 

statement executed in head section of page. function objects declared @ top level within iife created @ time. function returned iife, init, registered listener later execution, after dom elements have been created html body , window load event fires.

if call userstart init after other el , style have been initialized, game start. although userstart called in response clicking start button, still behave same if called other means.


Comments

Popular posts from this blog

html - Styling progress bar with inline style -

java - Oracle Sql developer error: could not install some modules -

How to use autoclose brackets in Jupyter notebook? -