TurgidWizard TurgidWizard - 2 months ago 9
CSS Question

JS function named `animate` doesn't work in Chrome, but works in IE

This won't work, nothing happens. How do I make it work, what am I doing wrong?



function animate() {
var div = document.getElementById('demo');
div.style.left = "200px";
div.style.color = "red";
}

#demo {
position: absolute;
}

<p id='demo' onclick="animate()">lolol</p>




Answer

The problem is that, since you use an event handler content attribute, your global function...

window.animate

...is shadowed by...

Element.prototype.animate

...which was introduced recently in Web Animations:

5.21 Extensions to the Element interface

Since DOM Elements may be the target of an animation, the Element interface [DOM4] is extended as follows:

Element implements Animatable;

This allows the following kind of usage.

elem.animate({ color: 'red' }, 2000);

This behavior is explained in step 10 of getting the current value of the event handler:

Lexical Environment Scope

  1. If H is an element's event handler, then let Scope be the result of NewObjectEnvironment(document, the global environment).

    Otherwise, H is a Window object's event handler: let Scope be the global environment.

  2. If form owner is not null, let Scope be the result of NewObjectEnvironment(form owner, Scope).

  3. If element is not null, let Scope be the result of NewObjectEnvironment(element, Scope).

Note: NewObjectEnvironment() is defined in ECMAScript edition 5 section 10.2.2.3 NewObjectEnvironment (O, E)

That means that the scope of the target element shadows the global scope.

Therefore, you can

  • Rename your function

    function animate__() {
      var div = document.getElementById('demo');
      div.style.left = "200px";
      div.style.color = "red";
    }
    #demo {
      position: absolute;
    }
    <p id='demo' onclick="animate__()">Click me</p>

  • Use window.animate (assuming window has not been shadowed):

    <p id='demo' onclick="window.animate()">Click me</p>
    

    function animate() {
      var div = document.getElementById('demo');
      div.style.left = "200px";
      div.style.color = "red";
    }
    #demo {
      position: absolute;
    }
    <p id='demo' onclick="window.animate()">Click me</p>

  • Use an event handler IDL attribute instead of a content attribute one:

    document.getElementById('demo').onclick = animate;
    

    function animate() {
      var div = document.getElementById('demo');
      div.style.left = "200px";
      div.style.color = "red";
    }
    document.getElementById('demo').onclick = animate;
    #demo {
      position: absolute;
    }
    <p id='demo'>Click me</p>

  • Use an event listener instead of an event handler:

    document.getElementById('demo').addEventListener('click', animate);
    

    function animate() {
      var div = document.getElementById('demo');
      div.style.left = "200px";
      div.style.color = "red";
    }
    document.getElementById('demo').addEventListener('click', animate);
    #demo {
      position: absolute;
    }
    <p id='demo'>Click me</p>