skip to Main Content

I’m using Bootstrap’s Buttons plugin toggle state feature on a custom checkbox. When this button is toggled (on), a hidden element should appear near the top of the page and then the page should scroll to the top. When the button is toggled next (off), the element should disappear and the page should scroll to the top.

The hidden element is toggled when the button is toggled on and off but the scroll is not working.

Changing the data-toggle from ‘buttons’ to ‘button’ makes the scroll work but does not visibly toggle the button so that is no good.

I tried setting an onchange event for the checkbox itself but that also doesn’t scroll.

It seems that Bootstrap’s function for the onclick event is doing something that doesn’t allow my onclick function to run properly. I failed at trying to understand it so far (I will keep trying).

Setting a timeout for the window.scrollTo() function makes it work. Why could this be? Is there a way to do this without the timeout?

<body>
    <div class="container">
        <div>
            <h3>Toggle Header and Scroll To Top</h3><hr />
            <h1 id="displayMe" class="d-none">Display Me</h1>
            <div style="height: 100vh;"></div>
            <div class="btn-group-toggle btn btn-success custom-control custom-switch" data-toggle="buttons" id="myButton">
                <input type="checkbox" class="custom-control-input" id="myCheckbox">
                <label class="custom-control-label" for="myCheckbox">Toggle and Scroll</label>
            </div>
        </div>
    </div>
    <script src="assets/jquery/jquery.min.js"></script>
    <script src="assets/twitter-bootstrap/js/bootstrap.min.js"></script>
    <script>
        $(document).ready(function () {
            $("#myButton").on("click", toggleAndScroll);
        });

        function toggleAndScroll() {
            $('#displayMe').toggleClass('d-none');

            //setTimeout(function () {
                window.scrollTo(0, 0);
            //}, 100);
        }
    </script>
</body>

https://jsfiddle.net/ews9q50v/

(Uncomment the setTimeout lines to see it working)

2

Answers


  1. I have no idea why it doesn’t work. Bootstrap is messing something up.
    But you can easily bypass it by moving scrollTo to the end of event loop using setTimeout(func, 0).

    $("#myButton").on("click", toggleAndScroll);
    
    function toggleAndScroll() {
        $('#displayMe').toggleClass('d-none');
    
        setTimeout(function () {
            window.scrollTo(0, 0);
        }, 0);
    }
    

    demo

    Login or Signup to reply.
  2. This seems to work for chrome but Firefox is having other issues:

    function toggleAndScroll() {
      $('#displayMe').toggleClass('d-none');
    
      window.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth'
      });
    }
    

    But since you are using jQuery something like this works in both Firefox and chrome:

    function toggleAndScroll() {
      $('#displayMe').toggleClass('d-none');
      $("html, body").animate({ scrollTop: 0 }, "slow");
    }
    

    I’m not entirely sure what the issue is – probably something to do with the scroll height changing at the same time as scrollTo is called.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search