Events & timing

What are events?

Event are actions that happen in the browser, such as a user interacting with the page, the window being resized, or some content being loaded. You can listen to these events using JavaScript and run some code when they occur. While there are many events, we'll focus on the most common ones:

  • click – Fires when an element is clicked.
  • mousemove – Fires when the mouse is moved over an element.
  • resize – Fires when the document view has been resized.
  • scroll – Fires when the view of an element has been scrolled.
  • keydown – Fires when the user presses a key.

Event listeners

To listen to an event, you need to add an event listener to an element. An event listener is a function that will be executed when the event occurs. You can add an event listener to an element using the addEventListener() method. The first argument is the name of the event, and the second argument is the function that will be executed when the event occurs. The function automatically takes the fired event object as input, which contains information about the event.

// Function to remove the outline of the target when leaving target
function removeOutline(event) {
  // Get the target of the event
  var target = event.target;
  // Remove the outline of the target
  target.style.removeProperty('outline');
  target.removeEventListener('mouseleave', removeOutline);
}

// Function outlining the target of the event
function outlineTarget(event) {
  // Get the target of the event
  var target = event.target;
  // Set the outline of the target
  target.style.outline = 'dotted 1px red';
  target.addEventListener('mouseleave', removeOutline);
}

// Listen to the movement of the mouse on the window
window.addEventListener("mousemove", outlineTarget);

The click event

The click event is fired when an element is clicked. The event object contains information about the click, such as the position of the click relative to the page or window, the type of pointer that was used to click, or the target of the click. Here is an example displaying the information of the click event:

// Get marker
var marker = document.getElementById("marker");

// Move the marker to the position of the click
function updateMarkerToPosition(event) {
  marker.style.left = event.clientX + "px";
  marker.style.top = event.clientY + "px";

  // Update the content of the marker
  marger.innerHTML = event.pointerType + " clicked " + event.target.tagName + " at<br/>clientX: " + event.clientX + "px, clientY: " + event.clientY + "px";
}

// Add the event listener to the document
document.addEventListener("click", updateMarkerToPosition);

The mousemove event

The mousemove event is fired when the mouse is moved over an element. Similarly to the click event, the event object contains information about the mouse move, such as its position relative to the page, window or screen and its target. This event listener is essential if you want to implement a custom cursor. Additionally, the event contains information about the mouse buttons and modifier keys that were pressed when the mouse was moved. Here is an example displaying the information of the mousemove event:

// Get marker
var marker = document.getElementById("marker");

// Move the marker to the position of the mousemove
function updateMarkerToPosition(event) {
  marker.style.left = event.clientX + "px";
  marker.style.top = event.clientY + "px";

  // Get the modifier keys pressed
  let modifierKeysPressed = [];
  if (event.altKey) {modifierKeysPressed.push("alt");}
  if (event.ctrlKey) {modifierKeysPressed.push("ctrl");}
  if (event.metaKey) {modifierKeysPressed.push("meta");}
  if (event.shiftKey) {modifierKeysPressed.push("shift");}
  if (modifierKeysPressed.length === 0) {modifierKeysPressed = "no modifier keys";}

  // Update the content of the marker
  marger.innerHTML = event.pointerType + " moved over " + event.target.tagName + " at
clientX: " + event.clientX + "px, clientY: " + event.clientY + "px
while pressing " + modifierKeysPressed; } // Add the event listener to the document document.addEventListener("mousemove", updateMarkerToPosition);

The resize event

The resize event is fired when the document view has been resized. While more niche, this event is very useful for recalculating some layout elements you can't do with CSS. Here is an example updating the viewport width and height variables on resize:

// Get the viewport width and height
var viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
var viewportHeight = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

// Get the output element
var output = document.querySelector(".output");

// Function to update the output
function updateOutput() {
  output.textContent = 'Viewport width: ' + viewportWidth + 'px,<br/>Viewport height: ' + viewportHeight + 'px';
}

// Add the event listener to the document
window.addEventListener("resize", function () {
  // Update the viewport width and height
  viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
  viewportHeight = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
  // Update the output
  updateOutput();
});

The scroll event

The scroll event is fired when the view of an element has been scrolled. This event is useful if you want to implement scroll-driven animations or other effects. Here is an example displaying the scroll position of the page:

// Get the scroll position
var scrollPositionX = window.scrollX;
var scrollPositionY = window.scrollY;

// Get the output element
var output = document.querySelector(".output");

// Function to update the output
function updateOutput() {
  output.textContent = 'Scroll position X: ' + scrollPositionX + 'px,<br/>Scroll position Y: ' + scrollPositionY + 'px';
}

// Add the event listener to the document
window.addEventListener("scroll", function () {
  // Update the scroll position
  scrollPositionX = window.scrollX;
  scrollPositionY = window.scrollY;
  // Update the output
  updateOutput();
});

The keydown event

The keydown event is fired when the user presses a key. This event is useful if you want to implement keyboard shortcuts or navigation. Here is an example displaying the key that was pressed on keydown:

// Get the key that was pressed
var keyPressed = null;

// Get the output element
var output = document.querySelector(".output");

// Add the event listener to the document
document.addEventListener("keydown", function (event) {
  // Update the key that was pressed
  keyPressed = event.key;
  // Update the output
  output.textContent = 'Key pressed: ' + keyPressed;
});

Delays, intervals & frames

The setTimeout function

The setTimeout() function is used to delay the execution of a function. It takes two arguments: the function to execute, and the delay in milliseconds. By assigning the return value of the setTimeout() function to a variable, you can cancel the execution of the function using the clearTimeout() function.

alert("You've just run the code");

setTimeout(function () {
  alert("It's time to do something!");
}, 5000); // 5000 ms = 5 seconds

The setInterval function

Similarly, the setInterval() function is used to repeatedly execute a function at a specified interval. It takes two arguments: the function to execute, and the delay in milliseconds. By assigning the return value of the setInterval() function to a variable, you can cancel the execution of the function using the clearInterval() function.

let interval = setInterval(function () {
  alert("Friendly reminder!");
}, 3000); // 3000 ms = 3 seconds

The requestAnimationFrame function

The requestAnimationFrame() function is used to execute a function at the next available screen refresh. It takes one argument: the function to execute. By assigning the return value of the requestAnimationFrame() function to a variable, you can cancel the execution of the function using the cancelAnimationFrame() function. This function is especially useful for creating procedural animations.

// Declare an empty requestAnimationFrame variable
let frame;

// Select the element to animate
const animated = document.querySelector(".animation");

// Function to animate the element
function animate() {
  // Get the parent element of the element to animate
  const parent = animated.parentElement;

  // Get the current time
  const now = Date.now() * 0.002;

  // Animate the element
  animated.style.transform = `translate3d(${(
      Math.sin(now) * 
      (parent.clientWidth - animated.clientWidth)
    ) / 2}px, ${(
      Math.cos(now * Math.PI) * 
      (parent.clientHeight - animated.clientHeight)
    ) / 2
  }px, 0)`;

  // Request the next animation frame
  frame = requestAnimationFrame(animate);
}

// Start the animation
frame = requestAnimationFrame(animate);
Procedurally animated