Remove hover event after some time using plain JavaScript

I have a Flip cards, based on: https://www.w3schools.com/howto/howto_css_flip_card.asp.

They work well, nonetheless in mobile (since there’s no mouse hover) it expects to tap out in order to the card flip to the unhover state. To prevent that, I want to remove hover event after a certain time has passed using javascript when previously pressed.

This is my current JS code:

let test = document.getElementById("flip-card");

// This handler will be executed only once when the cursor is hovered

test.addEventListener("mouseenter", function( event ) {
  
  console.log('onHover was excecuted'); // debug thing
  

  // reset the hover after a short delay
  setTimeout(function() {
    test.unbind('mouseenter mouseleave'); //this needs jQuery, is there anyway to do it with plain Js?
    
  }, 3000);
}, false);

Thank you for your advice!

Append Information

I want to “unflip” the “flip-card” after certain time has passed, no matter if the cursor is still there.

Answer

I think what you’re looking for is removeEventListener, but it has a catch. You can’t remove handlers that are set using addEventListener('event', function() { ... }). You have to define your function, meaning your example would look like:

let test = document.getElementById("flip-card");

function handler( event ) {
  
  console.log('onHover was excecuted'); // debug thing
  

  // reset the hover after a short delay
  setTimeout(function() {
    test.unbind('mouseenter mouseleave'); //this needs jQuery, is there anyway to do it with plain Js?
    
  }, 3000);
}

// This handler will be executed only once when the cursor is hovered
test.addEventListener("mouseenter", handler, false);

removeEventListener must receive the same capture argument that the addEventListener used to add the event in the first place. For example:

test.addEventListener("mouseenter", handler, false);

// Will be removed by
test.removeEventListener('mouseenter', handler, false);
test.removeEventListener('mouseenter', handler, { capture: false });

// But not by
test.removeEventListener('mouseenter', handler, true);
test.removeEventListener('mouseenter', handler, { capture: true });

You can read up more about it on MDN here.

Update

After discussing it more, it turns out the issue was more about changing the “active” state when on mobile vs on desktop.

To achieve this, we can stop using mouse* events and instead use pointer* events. They have the event.pointerType property, which can be either “mouse”, “pen”, or “touch”

Inside of our handler function, we’ll add a conditional to look for pointerType === 'touch'.

function handler(event) {
  if (event.pointerType === 'touch') {
    // Do stuff
  }
}

To avoid too much complexity, we want to leave all the styling up to the CSS you already wrote. All we need need to do is:

a. Mark the body as being “touch compatible”. b. Add a .active class to replace :hover styles.

Our updated function looks like this

function handler(event) {
  if (event.pointerType === 'touch') {
    event.preventDefault();

    document.body.classList.add('pointer-active'); // arbitrary class name
    element.classList.add('active');
  }
}

Now we just need to remove the class after a certain amount of delay, which we can do with a setTimeout.

function handler(event) {
  if (event.pointerType === 'touch') {
    event.preventDefault();

    document.body.classList.add('pointer-active'); // arbitrary class name
    element.classList.add('active');
    
    setTimeout(function() {
      element.classList.remove('active');
    }, 3000);
  }
}

Then we add that back into your original example, it looks like this:

let test = document.getElementById("flip-card");

function handler( event ) {
  console.log('onPointerDown was excecuted'); // debug thing
  
  
  // If the pointer is touch, from mouse, pen, touch
  if (event.pointerType === 'touch') {
    event.preventDefault();

    document.body.classList.add('pointer-active')
    // add the active class
    test.classList.add('active');

    // Remove class after a delay
    setTimeout(function() {
      test.classList.remove('active');
    }, 3000);  
  }
}

// This handler will be executed only once when the cursor is hovered
test.addEventListener("pointerout", handler, false);

Here’s a codepen where you can mess around with it further.

Leave a Reply

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