简体   繁体   中英

On Scroll Animated Skill Bar isn't working

I am working with my Portfolio and I am stuck in animated skill bar. I am using JQuery and I have followed different tutorials but none of them isn't working in my project. I have calculate section scroll position and window scroll position. I changed Parent div and child div, but the result are same. Here is My Code

 $(document).ready(function() { var skillBar = $('.skill-body'); $(window).scroll(function() { var SkillLocation = $("#Education-Skill").offset().top; var scrollLocation = $(this).scrollTop(); skillBar.each(function() { if (SkillLocation <= scrollLocation) { $(this).find('.inner-skill-bar').animate({ width: $(this).attr('data-percent') }, 2000); } }); }); });
 .outer-skill-bar { height: 26px; width: 100%; border: 1px solid black; } .inner-skill-bar { height: 100%; width: 0%; background: lightcoral; border-right: 0.5px solid rgb(146, 136, 136); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container" id="Education-Skill"> <div class="row"> <div class="col-md-6 skill" id="skill"> <div class="all-skill"> <div class="my-skill"> <div class="skill-head d-flex"> <i class="fab fa-html5 fa-lg"></i> <p>HTML5</p> </div> <div class="skill-body d-flex" data-percent="90%"> <div class="outer-skill-bar"> <div class="inner-skill-bar"></div> </div> <div class="percent"> <p class="skill-value">90%</p> </div> </div> </div> <!--my-skill--> <div class="my-skill"> <div class="skill-head d-flex"> <i class="fab fa-css3-alt fa-lg"></i> <p>CSS3</p> </div> <div class="skill-body d-flex" data-percent="80%"> <div class="outer-skill-bar"> <div class="inner-skill-bar"></div> </div> <div class="percent"> <p class="skill-value">80%</p> </div> </div> </div> <!--my-skill--> </div> <!--all skill--> </div> <!--col--> </div> <!--row--> </div> <!--Container-->

You just have to decrease the skillPosition variable a bit, so that it starts the animation when it appears on your screen. For this example I just used - 100 , but you can tailor it any way you want:

 $(document).ready(function(){ var skillBar = $('.skill-body'); $(window).scroll(function(){ var SkillLocation = $("#Education-Skill").offset().top; var scrollLocation = $(this).scrollTop(); skillBar.each(function(){ if(SkillLocation - 100 <= scrollLocation) { $(this).find('.inner-skill-bar').animate({width:$(this).attr('data-percent')}, 2000); } }); }); });
 .vertical-offset { width: 100%; height: 250px; } .outer-skill-bar{ height: 26px; width: 100%; border: 1px solid black; } .inner-skill-bar{ height: 100%; width: 0%; background: lightcoral; border-right: 0.5px solid rgb(146, 136, 136); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="vertical-offset">Scroll down...</div> <div class="container" id="Education-Skill"> <div class="row"> <div class="col-md-6 skill" id="skill"> <div class="all-skill"> <div class="my-skill"> <div class="skill-head d-flex"> <i class="fab fa-html5 fa-lg"></i> <p>HTML5</p> </div> <div class="skill-body d-flex" data-percent="90%"> <div class="outer-skill-bar"> <div class="inner-skill-bar"></div> </div> <div class="percent"> <p class="skill-value">90%</p> </div> </div> </div> <!--my-skill--> <div class="my-skill"> <div class="skill-head d-flex"> <i class="fab fa-css3-alt fa-lg"></i> <p>CSS3</p> </div> <div class="skill-body d-flex" data-percent="80%"> <div class="outer-skill-bar"> <div class="inner-skill-bar"></div> </div> <div class="percent"> <p class="skill-value">80%</p> </div> </div> </div> <!--my-skill--> </div><!--all skill--> </div> <!--col--> </div> <!--row--> </div> <!--Container--> <div class="vertical-offset"></div>

Don't use scroll event listener for this kind of stuff, it's bad for browser performance.

You should rather use Intersection Observer (IO) for this, this was designed for such problems. With IO you can react whenever an HTML element intersects with another one (or with the viewport)

Check this page , it shows you how to animate an element once it comes into viewport (scroll all the way down)

Short recap on what you have to do:

First you have to create a new observer:

var options = {
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

Here we define that once your target Element is 100% visible in the viewport (threshold of 1) your callback Function is getting executed. Here you can define another percentage, 0.5 would mean that the function would be executed once your element is 50% visible.

Then you have to define which elements to watch, in your case this would be the counter elements:

var target = document.querySelector('.counter');
observer.observe(target);

Last you need to specify what should happen once the element is visible in your viewport by defining the callback function:

var callback = function(entries, observer) { 
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // here you animate the skill bar
  });
};

If you need to support older browsers, use the official polyfill from w3c.

If you don't want to trigger the animation again when the elements are scrolled again into view a second time then you can also unobserve an element once it's animated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM