Search code examples
jquerybootstrap-modalbrowser-history

bootstrap 3 close Modal when pushing browser back button


I just want to create a modal page which behaves the same either pushing the browser back button or the close button inside the modal, using bootstrap 3. I found a script which does that, but there is a problem. let's say I start off with a google.com, go to this modal page, then push the "Modal!" button, then push the browser back button, it will close the modal, if I push the back button again, it will take me back to google.com (all is good). But this time, if I open the modal page and close the modal using the "close" button instead. But now, I would have to push the back button twice to go back to google.com. If I open and close the modal with the close button inside of modal for like 10x. I found that I have to push the browser back button 10 more times to get back to google.com page. How to fix this problem? TIA

<!--html, bootstrap 3.2.0-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
  <div class="modal-body">
    <p>If you press the web browser's back button not the modal's "close" button, the modal will close and the hash "#myModal" will be removed for the URL</p>
  </div>
  <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
</div>
</div>
</div>

<!--jquery-->
$('#myModal').on('show.bs.modal', function (e) {
    window.history.pushState('forward', null, '#modal');
});

$('#myModal').on('hide.bs.modal', function (e) {
    //pop the forward state to go back to original state before pushing the "Modal!" button
});

$(window).on('popstate', function () {
    $('#myModal').modal('hide');
});

jsfiddle source


Solution

  • I use this code for my own website

    window.onload=function(){
    
        State=popset=0;
        setpops=function(){
            if(popset) return;popset=1;// dont set event multiple times
            window.onpopstate=function(e){
                State=e.state;
                if(e.state=="hide"){
                    $(".modal").modal("hide").removeClass("in show");
                    $(".modal-backdrop").remove();// force hide bg
                    /* in some old devices .modal("hide") is not enough */
                }
            };
        };
    
        $(".modal")
        .on("show.bs.modal",function(){// while modal show
            path=window.location.pathname+window.location.search;
            history.pushState("hide",null,path);
            history.pushState("show",null,path);
            State="show";
        })
        .on("hidden.bs.modal",function(){// while modal hide
            if(!!State)
                history.go(State=="hide"?-1:-2);// remove extra forward states
        });
    
        window.onpopstate=function(){setpops();};
    
        setTimeout(function(){setpops();},2000);// fix old webkit bug
    
    };
    
    • dont use $(document).ready instead of window.onload

    Tested on Chrome 87 ,   FireFox 84 ,   Chromium 88 ,   Android 4.1 / 4.2 / 7.1 / 9.0

    (i am user5490177 deleted account which answer same question, this is a new improved version)