Support Ukraine

Velo by Wix: Imitating hover event on repeater container

Velo API doesn't provide a hover event on the repeater container. In this post, we look at one way how we can imitate the hover event.

Motivation

We have a $w.Repeater component with items of users' cards. When we point with the mouse cursor over some item we want to change background color of this item to light blue color #CCE4F7 and when the cursor moves off of item we want to return the initial white color.

For this, we're going to use two other events that provide repeater API:

Also, repeater items don't have property style.backgroundColor for changing the background color of an element. But we can use background.src property for changing the background image. So in this way, we're going to use a one-pixel image.

Download: Here is one-pixel image light blue pixel image

Event handlers

To start with, set handlers to onMouse{In/Out} events. We will use one function for two events by repeaters containers. We declare the handler function above and pass the function's name as an argument to container methods.

/**
 * @param {$w.MouseEvent} event
 */
const imitateHover = (event) => {
  // our handler for containers
}

$w.onReady(function () {
  $w('#container1').onMouseIn(imitateHover).onMouseOut(imitateHover); // set handlers
});

Imitate hover

We use one function for two events, therefore we need to listen to which type of event is going. We're expecting two event types:

Let's see the code:

/**
 * @param {$w.MouseEvent} event
 */
const imitateHover = (event) => {
  if (event.type === 'mouseenter') {
    console.log('we have mouseenter if onMouseIn() is running');
  }

  if (event.type === 'mouseleave') {
    console.log('we have mouseleave if onMouseOut() is running');
  }
};

$w.onReady(function () {
  $w('#container1').onMouseIn(imitateHover).onMouseOut(imitateHover);
});

The object event always will be consistent with the current container item, which we point mouse cursor. And we can change the background.src property of the container by event.target.

// link to one pixel image
const HOVER_PNG = 'https://static.wixstatic.com/media/e3b156_df544ca8daff4e66bc7714ebc7bf95f1~mv2.png';

/**
 * @param {$w.MouseEvent} event
 */
const imitateHover = (event) => {
  // when the cursor over container then set image.
  if (event.type === 'mouseenter') {
    event.target.background.src = HOVER_PNG;
  }

  if (event.type === 'mouseleave') {
    // when the cursor is gone then remove the pixel image.
    event.target.background.src = '';
  }
}

$w.onReady(function () {
  $w('#container1').onMouseIn(imitateHover).onMouseOut(imitateHover);
});

Great! It works.

One-pixel image

We used the direct link to the one-pixel image. The size of this image is only 70 bytes. For example, the link of this image has 82 chars length, it's 82 bytes. The link takes up more memory than the image. ¯\_(ツ)_/¯

data:URL

Data URLs, it's a protocol that allows embedded small files inline in documents as a string. It means we can convert a one-pixel PNG image to string and pass it to background.src.

We can create needed images by 1x1 PNG generator #cce4f7ff.

// one-pixel image encoded to base64
const HOVER_PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mM88+R7PQAIUwMo5M6pSAAAAABJRU5ErkJggg==';

/**
 * @param {$w.MouseEvent} event
 */
const imitateHover = (event) => {
  if (event.type === 'mouseenter') {
    event.target.background.src = HOVER_PNG;
  }

  if (event.type === 'mouseleave') {
    event.target.background.src = '';
  }
};

$w.onReady(function () {
  $w('#container1').onMouseIn(imitateHover).onMouseOut(imitateHover);
});

The data:URL image is a little longer than the direct link for this image. And other reason to use data:URL with the small image we don't send HTTP request for fetching this image.

Live Demo: Hover on repeater container

Resources

Posts