Scroll animation in plain JavaScript - Stack Overflow

I am trying to build a scroll animation section when visitors click on the anchor. As you might notice

I am trying to build a scroll animation section when visitors click on the anchor. As you might notice the variable "id" will show #1, this will match the id value of the section itself. How could I add the scroll animation to this javascript?

var section = document.getElementsByTagName("section"),
  nav = document.getElementById("nav-bar"),
  navHeight = nav.offsetHeight,
  navAnchor = nav.querySelectorAll("li a");

for (var i = 0; i < navAnchor.length; i++) {
  var element = navAnchor[i];

  element.addEventListener("click", function(e) {
    e.preventDefault();
    var el = this,
      id = el.getAttribute("href");

    function scrollTo(element, to, duration) {
      var element = element,
        to = section + id;
      console.log(id);
      if (duration <= 0) {
        return;
      }
      var difference = to - element.scrollTop;
      var perTick = difference / duration * 10;
      consolelo

      setTimeout(function() {
        element.scrollTop = element.scrollTop + perTick;
        if (element.scrollTop === to) return;
        scrollTo(element, to, duration - 10);

      }, 500);
    }
  });
}
ul li {
  list-style-type: none;
  display: inline-block;
}

li a {
  text-decoration: none;
  display: block;
  width: 120px;
  padding-top: 10px;
  padding-bottom: 10px;
  border: 1px solid black;
  text-align: center;
}

section {
  width: 100%;
  height: 300px;
  border: 1px solid red;
}
<div class="nav-block" id="nav-bar">
  <ul class="navbar-unordered-list">
    <li class="link">
      <a href="#1" class="active">Profile</a>
    </li>

    <li class="link">
      <a href="#2" class="scroll">Personal Project</a>
    </li>

    <li class="link">
      <a href="#3" class="scroll">Skills</a>
    </li>

    <li class="link">
      <a href="#4" class="scroll">CSS Drawings</a>
    </li>

    <li class="link">
      <a href="#5" class="scroll">Contact</a>
    </li>
  </ul>
</div>

<section class="sections section1" id="1">
  1
</section>

<section class="sections section2" id="2">
  2
</section>

<section class="sections section3" id="3">
  3
</section>

<section class="sections section4" id="4">
  4
</section>

<section class="sections section5" id="5">
  5
</section>

I am trying to build a scroll animation section when visitors click on the anchor. As you might notice the variable "id" will show #1, this will match the id value of the section itself. How could I add the scroll animation to this javascript?

var section = document.getElementsByTagName("section"),
  nav = document.getElementById("nav-bar"),
  navHeight = nav.offsetHeight,
  navAnchor = nav.querySelectorAll("li a");

for (var i = 0; i < navAnchor.length; i++) {
  var element = navAnchor[i];

  element.addEventListener("click", function(e) {
    e.preventDefault();
    var el = this,
      id = el.getAttribute("href");

    function scrollTo(element, to, duration) {
      var element = element,
        to = section + id;
      console.log(id);
      if (duration <= 0) {
        return;
      }
      var difference = to - element.scrollTop;
      var perTick = difference / duration * 10;
      consolelo

      setTimeout(function() {
        element.scrollTop = element.scrollTop + perTick;
        if (element.scrollTop === to) return;
        scrollTo(element, to, duration - 10);

      }, 500);
    }
  });
}
ul li {
  list-style-type: none;
  display: inline-block;
}

li a {
  text-decoration: none;
  display: block;
  width: 120px;
  padding-top: 10px;
  padding-bottom: 10px;
  border: 1px solid black;
  text-align: center;
}

section {
  width: 100%;
  height: 300px;
  border: 1px solid red;
}
<div class="nav-block" id="nav-bar">
  <ul class="navbar-unordered-list">
    <li class="link">
      <a href="#1" class="active">Profile</a>
    </li>

    <li class="link">
      <a href="#2" class="scroll">Personal Project</a>
    </li>

    <li class="link">
      <a href="#3" class="scroll">Skills</a>
    </li>

    <li class="link">
      <a href="#4" class="scroll">CSS Drawings</a>
    </li>

    <li class="link">
      <a href="#5" class="scroll">Contact</a>
    </li>
  </ul>
</div>

<section class="sections section1" id="1">
  1
</section>

<section class="sections section2" id="2">
  2
</section>

<section class="sections section3" id="3">
  3
</section>

<section class="sections section4" id="4">
  4
</section>

<section class="sections section5" id="5">
  5
</section>

Share Improve this question edited May 1, 2017 at 12:16 Front-end Developer asked Apr 29, 2017 at 16:03 Front-end DeveloperFront-end Developer 4101 gold badge7 silver badges17 bronze badges 4
  • 2 "There are tons of examples of scroll animations in jQuery, but not much of JavaScript." The jQuery ones are in JavaScript. They're just using jQuery instead of using the DOM directly. – T.J. Crowder Commented Apr 29, 2017 at 16:05
  • I meant vanilla JavaScript – Front-end Developer Commented Apr 29, 2017 at 16:08
  • You need to preventDefault – mplungjan Commented Apr 29, 2017 at 16:11
  • 1 It's still vanilla JavaScript. Using a library doesn't change the language you're working with. The distinction is between "using jQuery" and "using the DOM directly," it has nothing whatsoever to do with the language. – T.J. Crowder Commented Apr 29, 2017 at 16:11
Add a ment  | 

5 Answers 5

Reset to default 7

The reason you see it move at all is that you haven't prevented the default action of following the link, which takes you to the anchor the link references. :-)

Separately from that, the scrollTo function shouldn't be inside the event handler.

Assuming you want to adjust the main scrollbar, I wouldn't use setInterval, I'd use requestAnimationFrame, see ments:

var section = document.getElementsByTagName("section"),
  nav = document.getElementById("nav-bar"),
  navHeight = nav.offsetHeight,
  navAnchor = nav.querySelectorAll("li a"),
  animate = findAnimationElement();

for (var i = 0; i < navAnchor.length; i++) {
  var element = navAnchor[i];

  element.addEventListener("click", function(e) {
    var el = this,
      id = el.getAttribute("href");

    e.preventDefault(); // <=== Don't follow the link
    scrollTo(document.getElementById(id.substring(1)), 300);
    // Skip the "#" on "#1" -----------^^^^^^^^^^^^^
  });
}

function findAnimationElement() {
  // Webkit browsers animate `body`, others animate `html` (the document element)
  var bodyCurrent = document.body.scrollTop;
  var docElCurrent = document.documentElement.scrollTop;
  document.documentElement.scrollTop = document.body.scrollTop = 10;
  var animate;
  if (document.body.scrollTop > 0) {
    animate = document.body;
    document.body.scrollTop = bodyCurrent;
  } else {
    animate = document.documentElement;
    document.documentElement.scrollTop = docElCurrent;
  }
  return animate;
}

function scrollTo(to, duration) {
  // When should we finish?
  var finishAt = Date.now() + duration;
  
  // Start
  requestAnimationFrame(tick);

  function tick() {
    // How many frames left? (60fps = 16.6ms per frame)
    var framesLeft = (finishAt - Date.now()) / 16.6;
    
    // How far do we have to go?
    var distance = to.getBoundingClientRect().top;
    if (distance <= 0) {
      // Done (this shouldn't happen, belt & braces)
      return;
    }
    
    // Adjust by one frame's worth
    if (framesLeft <= 1) {
      // Last call
      animate.scrollTop += distance;
    } else {
      // Not the last, adjust and schedule next
      animate.scrollTop += Math.max(1, distance / framesLeft);
      requestAnimationFrame(tick);
    }
  }
}
ul li {
  list-style-type: none;
  display: inline-block;
}

li a {
  text-decoration: none;
  display: block;
  width: 120px;
  padding-top: 10px;
  padding-bottom: 10px;
  border: 1px solid black;
  text-align: center;
}

section {
  width: 100%;
  height: 300px;
  border: 1px solid red;
}
<div class="nav-block" id="nav-bar">
  <ul class="navbar-unordered-list">
    <li class="link">
      <a href="#1" class="active">Profile</a>
    </li>

    <li class="link">
      <a href="#2">Personal Project</a>
    </li>

    <li class="link">
      <a href="#3">Skills</a>
    </li>

    <li class="link">
      <a href="#4">CSS Drawings</a>
    </li>

    <li class="link">
      <a href="#5">Contact</a>
    </li>
  </ul>
</div>

<section class="sections section1" id="1">
  1
</section>

<section class="sections section2" id="2">
  2
</section>

<section class="sections section3" id="3">
  3
</section>

<section class="sections section4" id="4">
  4
</section>

<section class="sections section5" id="5">
  5
</section>

try to use this

function animate(elem, style, unit, from, to, time, prop) {
    if (!elem) {
        return;
    }
    var start = new Date().getTime(),
        timer = setInterval(function () {
            var step = Math.min(1, (new Date().getTime() - start) / time);
            if (prop) {
                elem[style] = (from + step * (to - from))+unit;
            } else {
                elem.style[style] = (from + step * (to - from))+unit;
            }
            if (step === 1) {
                clearInterval(timer);
            }
        }, 25);
    if (prop) {
          elem[style] = from+unit;
    } else {
          elem.style[style] = from+unit;
    }
}

window.onload = function () {
    var target = document.getElementById("div5");
    animate(document.scrollingElement || document.documentElement, "scrollTop", "", 0, target.offsetTop, 2000, true);
};

I see what you're getting at...

The only way to move the window with JS (Pure) is to create a progressive frame animation. You can do that as follows...

function animate() {
var nave = document.getElementById("navAnchor"); 
var id = setInterval(frame, 40);
var top = nave.offfset.top;
  function frame() {
    if (pos == 100) {
        clearInterval(id);
    } else {
        pos++; 
        nave.style.top = pos + 'px';
    }
  }
}

If you are open, you're life might be simplified if you allowed for Jquery which has animation controls built in.

$("nav").click(function() {
    $("#navAnchor").animate({
        top: 200;
    });
};

Another, less elegant, option is to shift the entire body using a CSS animation and JS button.

I have found a solution that is much more readible. Enjoy!

"use strict";

(function() {

  // Scroll function
  const scrollTo = (element, to, duration) => {
    if (duration <= 0) {
    	return;
    }
    const difference = to - element.scrollTop;
    const perTick = difference / duration * 10;
    
    setTimeout(() => {
		element.scrollTop = element.scrollTop + perTick;
		if (element.scrollTop === to) {
			return;
		}
		scrollTo(element, to, duration - 10);
    }, 1);
  }
  
// Top Navigation
// Save DOM elements that can be scrolled to
// let targetElements = {};

let targetElements = {};

(function() {
	var section = document.getElementsByTagName("section");
	targetElements = section;	
})();

// Select links with scroll action
const scrollElements = document.getElementsByClassName('scroll');

// Add event listeners to navigation links with scroll action
Array.prototype.forEach.call(scrollElements, scrollElement => {
	scrollElement.addEventListener('click', event => {
	  	event.preventDefault(); // avoid jumping

	  	const targetElement = targetElements[(scrollElement.getAttribute('href').slice(1))];
	  	scrollTo(document.body, targetElement.offsetTop, 1000);
	});
});
})();

You can use the jQuery. With just a few lines of code! First, put the following link inside the head:

    ```
    <script
    src="https://code.jquery./jquery-3.5.1.min.js"
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
    crossorigin="anonymous"></script>
    ```

Then:

    ```
    <script>            
    $('#btn').click(function () {
            $('body, html').animate({
                'scrollTop': 100 // <--- How far from the top of the screen?100?
            }, 1000);// <---time = 1s
        });
    </script>
    ```

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745116102a4612136.html

相关推荐

  • Scroll animation in plain JavaScript - Stack Overflow

    I am trying to build a scroll animation section when visitors click on the anchor. As you might notice

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信