Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

javascript - Scrolltop function not working correctly when scrolling on mobile

I have a button that scrolls to another element. This works fine on desktop but on mobile if I scroll a little bit and click the button, the function does not scroll precisely to the element I want but is a bit off, even though I didn't specify any offset.

On desktop I have a fixed menu that changes size, so that is why in below code I check for desktop or mobile using the window width:

if(window.outerWidth > 991) {
    console.log('desktop');
    $("body").on("click","#bestellenbtn",function(){
        var scrollmenuheight = $('.scrollmenu').height();
        $([document.documentElement, document.body]).animate({
        scrollTop: $("#bestellen").offset().top - scrollmenuheight
    }, 1000);
    });
}else{
    console.log('mobile');
    $("body").on("click","#bestellenbtn",function(){
        $([document.documentElement, document.body]).animate({
        scrollTop: $("#bestellen").offset().top
    }, 1000);
    });
}

This is the button that starts the function:

<a href="javascript:void(0);" id="bestellenbtn"><button class="btnstyle blue-inverse" type="button" name="button">Bestellen</button></a>

And the element:

<div class="separator" id="bestellen">
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <h2>Bestellen</h2>
      </div>
    </div>
  </div>
</div>

I added a copy of the page in a codepen so you can see it for yourself (click the first of 4 blue buttons on mobile view):

https://codepen.io/twan2020/pen/RwGmaMQ You can resize to get the mobile version.

What can I do?

I've tried changing the offset but that shouldn't be necessary because on mobile there is no fixed menu that changes the height of the document.

I made a short video to show what the problem is:

https://gyazo.com/431163072afb0de9a6488ebfba895ff5

question from:https://stackoverflow.com/questions/65848336/scrolltop-function-not-working-correctly-when-scrolling-on-mobile

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  1. Use the if-statement inside the function that handels #bestellenbtn click.

  2. Use window.innerWidth instead of window.outerWidth. However, For compatibility reason, it is better that you use the following code instead.

var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); .

  1. On mobile, use Element.scrollIntoView() with smooth behaviour. Let JS rules.

Element.scrollIntoView()

The Element interface's scrollIntoView() method scrolls the element's parent container such that the element on which scrollIntoView() is called is visible to the user. MDN - Element.scrollIntoView()

document.querySelector("#bestellen")
          .scrollIntoView({block: "start", behavior: "smooth"})



$("body").on("click","#bestellenbtn",function(){
var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  if(viewportWidth > 991) {
    console.log('desktop');
    var scrollmenuheight = $('.scrollmenu').height();
    $([document.documentElement, document.body]).animate({
      scrollTop: $("#bestellen").offset().top - scrollmenuheight
    }, 1000);
  }else{
    console.log('mobiel');
    document.querySelector("#bestellen")
      .scrollIntoView({block: "start", behavior: "smooth"})
  }
});


Update.

Do you have an idea why on desktop when I click, the animation is not instant but only starts after about 1 second? Maybe the function is too heavy?

That is probably because of animation duration. Try using 300 or 700 as timeout for the animate function.


If you need a similar behaviour as on mobile, use window.scrollTo with smooth behaviour.

Window.scrollTo() scrolls to a particular set of coordinates in the document. - MDN - Window.scrollTo()

$("body").on("click","#bestellenbtn",function(){
  var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  if(viewportWidth > 991) {
    console.log('desktop');
    var scrollmenuheight = $('.scrollmenu').height();
    var offsetTop = $("#bestellen").offset().top - scrollmenuheight;
    window.scrollTo({
      top: offsetTop,
      behavior: 'smooth'
    });
    
  
  }else{
    console.log('mobiel');
    document.querySelector("#bestellen")
      .scrollIntoView({block: "start", behavior: "smooth"})
  }
});

On mobile, it scroll faster because the distance between #bestellenbtn and #bestellen is more than the distance between those two elements on desktop.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...