Skip to content
Tippy Logo

Tippy.js

View on GitHub
v6.3.7

AJAX

Initiating AJAX requests is facilitated by lifecycle hooks. This allows you to do very powerful things. For example, let's say you wanted to show a new image inside a tooltip each time it gets shown:

Let's walk through a little tutorial to learn how to do this.

First, let's setup our HTML:

<button id="ajax-tippy">Hover for a new image</button>

Now, let's add some JavaScript:

tippy('#ajax-tippy', { content: 'Loading...', });

Here's the result so far (nothing happens yet!):

To initiate the AJAX request every time the tippy shows, use the onShow lifecycle:

tippy('#ajax-tippy', { content: 'Loading...', onShow(instance) { // Code here is executed every time the tippy shows }, });

Using fetch, we can fetch a random image from an Unsplash API:

tippy('#ajax-tippy', { // ... onShow(instance) { fetch('https://unsplash.it/200/?random') .then((response) => response.blob()) .then((blob) => { // Convert the blob into a URL const url = URL.createObjectURL(blob); // Create an image const image = new Image(); image.width = 200; image.height = 200; image.style.display = 'block'; image.src = url; // Update the tippy content with the image instance.setContent(image); }) .catch((error) => { // Fallback if the network request failed instance.setContent(`Request failed. ${error}`); }); }, });

There are currently two problems with this:

  • When the tippy is hidden, it doesn't reset back to Loading...
  • If you quickly hover in and out of the tippy, it initiates many different requests and each image rapidly replaces the old one as each request finishes

The first one can be solved by using the onHidden lifecycle, which is executed once the tippy fully transitions out and is unmounted from the DOM:

tippy('#ajax-tippy', { // ... onHidden(instance) { instance.setContent('Loading...'); }, });

The second one requires some state:

tippy('#ajax-tippy', { // ... onCreate(instance) { // Setup our own custom state properties instance._isFetching = false; instance._src = null; instance._error = null; }, onShow(instance) { if (instance._isFetching || instance._src || instance._error) { return; } instance._isFetching = true; fetch('https://unsplash.it/200/?random') .then((response) => response.blob()) .then((blob) => { const src = URL.createObjectURL(blob); instance._src = src; // ... }) .catch((error) => { instance._error = error; instance.setContent(`Request failed. ${error}`); }) .finally(() => { instance._isFetching = false; }); }, onHidden(instance) { instance.setContent('Loading...'); // Unset these properties so new network requests can be initiated instance._src = null; instance._error = null; }, });
MethodsAccessibility

© 2022 — MIT License

Icons made by Freepik from www.flaticon.com