Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tdsymonds/23917215f591a9e1442a38783c77f0f0 to your computer and use it in GitHub Desktop.
Save tdsymonds/23917215f591a9e1442a38783c77f0f0 to your computer and use it in GitHub Desktop.
Cause back button to close Bootstrap modal windows
// For the below to work with the escape key
// I needed to add data-keyboard="false" to the modal
// in the HTML so that the standard bootstrap function
// doesn't fire, the below fires instead
$('div.modal').on('show.bs.modal', function() {
var modal = this;
var hash = modal.id;
window.location.hash = hash;
window.onhashchange = function() {
if (!location.hash){
$(modal).modal('hide');
}
}
});
$('div.modal').on('hidden.bs.modal', function() {
var hash = this.id;
history.replaceState('', document.title, window.location.pathname);
});
// when close button clicked simulate back
$('div.modal button.close').on('click', function(){
window.history.back();
})
// when esc pressed when modal open simulate back
$('div.modal').keyup(function(e) {
if (e.keyCode == 27){
window.history.back();
}
});
@jsoftwareengineering
Copy link

jsoftwareengineering commented Mar 12, 2017

This doesn't quite work on forward as navigating forward doesn't refresh the page (at least on macOS in Chrome and Safari this seems to be the case).

To fix this, add

else {
    $(modal).modal('show');
}

to the onhashchange function.

There does seem to be some remaining history bug using my solution here where after pressing forward, sometimes one must now press back twice to get back.

@rproenca
Copy link

rproenca commented Jul 5, 2017

Line 18 can be removed, right?
var hash = this.id;

@FynnZW
Copy link

FynnZW commented Jul 9, 2019

Works great, thanks!
My only problem was that clicks next to the modal closed it, but did not clear the history entry, so I had to click through several empty history entries.
My solution was to listen to the hide.bs.modal-event (instead of the different close-triggers individually) and using history.back() if the hash-fragment is still there (user did not use back button, but close icon, overlay, etc).
Might be helpful to someone else:

$('div.modal').on('show.bs.modal', function() {
  var modal = this;
  var hash = modal.id;
  window.location.hash = hash;
  window.onhashchange = function() {
      if (!location.hash) {
          $(modal).modal('hide');
      }
  }
});

$('div.modal').on('hide.bs.modal', function(e) {
  // hash fragment is still there? User did not use back-button, reset browser history manually now
  // check referrer to disable this for links that where copied and opened with the hash
  if (location.hash && document.referrer.includes(location.host)) {
    window.history.back();
  } 
});

edit: Added a referrer-check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment