Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The use of function statements in JavaScript is discouraged. Check out <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope" rel="nofollow">Mozilla's page on function scope</a> which has a great section on function statements vs. function expressions, and states: </p> <blockquote> <p>Functions can be conditionally defined using either //function statements// (an allowed extension to the ECMA-262 Edition 3 standard) or the Function constructor. Please note that such function statements are no longer allowed in ES5 strict. Additionally, this feature does not work consistently cross-browser, so you should not rely on it.</p> </blockquote> <p>The fact that you are seeing differences between browsers with this code is not surprising.</p> <p>Try </p> <pre><code>var tile1 = function () { ... } </code></pre> <p>While this should work for you here, it does so only because variable definitions with <code>var</code> are hoisted. As JavaScript evolves and we start using <code>let</code> instead of <code>var</code>, your use of <code>tile1</code> in the <code>setInterval</code> call outside the loop in which <code>tile1</code> is defined won't work.</p> <p>One of the problems that can occur is that when you use <code>i</code> inside the inner function, you are <strong>always</strong> referring to the single instance of <code>i</code> in the outer scope (the loop counter), whose value is always equal to <code>index</code>. (EDIT: I show how to fix this below.)</p> <p>Always be very, very careful when defining functions inside a loop. You really need to understand closures and hoisting and related concepts. Is there any way that <code>tile1</code> can be defined globally, outside the loop?</p> <p>Regarding your question on simplifying the code structure, I think you would be okay with defining <code>tile1</code> with <code>var</code>, <s>but I don't think you need that inner loop with <code>i</code>. Try:</p> <pre><code>$('div.tile').each(function(index, element) { var tile1 = function () { var one ="div.tile div.one"; . . . if (index === 3) { // CHANGED I TO INDEX HERE. delayRate=0; } } window.setInterval(tile1, 3000); }); </code></pre> <p>I'm not sure what the inner loop was buying you.</s></p> <p>ASIDE: There is an effort underway for future JavaScript versions to deal with function statements in a block scope; you can see <a href="http://kangax.github.io/es5-compat-table/es6/" rel="nofollow">here</a> that this is supported by certain versions of Chrome, but not Firefox.</p> <p><strong>ADDENDUM</strong></p> <p>Okay now I see that you want to cycle three steps in your <code>tile1</code> function. While it is possible to put a for-loop inside the function, the JavaScript way is to have the function just run one step of its animation each time. If it needs some kind of counter, the counter should be external. One way to do this is like this:</p> <pre><code>var tile1 = function (i) { . . // use the value i here as needed . . setTimeout(function () {tile1((i + 1) % 3)}, 3000); }; tile1(0); </code></pre> <p>What this does is it first calls your tile function with the value 0. Then after you do what you want at 0, you will schedule the next frame to run 3 seconds later with the i = 1. Then three seconds or so later with 2, then three seconds or so later with 0.</p> <p>There is a little drift here, so you might want to use <code>setInterval</code>. This requires a closure. The form of the solution is this:</p> <pre><code>(function () { var i = 0; var tile1 = function () { . . // use the value i here as needed . . i = (i + 1) % 3; }; setInterval(tile1, 3000); }()); </code></pre> <p>This code is pretty cool. It is a call of an anonymous function which calls <code>setInterval</code> to schedule the <code>tile1</code> function to run every 3 seconds. Each time <code>tile1</code> runs it uses the value of a non-local <code>i</code> which is hidden from the rest of the code with the closure. Each execution of <code>tile1</code> uses the right value of <code>i</code>, then finishes by changing <code>i</code> to the proper value for its next invocation!</p> <p>Both of these techniques are good to master in JavaScript. Have fun with them. The second one, of course, has no clock drift so it is probably better. To professionalize the code, you might want to assign the result of <code>setInterval</code> to a variable so you can call <code>clearInterval</code> at a later time.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload