Skip to content

Alert with progress bar similar to toast JS

I’m trying to make an alert with descending progress bar. I need that when the mouse passes over the alert, the progress bar will stop and when I remove the mouse it will continue where it left off. After completing 5 sec, it closes by itself. I put the option when clicking on the alert, close it, but it is optional.

Below is the code I made:

var currentChunk = 0;
var chunks = 5;

$('.alert').click(function() {
  $(".alert").alert('close');
});

$('.alert').hover(function() {
  window.clearInterval(timer);
  window.clearTimeout(time);
  $(".alert").css('opacity', 1);
}, function() {
  $(".alert").css('opacity', .9);
  timer = setInterval(function() {
    update();
  }, 10);
});

var timer = setInterval(function() {
  update();
}, 10);

var time = window.setTimeout(function() {
  $(".alert").fadeTo(1000, 0).slideUp(1000, function() {
    $(this).remove();
  });
}, ((chunks - currentChunk) * 1000));

function update() {
  currentChunk += 0.01;
  var progPercent = 100 - (currentChunk * (100 / chunks));
  $(".progress-bar").css('width', progPercent + '%').attr('aria-valuenow', progPercent);

  if (progPercent <= 0) {
    $(".alert").remove();
  }

  if (currentChunk >= 5) {
    window.clearInterval(timer);
  }
}
body {
  padding: 25px;
}

.alert {
  position: relative;
}

.progress {
  position: absolute;
  width: 100%;
  bottom: 0px;
  left: 0px;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

<div class="alert alert-success" id="alert" role="alert" style="cursor:pointer;opacity:.85">
  <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  <strong>Success!</strong> You have been signed in successfully!
  <div class="progress active" role="progressbar" style="height:5px">
    <div class="progress-bar bg-success" id="pb" style="width:100%;opacity:0.5"></div>
  </div>
</div>

There are two errors I want to correct. When the mouse is placed over the alert, the progress bar decrements beyond where it was and before the progress bar ends, it closes the alert.

Answer

The issue is caused by an easing transition on the progress bar from bootstrap’s styles. In other words, the actual progress is further along than you think, because the easing function makes the visuals lag.

If you remove the transition, it works as expected.

var currentChunk = 0;
var chunks = 5;

$('.alert').click(function() {
  $(".alert").alert('close');
});

$('.alert').hover(function() {
  window.clearInterval(timer);
  window.clearTimeout(time);
  $(".alert").css('opacity', 1);
}, function() {
  $(".alert").css('opacity', .9);
  timer = setInterval(function() {
    update();
  }, 10);
});

var timer = setInterval(function() {
  update();
}, 10);

var time = window.setTimeout(function() {
  $(".alert").fadeTo(1000, 0).slideUp(1000, function() {
    $(this).remove();
  });
}, ((chunks - currentChunk) * 1000));

function update() {
  currentChunk += 0.01;
  var progPercent = 100 - (currentChunk * (100 / chunks));
  $(".progress-bar").css('width', progPercent + '%').attr('aria-valuenow', progPercent);

  if (progPercent <= 0) {
    $(".alert").remove();
  }

  if (currentChunk >= 5) {
    window.clearInterval(timer);
  }
}
body {
  padding: 25px;
}

.alert {
  position: relative;
}

.progress {
  position: absolute;
  width: 100%;
  bottom: 0px;
  left: 0px;
}
.progress-bar {
  transition: none !important;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

<div class="alert alert-success" id="alert" role="alert" style="cursor:pointer;opacity:.85">
  <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  <strong>Success!</strong> You have been signed in successfully!
  <div class="progress active" role="progressbar" style="height:5px">
    <div class="progress-bar bg-success" id="pb" style="width:100%;opacity:0.5"></div>
  </div>
</div>