如何在纯JavaScript中平滑滚动到一个元素 [英] How to smoothly scroll to an element in pure javascript

查看:62
本文介绍了如何在纯JavaScript中平滑滚动到一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想平滑地滚动到一个元素而不使用jQuery - 只是纯粹的javascript。我想要一个通用函数能够向下滚动并顺利向上滚动到文档中的特定位置。



我知道我可以在jQuery中使用以下内容:

  $('html,body')。animate({
scrollTop:$('#myelementid')。 offset()。top
},500);

我如何只使用javascript进行操作?



这就是我要做的事情:



  function scrollToHalf( ){//我该怎么办?} function scrollToSection(){//我该怎么做?}  

 < input type =buttononClick =scrollToHalf()value =Scroll To 50%of page> <峰; br> < input type =buttononClick =scrollToSection()value =Scroll To Section1> < section style =margin-top:1000px; ID = SECTION1 >这是一节< / section>  



在jquery我会做它是这样的:



  html,body {height:3000px;}  

 < script src =https://ajax.googleapis。 com / ajax / libs / jquery / 2.1.1 / jquery.min.js>< / script>< input type =buttononClick =scrollToHalf()value =滚动到页面的50% >< br>< input type =buttononClick =scrollToSection()value =Scroll To Section1>< section style =margin-top:1000px; ID = SECTION1 >这是一节< / section>< script>函数scrollToHalf(){var height = $('body')。height(); $('html,body')。animate({scrollTop:height / 2},500);} function scrollToSection(){$('html,body')。animate({scrollTop:$('#section1')。 offset()。top},500);}< / script>  



编辑:我也希望能够平滑滚动到页面上的某个位置



编辑:CSS解决方案也很受欢迎(虽然我更喜欢javascript解决方案)

解决方案

您可以使用 for 循环 window.scrollTo setTimeout 使用普通Javascript平滑滚动。要滚动到特定元素,只需使用元素的offsetTop作为第一个参数调用 scrollToSmoothly 函数。

  function scrollToSmoothly(pos,time){
/ *时间仅适用于向上滚动* /
/ *由hev1 * /
/ * pos编写的代码是滚动到的y位置(以像素为单位)* /
if(isNaN(pos)){
throwPosition必须是数字;
}
if(pos< 0){
throwPosition is not negative;
}
var currentPos = window.scrollY || window.screenTop;
if(currentPos< pos){
var t = 10;
for(let i = currentPos; i< = pos; i + = 10){
t + = 10;
setTimeout(function(){
window.scrollTo(0,i);
},t / 2);
}
}其他{
时间=时间|| 2;
var i = currentPos;
var x;
x = setInterval(function(){
window.scrollTo(0,i);
i - = 10;
if(i< = pos){
clearInterval (x);
}
},时间);
}
}

演示:



 < button onClick =scrollToDiv()>滚动到元素< / button> < div style =margin:1000px 0px; text-align:center;> Div元素< p />< button onClick =scrollToSmoothly(Number(0))>滚动回顶部< / button> ;< p />< button onClick =scrollToSmoothly(document.body.offsetHeight)>滚动到底部< / button>< / div>< button onClick =scrollToSmoothly(Number(500)) >滚动到y位置500px< / button>< script>函数scrollToSoothly(pos,time){/ *时间仅适用于向上滚动* // *由hev1 * // * pos编写的代码是y-滚动到的位置(以像素为单位)* / if(isNaN(pos)){throw位置必须是数字; } if(pos< 0){throw位置不能为负; } var currentPos = window.scrollY || window.screenTop; if(currentPos< pos){if(time){var x; var i = currentPos; x = setInterval(function(){window.scrollTo(0,i); i + = 10; if(i> = pos){clearInterval(x);}},time); } else {var t = 10; for(let i = currentPos; i< = pos; i + = 10){t + = 10; setTimeout(function(){window.scrollTo(0,i);},t / 2); }}} else {time = time || 2; var i = currentPos; var x; x = setInterval(function(){window.scrollTo(0,i); i  -  = 10; if(i< = pos){clearInterval(x);}},time); function scrollToDiv(){var elem = document.querySelector(div); scrollToSmoothly(elem.offsetTop);}< / script>  



要在确切的时间内滚动到某个位置,可以使用 window.requestAnimationFrame 。 JSFiddle WebPage演示: http://jsfiddle.net/4xwnzgj5/embedded/result

  function scrollToSmoothly(pos,time){
/ *时间是滚动所需的准确时间(以毫秒为单位)* /
/ * Pos是滚动到的y位置(以像素为单位)* /
/ *由hev1 * /
写的代码if(typeof pos!==number){
pos = parseFloat(pos);
}
if(isNaN(pos)){
console.warn(Position必须是数字或数字字符串。);
抛出位置必须是数字;
}
if(pos< 0 || time< 0){
return;
}
var currentPos = window.scrollY || window.screenTop;
var start = null;
时间=时间|| 500;
window.requestAnimationFrame(函数步骤(currentTime){
start =!start?currentTime:start;
if(currentPos< pos){
var progress = currentTime - start;
window.scrollTo(0,((pos-currentPos)* progress / time)+ currentPos);
if(progress< time){
window.requestAnimationFrame(step);
} else {
window.scrollTo(0,pos);
}
} else {
var progress = currentTime - start;
window.scrollTo(0, currentPos - ((currentPos-pos)* progress / time));
if(progress< time){
window.requestAnimationFrame(step);
} else {
window .scrollTo(0,pos);
}
}
});
}

演示:



 < button onClick =scrollToSmoothly(Number(document.querySelector('div')。offsetTop),Number( 300))> Scroll To Div(300ms)< / button>< button onClick =scrollToSmoothly(Number(document.querySelector('div')。offsetTop),Number(200))> Scroll To Div (200ms)< / button>< button onClick =scrollToSmoothly(Number(document.querySelector('div')。offsetTop),Number(100))> Scroll To Div(100ms)< / button>< ;按钮onClick =scrollToSmoothly(Number(document.querySelector('div')。offsetTop),50)> Scroll To Div(50ms)< / button>< button onClick =scrollToSmoothly(Number(document.querySelector) ('div')。offsetTop),Number(1000))> Scroll To Div(1000ms)< / button>< div style =ma rgin:500px 0px;> DIV< p />< button onClick =scrollToSmoothly(0,500)>返回顶部< / button>< button onClick =scrollToSmoothly(document.body.scrollHeight) >滚动到底部< /按钮>< / div>< div style =margin:500px 0px;>< / div>< button style =margin-top:100px; onClick =scrollToSmoothly(500,3000)>滚动到y位置500px(3000ms)< / button>< script>函数scrollToSoothly(pos,time){/ *时间是滚动所需的准确时间量(以毫秒为单位)* / / * Pos是滚动到的y位置(以像素为单位)* / / *由hev1 * / if(typeof pos!==number)写的代码{pos = parseFloat(pos); } if(isNaN(pos)){console.warn(Position必须是数字或数字字符串。);扔位置必须是数字; } if(pos< 0 || time< 0){return; } var currentPos = window.scrollY || window.screenTop; var start = null;时间=时间|| 500; window.requestAnimationFrame(function step(currentTime){start =!start?currentTime:start; if(currentPos< pos){var progress = currentTime  -  start; window.scrollTo(0,((pos-currentPos)* progress / time) + currentPos); if(progress< time){window.requestAnimationFrame(step);} else {window.scrollTo(0,pos);}} else {var progress = currentTime  -  start; window.scrollTo(0,currentPos- ((currentPos-pos)* progress / time)); if(progress< time){window.requestAnimationFrame(step);} else {window.scrollTo(0,pos);}}});}< / script> ;  



或者,您可以使用窗口.scroll 滚动到特定的x和y位置, window.scrollBy 从当前位置滚动:

  //滚动到特定值
// scrollTo是相同的
window.scroll({
top:2500,
left:0,
行为:'smooth'
});

//从当前位置滚动某些金额
window.scrollBy({
top:100,//可能是负值
left:0,
行为:'流畅'
});

演示:



 < button onClick =scrollToDiv()>滚动到元素< / button>< div style =margin:500px 0px ;> Div< / div>< script>函数scrollToDiv(){var elem = document.querySelector(div); window.scroll({top:elem.offsetTop,left:0,behavior:'smooth' });}< / script>  



如果您只需要要滚动到一个元素,而不是文档中的特定位置,您可以使用 Element.scrollIntoView 并将行为设置为光滑

  document.getElementById(elemID)。scrollIntoView({
behavior:'smooth'
} );

演示:



 < button onClick =scrollToDiv()>滚动到元素< / button>< div id =myDivstyle = margin:500px 0px;> Div< / div>< script> function scrollToDiv(){document.getElementById(myDiv)。scrollIntoView({behavior:'smooth'});}< / script>  



现代浏览器支持滚动行为 CSS属性,可用于在文档中平滑滚动(无需Javascript;通过为锚标记提供 href 加上要滚动到的元素的 id 。您还可以为特定元素(如 div )设置滚动行为属性,以使其内容平滑滚动。 / p>

演示:



  html,body {scroll-behavior:smooth;} a,a:visited {color:initial;}  

 < a href =#elem>滚动到元素< / a>< div id =elemstyle =margin:500px 0px; > Div< / div>  



CSS <$ c使用 window.scrollTo 时,$ c> scroll-behavior 属性也适用于Javascript。



演示:



  html,body {scroll-behavior:smooth;}  

 < button onClick =scrollToDiv()>滚动到元素< / button>< div style = margin:500px 0px;> Div< / div>< script> function scrollToDiv(){var elem = document.querySelector(div); window.scrollTo(0,elem.offsetTop);}< / script>  



要检查是否支持滚动行为属性,您可以检查它是否作为HTML元素样式中的键存在。



  var scrollBehaviorSupported ='scroll-behavior'; console.log('支持滚动行为:',scrollBehaviorSupported);  


I want to smoothly scroll to an element without using jQuery – just pure javascript. I would like a generic function to be able to both scroll down and scroll up smoothly to a specific position in the document.

I know I can use the following in jQuery:

$('html, body').animate({
     scrollTop: $('#myelementid').offset().top
}, 500);

How would I do it with just javascript?

This is what I am trying to do:

function scrollToHalf(){
  //what do I do?
}
function scrollToSection(){
 //What should I do here?
}

<input type="button" onClick="scrollToHalf()" value="Scroll To 50% of Page">
    <br>
    <input type="button" onClick="scrollToSection()" value="Scroll To Section1">
    <section style="margin-top: 1000px;" id="section1">
      This is a section
</section>

In jquery I would do it like so:

html, body{
  height: 3000px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" onClick="scrollToHalf()" value="Scroll To 50% of Page">
<br>
<input type="button" onClick="scrollToSection()" value="Scroll To Section1">
<section style="margin-top: 1000px;" id="section1">
  This is a section
</section>
<script>
function scrollToHalf(){
  var height = $('body').height();
	$('html, body').animate({
         scrollTop: height/2
    }, 500);
}
function scrollToSection(){
	$('html, body').animate({
         scrollTop: $('#section1').offset().top
    }, 500);
}
</script>

EDIT: I would also like to be able to smooth scroll to a certain position on the page

EDIT: CSS solutions are also welcome (although I would prefer javascript solutions)

解决方案

You can use a for loop with window.scrollTo and setTimeout to scroll smoothly with plain Javascript. To scroll to a specific element, just call the scrollToSmoothly function with the element's offsetTop as the first argument.

function scrollToSmoothly(pos, time) {
  /*Time is only applicable for scrolling upwards*/
  /*Code written by hev1*/
  /*pos is the y-position to scroll to (in pixels)*/
  if (isNaN(pos)) {
    throw "Position must be a number";
  }
  if (pos < 0) {
    throw "Position can not be negative";
  }
  var currentPos = window.scrollY || window.screenTop;
  if (currentPos < pos) {
    var t = 10;
    for (let i = currentPos; i <= pos; i += 10) {
      t += 10;
      setTimeout(function() {
        window.scrollTo(0, i);
      }, t / 2);
    }
  } else {
    time = time || 2;
    var i = currentPos;
    var x;
    x = setInterval(function() {
      window.scrollTo(0, i);
      i -= 10;
      if (i <= pos) {
        clearInterval(x);
      }
    }, time);
  }
}

Demo:

<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element<p/>
<button onClick="scrollToSmoothly(Number(0))">Scroll back to top</button>
<p/>
<button onClick="scrollToSmoothly(document.body.offsetHeight)">
Scroll To Bottom
</button>
</div>
<button onClick="scrollToSmoothly(Number(500))">
Scroll to y-position 500px
</button>
<script>
function scrollToSmoothly(pos, time){
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
     if(isNaN(pos)){
      throw "Position must be a number";
     }
     if(pos<0){
     throw "Position can not be negative";
     }
    var currentPos = window.scrollY||window.screenTop;
    if(currentPos<pos){
    if(time){
    	var x;
      var i = currentPos;
      x = setInterval(function(){
         window.scrollTo(0, i);
         i += 10;
         if(i>=pos){
          clearInterval(x);
         }
     }, time);
    } else {
    var t = 10;
       for(let i = currentPos; i <= pos; i+=10){
       t+=10;
        setTimeout(function(){
      	window.scrollTo(0, i);
        }, t/2);
      }
      }
    } else {
    time = time || 2;
       var i = currentPos;
       var x;
      x = setInterval(function(){
         window.scrollTo(0, i);
         i -= 10;
         if(i<=pos){
          clearInterval(x);
         }
     }, time);
      }
}
function scrollToDiv(){
  var elem = document.querySelector("div");
  scrollToSmoothly(elem.offsetTop);
}
</script>

To scroll to a certain position in an exact amount of time, window.requestAnimationFrame can be put to use. JSFiddle WebPage Demo: http://jsfiddle.net/4xwnzgj5/embedded/result

function scrollToSmoothly(pos, time){
  /*Time is exact amount of time the scrolling will take (in milliseconds)*/
  /*Pos is the y-position to scroll to (in pixels)*/
  /*Code written by hev1*/
  if(typeof pos!== "number"){
  pos = parseFloat(pos);
  }
  if(isNaN(pos)){
   console.warn("Position must be a number or a numeric String.");
   throw "Position must be a number";
  }
  if(pos<0||time<0){
  return;
  }
  var currentPos = window.scrollY || window.screenTop;
    var start = null;
  time = time || 500;
  window.requestAnimationFrame(function step(currentTime){
    start = !start? currentTime: start;
    if(currentPos<pos){
    var progress = currentTime - start;
    window.scrollTo(0, ((pos-currentPos)*progress/time)+currentPos);
    if(progress < time){
        window.requestAnimationFrame(step);
    } else {
        window.scrollTo(0, pos);
    }
    } else {
     var progress = currentTime - start;
    window.scrollTo(0, currentPos-((currentPos-pos)*progress/time));
    if(progress < time){
        window.requestAnimationFrame(step);
    } else {
        window.scrollTo(0, pos);
    }
    }
  });
}

Demo:

<button onClick="scrollToSmoothly(Number(document.querySelector('div').offsetTop), Number(300))">
Scroll To Div (300ms)
</button>
<button onClick="scrollToSmoothly(Number(document.querySelector('div').offsetTop), Number(200))">
Scroll To Div (200ms)
</button>
<button onClick="scrollToSmoothly(Number(document.querySelector('div').offsetTop), Number(100))">
Scroll To Div (100ms)
</button>
<button onClick="scrollToSmoothly(Number(document.querySelector('div').offsetTop), 50)">
Scroll To Div (50ms)
</button>
<button onClick="scrollToSmoothly(Number(document.querySelector('div').offsetTop), Number(1000))">
Scroll To Div (1000ms)
</button>
<div style="margin: 500px 0px;">
DIV<p/>
<button onClick="scrollToSmoothly(0, 500)">
Back To Top
</button>
<button onClick="scrollToSmoothly(document.body.scrollHeight)">
Scroll To Bottom
</button>
</div>
<div style="margin: 500px 0px;">

</div>
<button style="margin-top: 100px;" onClick="scrollToSmoothly(500, 3000)">
Scroll To y-position 500px (3000ms)
</button>
<script>
function scrollToSmoothly(pos, time){
  /*Time is exact amount of time the scrolling will take (in milliseconds)*/
  /*Pos is the y-position to scroll to (in pixels)*/
  /*Code written by hev1*/
  if(typeof pos!== "number"){
  pos = parseFloat(pos);
  }
  if(isNaN(pos)){
   console.warn("Position must be a number or a numeric String.");
   throw "Position must be a number";
  }
  if(pos<0||time<0){
  return;
  }
  var currentPos = window.scrollY || window.screenTop;
	var start = null;
  time = time || 500;
  window.requestAnimationFrame(function step(currentTime){
  	start = !start? currentTime: start;
    if(currentPos<pos){
    var progress = currentTime - start;
    window.scrollTo(0, ((pos-currentPos)*progress/time)+currentPos);
    if(progress < time){
    	window.requestAnimationFrame(step);
    } else {
    	window.scrollTo(0, pos);
    }
    } else {
     var progress = currentTime - start;
    window.scrollTo(0, currentPos-((currentPos-pos)*progress/time));
    if(progress < time){
    	window.requestAnimationFrame(step);
    } else {
    	window.scrollTo(0, pos);
    }
    }
  });
}
</script>

Alternatively, you can use window.scroll which scrolls to a specific x and y position and window.scrollBy which scrolls from the current position:

// Scroll to specific values
// scrollTo is the same
window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth' 
});

// Scroll certain amounts from current position 
window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

Demo:

<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 500px 0px;">Div</div>
<script>
function scrollToDiv(){
var elem = document.querySelector("div");
window.scroll({
      top: elem.offsetTop, 
      left: 0, 
      behavior: 'smooth' 
});
}
</script>

If you only need to scroll to an element, not a specific position in the document, you can use Element.scrollIntoView with behavior set to smooth.

document.getElementById("elemID").scrollIntoView({ 
  behavior: 'smooth' 
});

Demo:

<button onClick="scrollToDiv()">Scroll To Element</button>
<div id="myDiv" style="margin: 500px 0px;">Div</div>
<script>
function scrollToDiv(){
    document.getElementById("myDiv").scrollIntoView({ 
      behavior: 'smooth' 
   });
}
</script>

Modern browsers support the scroll-behavior CSS property, which can be used to make scrolling in the document smooth (without the need for Javascript; anchor tags can be used for this by giving the anchor tag a href of # plus the id of the Element to scroll to). You can also set the scroll-behavior property for a specific element like a div to make its contents scroll smoothly.

Demo:

html, body{
  scroll-behavior: smooth;
}
a, a:visited{
  color: initial;
}

<a href="#elem">Scroll To Element</a>
<div id="elem" style="margin: 500px 0px;">Div</div>

The CSS scroll-behavior property works with Javascript as well when using window.scrollTo.

Demo:

html, body{
  scroll-behavior: smooth;
}

<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 500px 0px;">Div</div>
<script>
function scrollToDiv(){
  var elem = document.querySelector("div");
  window.scrollTo(0, elem.offsetTop);
}
</script>

To check if the scroll-behavior property is supported, you can check if it exists as a key in the style of the HTML element.

var scrollBehaviorSupported = 'scroll-behavior' in document.documentElement.style;
console.log('scroll-behavior supported:',scrollBehaviorSupported);

这篇关于如何在纯JavaScript中平滑滚动到一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆