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>

Solution 1

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

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

    <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;
    

  • Use an event listener instead of an event handler:

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

Solution 2

As mentioned in the comment, the fix is to rename the function because it seems Chrome has reserved the original name.

element.animate()

The forthcoming Web Animations JavaScript API lets you animate web content from script. The element.animate() function included in todays Beta is the first part of the API to ship in Chrome: it makes it possible to create simple CSS Animations using JavaScript. This means that animations can be dynamically generated without paying a CSS style recalculation cost. Animations created in this way are also cancelable and provide guaranteed end events (in contrast, CSS Transitions only generate events if they cause a style change).

http://blog.chromium.org/2014/05/chrome-36-beta-elementanimate-html.html

This is the usage example of the original animate function:

elem.animate([
    {transform: 'translateX(0px)'},
    {transform: 'translateX(100px)'}
], 3000);

Solution 3

I have just had the same problem. Now I know that 'animate' is a reserved word or something. I changed the name of my function from 'animate' to 'anim' and the program worked fine. What a prank!