Simon Larsen
Simon Larsen

Reputation: 59

Dynamic javascript scroll not working as intended

So I've been trying to make a dynamic scroll animation that scrolls up and down repeatedly but which can be stopped once the mouse enters the webpage's main div, and then be restarted when the cursor leaves aforementioned div, where it will take in count if the user has scrolled themselves, as well as if the amount of the content has changed

But all it does is to start the first animation correctly, to then just give up stopping at the bottom refusing to let the user scroll at all.

And when i try to trigger the stop functionality it just gives me the error "TypeError: animate(...) is undefined, can't access property 0 of it" and i have no clue why.

Any ideas?

setTimeout(function(){

    if(screen.width >= 1300 && $('#animatediv')[0].scrollHeight > 700){

        var screenview = document.getElementById('animatediv').clientHeight;
        var to = $('#animatediv')[0].scrollHeight;
        var animatetime = ((to - 700) * 800) / 80;
        var used = 0;
        var delay = 2000;
        var userscroll = 0;
        var animatescroll = 0;
        var running = 0;

        $('#main').mouseleave(function() {
            running = 1;
            userscroll = $('#animatediv').scrollTop();
            setTimeout(function(){animate(screenview, to, animatetime, used, delay, userscroll, animatescroll, running)}, delay);
        });


        $('#main').mouseenter(function() {
            running = 0;
            var news = animate(screenview, to, animatetime, used, delay, userscroll, animatescroll, running)
            used = news[0];
            to = news[1];
            $('#animatediv').stop();
            animatescroll = $('#animatediv').scrollTop();
        });

    }

}, 600);




function animate(screenview, to, animatetime, used, delay, userscroll, animatescroll, running){

    to = $('#animatediv')[0].scrollHeight;

    var time = (animatetime - used) + (animatescroll - userscroll);

    if(to != 0){
        animateto = to - screenview;
    }
    else{
        animateto = 0;
    }

    $('#animatediv').animate({ scrollTop: animateto}, time, 'linear');

    setInterval(function(){

        if(running == 0){
            var returns = [used, to]
            return returns;
        }
        if(used == animatetime){
            if(to != 0){
                to = 0;
            }
            else{
                to = $('#animatediv')[0].scrollHeight;
            }
            used = 0;
            setTimeout(function(){animate(screenview, to, animatetime, used, delay, userscroll, animatescroll)}, delay);
        }
        else{
            used++;
        }

    }, 1);

}

Upvotes: 0

Views: 295

Answers (1)

evgeni fotia
evgeni fotia

Reputation: 4810

There is to many mistakes. so I made a different one. here is the Jsfiddle

   var runnig=true, deriction = "down";
   var time = 3000, lastScrollTop = 0;
   animate($('#animatediv')[0]);
   $('#main').mouseleave(function() {
         removeAndAnimate();
	 });
   $('#main').mouseenter(function() {
        runnig = false;
        lastScrollTop = $('#animatediv')[0].scrollTop;
        if(deriction === "down"){
          deriction = "up";
        }else{
          deriction = "down";
        }
        
        $('#animatediv').stop(true);
        setTimeout(function(){
           $('#animatediv')[0].addEventListener("scroll", userScroll, false);
        }, 100);
        
	 });



async function removeAndAnimate(){
  var resultat = await ($('#animatediv')[0].removeEventListener("scroll", userScroll, false));
  runnig = true;
  animate($('#animatediv')[0]);
}



function userScroll(){
   var st = this.scrollTop; 
   if (st > lastScrollTop){
      deriction = "down";
   } else {
      deriction = "up";
   }
   lastScrollTop = st <= 0 ? 0 : st;
}
 
	function animate(element){
		
		var scrollTop = element.scrollTop;
    var heightToScroll = element.scrollHeight - $(element).height();
		var animateto = 0, delay = 0;
		if(scrollTop != 0){
      if(deriction === "down"){
        animateto = heightToScroll;
        delay = (heightToScroll - scrollTop)*time/heightToScroll;
      }else{
        delay = scrollTop*time/heightToScroll;
      }
		}else{
      animateto = heightToScroll;
      delay = time;
    }

    
    if(deriction === "down"){
      deriction = "up";
    }else{
      deriction = "down"
    }
		
		$('#animatediv').animate({ scrollTop: animateto}, delay, 'linear', function(){
      if(runnig){
        animate(element);
      }
    });
		
	}
*{
	font-size: 62,5%;
	margin: 0;
	padding: 0;
}

body{
	background-color: #F5E7D3;
}

#main{
	width: 90%;
	margin: auto;
	text-align: center;
	background: linear-gradient(to bottom, #FFF1C4 20%, #72982D);
	/* overflow: hidden; */
	height: 350px;
}

#animatediv{
  border: 1px solid black;
	width: 50%;
	float: right;
	height: 300px;
	overflow-y: auto;
	overflow-x: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='main'>
  <div id='animatediv'>
    grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />grsgfes
    <br />
  </div>
</div>

Upvotes: 1

Related Questions