Razvan Zamfir
Razvan Zamfir

Reputation: 4616

jQuery: script for delaying removeClass() delays too long

I have a grid of products. Some products have gifts "attached".

$('.icon').hover(function() {
  $(this).closest('.product-box').addClass("hovered");
}, function() {
  setTimeout(function() {
    $(this).closest('.product-box').removeClass("hovered");
  }, 1000);
});
.product-box {
  position: relative;
  margin-top: 10px;
  background: #fff;
  border: 1px solid #ccc;
  padding: 10px;
}
.product-box .icon {
  cursor: pointer;
  position: absolute;
  top: 4px;
  right: 7px;
}
.product-box h3 {
  margin: 0;
}
.product-box .price {
  font-weight: bold;
  padding-bottom: 5px;
}
.product-box .gift {
  border: 1px solid #ddd;
  background: #fff;
  width: 100px;
  position: absolute;
  left: 101%;
  z-index: 99;
  display: none;
}
.product-box .gift p {
  margin: 0;
}
.product-box .gift img {
  max-width: 100%;
}
.product-box.hovered .gift {
  display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="container">
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>

  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <span class="icon"><i class="fa fa-gift" aria-hidden="true"></i></span>
      <div class="gift">
        <p>Gift</p>
        <img src="//lorempixel.com/100/100" />
      </div>
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>

  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

When I hover over the gift icon, a box with the gift details appears as the product box is added the class "hovered" from jQuery.

With no help from jQuery, if the user wants to click the gift box, it does not stay long enough to be cliked.

So I have tried to add a delay to the removal of the class "hovered" with the help of the setTimeout() function.

There are 2 problems:

  1. The gift box does not disappear on mouseout.
  2. The gift box should stay as long as it is hovered.

Where am I wrong?

Upvotes: 0

Views: 63

Answers (2)

Harry Chilinguerian
Harry Chilinguerian

Reputation: 565

$('.icon').hover(function() {
  let productBox = $(this).closest('.product-box');
  productBox.addClass("hovered");
}, function() {
  let productBox = $(this).closest('.product-box');
  setTimeout(function() { 
    productBox.removeClass("hovered");
  }, 1000);
});

Upvotes: 1

ponury-kostek
ponury-kostek

Reputation: 8060

You have problem with this in your setTimeout callback

$('.icon').hover(function() {
  $(this).closest('.product-box').addClass("hovered");
}, function() {
  var self = this; // create variable that holds `this` reference from this scope
  setTimeout(function() {
    // use self instead of this
    $(self).closest('.product-box').removeClass("hovered");
  }, 1000);
});

$('.icon').hover(function() {
  $(this).closest('.product-box').addClass("hovered");
}, function() {
  var self = this;
  setTimeout(function() {
    $(self).closest('.product-box').removeClass("hovered");
  }, 1000);
});
.product-box {
  position: relative;
  margin-top: 10px;
  background: #fff;
  border: 1px solid #ccc;
  padding: 10px;
}
.product-box .icon {
  cursor: pointer;
  position: absolute;
  top: 4px;
  right: 7px;
}
.product-box h3 {
  margin: 0;
}
.product-box .price {
  font-weight: bold;
  padding-bottom: 5px;
}
.product-box .gift {
  border: 1px solid #ddd;
  background: #fff;
  width: 100px;
  position: absolute;
  left: 101%;
  z-index: 99;
  display: none;
}
.product-box .gift p {
  margin: 0;
}
.product-box .gift img {
  max-width: 100%;
}
.product-box.hovered .gift {
  display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />

<div class="container">
  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>

  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <span class="icon"><i class="fa fa-gift" aria-hidden="true"></i></span>
      <div class="gift">
        <p>Gift</p>
        <img src="//lorempixel.com/100/100" />
      </div>
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>

  <div class="col-xs-6 col-sm-4 col-md-3">
    <div class="product-box">
      <h3 class="product-name text-center">Lorem</h3>
      <div class="product-image">
        <img src="//lorempixel.com/200/200" />
      </div>
      <div class="price text-center">$100</div>
      <div class="text-center"><a href="#" class="btn btn-xs btn-success">Add to cart</a></div>
    </div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

Upvotes: 0

Related Questions