Categories
JavaScript

JavaScript Events Handlers — onvisibilitychange event, onanimationcancel and More

Spread the love

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign event handler to handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we looked at the standard onvisibilitychange event, and non-standard onanimationcancel, onanimationend and onanimationiteration events.

onvisibilitychange

The onvisibilitychange is an event handler that’s run when the visibilitychange event is triggered and reaches the object. We define out own event handler function and then set it to this property. For example, we can write the following code to log the visibility of the current page:

document.onvisibilitychange = (event) => {  
  console.log("Visibility changed!");  
  console.log(event);  
};

The Event object has the details for the event. We should be able to see that the type property of the event object is 'visibilitychange’ .

onanimationcancel

The onanimationcancel event let us attach an event handler for situations when the animationcancel event, which is when then CSS animation unexpectedly aborts, like when we stop running the animation without the triggering the animationend event, which may happen when the animation name is changed, the animation is removed, or when it’s hidden directly or via change in CSS. onanimationcancel is only triggered with Firefox. For example, if we have the following HTML code to create a box and a button to hide the box:

<button id='hide-button'>  
  Hide Box  
</button><div id='container'>  
  <div id='box'> </div>  
</div>

Then we add the following CSS to style the box and change the size to 100 by 100 pixels and create the animation:

#box {  
  width: 100px;  
  height: 100px;  
  left: 0;  
  top: 0;  
  border: 1px solid red;  
  margin: 0;  
  position: relative;  
  background-color: red;  
  display: block;  
  justify-content: center;  
  animation: 5s slideBox;  
}

#container {  
  height: 500px;  
}
@keyframes slideBox {  
  from {  
    left: 0;  
    top: 0;  
  } to {  
    left: calc(100% - 100px);  
    top: calc(100% - 100px)  
  }  
}

In the CSS above, initially we have the box placed on the top left corner of the page and styled it with a red filling. We have the slideBox animation sequence to love the box from the top left corner of the page to the bottom right corner by sliding it 100 pixels right and 100 pixels down in each frame.

Then we add the following JavaScript code:

const hideButton = document.getElementById('hide-button');  
const box = document.getElementById('box');
document.onanimationcancel = () => {  
  console.log('Animation cancelled unexpectedly');  
};

hideButton.onclick = () => {  
  box.style.display = 'none';  
}

Then when we click the ‘Hide Box’ button, then we get ‘ Animation cancelled unexpectedly’ logged in Firefox. The animationcancel event doesn’t get triggered when the ‘Hide Box’ button is clicked, so it doesn’t seem to have a consistent implementation across browsers.

onanimationend

The onanimationend property is a property where we can set the value of it to an event handler function which is triggered when the animationend event is fired. It’s triggered when the CSS animation reaches the end of its active period which the the total of the animation duration multiplied by the animation iteration count and the animation delay. For example, if we have the following HTML code:

<div id='container'>  
  <div id='box'> </div>  
</div>

Then we add the following CSS to style the box and change the size to 100 by 100 pixels and create the animation:

#box {  
  width: 100px;  
  height: 100px;  
  left: 0;  
  top: 0;  
  border: 1px solid red;  
  margin: 0;  
  position: relative;  
  background-color: red;  
  display: block;  
  justify-content: center;  
  animation: 5s slideBox;  
}

#container {  
  height: 500px;  
}
@keyframes slideBox {  
  from {  
    left: 0;  
    top: 0;  
  } to {  
    left: calc(100% - 100px);  
    top: calc(100% - 100px)  
  }  
}

In the CSS above, initially we have the box placed on the top left corner of the page and styled it with a red filling. We have the slideBox animation sequence to love the box from the top left corner of the page to the bottom right corner by sliding it 100 pixels right and 100 pixels down in each frame.

Then we can add the following JavaScript code to log the animationend event via our onanimationend event handler:

const box = document.getElementById('box');document.onanimationend = () => {  
  console.log('Animation ended');  
};

Note this event handler only works on Firefox as the implementation of this event hasn’t been standardized, so we shouldn’t expect this event to be triggered and the event handler function to be called.

onanimationiteration

To do something while a CSS animation is running, we can use the onanimationiteration property by assigning an event handler function to this property. The event handler that we assign to this property will be called when the animationiteration event is being triggered.

The animationiteration is triggered when an iteration of the CSS animation ends and another one begins.

This event isn’t triggered at the same time as the animationend event, and it doesn’t get triggered if the animation iteration count is one. If we set the animation-iteration-count property of the element that’s being animated to make the element animate repeatedly, then this event will be triggered. For example, if we have the same box div element in the HTML code like we have before:

<div id='container'>  
  <div id='box'> </div>  
</div>

But we change the CSS code by adding the animation-iteration-count property to it:

#box {  
  width: 100px;  
  height: 100px;  
  left: 0;  
  top: 0;  
  border: 1px solid red;  
  margin: 0;  
  position: relative;  
  background-color: red;  
  display: block;  
  justify-content: center;  
  animation: 5s slideBox;  
  animation-iteration-count: 5;  
}

#container {  
  height: 500px;  
}

@keyframes slideBox {  
  from {  
    left: 0;  
    top: 0;  
  } to {  
    left: calc(100% - 100px);  
    top: calc(100% - 100px)  
  }  
}

And then switch the JavaScript code to have the following code to set the event handler to the onanimationiteration property:

const box = document.getElementById('box');
let iterationCount = 0;

document.onanimationiteration = () => {  
  console.log('Animation is running');  
  iterationCount++;;  
  console.log(iterationCount);  
};

Then in Firefox, we should see the following logged:

Animation is running1Animation is running2Animation is running3Animation is running4

We see that the value of iterationCount is increasing by 1 every time the animation is run, so the event handler is being run by the animationiteration event being trigger in Firefox. This event is an experimental event that’s available in Firefox only so far and it’s a work in progress like all the other animation events we looked at.

The onvisibilitychange is an event handler that’s run when the visibilitychange event is triggered and reaches the object. It’s a standard event that works on most modern browsers.

We can use it to log the situation when the page starting from it being invisible to it being visible and vice versa.

Then we looked at the non-standard onanimationcancel, onanimationend and onanimationiteration which are only triggered when used with Firefox.

Other browsers do not run these event handlers and we can infer that the corresponding animationcancel, animationend, and animationiteration events aren’t being triggered.

These events are triggered only on Firefox during CSS animations when the animation is cancelled unexpectedly like when the element being animation is abruptly removed when the animation ends, and when the animation repeats respectively.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *