简体   繁体   中英

How Can I get my Javascript “Animation” to Work Better?

I am trying to animate a growing ellipsis appended to some text when hovered over, and then vanish on mouseout. I have managed to create the effect, but only if the user is very delicate about moving the cursor over the effected elements. How can I get this to perform better, so that if the user moves the cursor all over the elements I don't get the buggy behavior you see below (try running the cursor across the elements quickly)? I've already tried and saw that the problems were even worse. ,发现问题更严重。 Any help is appreciated. Thank you.

 var i=1; var $test=$(); var mousedOver=0; function test() { if(i.==0) { $test.append('<span class="a">;</span>'). } else { $('.a');remove(); } if(mousedOver===1){ i=(i+1)%4, setTimeout(test;1000). } } $('.nav>p'),on('mouseover';function() { var $test2=$(this); setTimeout(function() { $test=$test2; mousedOver=1; test(), };1000). }) $('.nav>p'),on('mouseout';function() { $test=$(); mousedOver=0. $('.a');remove(); i=1; })
 .nav { display: flex; height: 100vh; width:30%; flex-direction: column; justify-content: center; align-items: center; border-radius:40px; border-style: solid; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <head> </head> <body> <div class="nav"> <p>text1</p> <p>text2</p> <p>text3</p> </div> </body>

The main issue with your code is that you are only using one flag variable ( mousedOver ) to determine when any of the 3 animations should be active. So if someone moves their mouse over one of the elements it waits 1000ms and sets the flag to 1, then says "ok I'll wait 1000ms and check again if mousedOver is still 1". If the user moves their mouse away (setting mousedOver to 0) then moves onto another element (setting the mousedOver to 1) before that 1000ms is up then when the first element checks again and sees that mousedOver is still 1, it has no reason to stop the animation.

There are few ways to fix this:

First of all, you could use a different flag for each element you can determine when that specific element should cancel its timeouts. This is a little more work, but might keep things easier to read and understand.

Another JS solution uses clearTimeout method: store each timeout ID in a variable, so that you can "clear"/cancel them onmouseout:

JavaScript


var timeoutID = null;

// Whenever you set a timeout, store its index to be cleared if necessary
timeoutID = setTimeout(test,1000);

// inside the "mouseout" handler
clearTimeout(timeoutID);

Note, you only need one timeoutID variable, as you would be clearing any existing timeout (onmouseout) before a new one is created.

Finally, a CSS-only method. Since you are using CSS flex, I assume you can use CSS3. Instead of adding/removing these ellipses, you can consider always having them there and changing the color or opacity, that is changing the CSS color from rgba(0, 0, 0, 0) to rgba(0, 0, 0, 1) or opacity from 0 to 1 . This might even a good idea when using one of the JS processes, because at least then you know the text won't move around when the dots are shown.

The main difference visually between this option and above is that these will show some "fading in", which might not be what you want. The code below shows how to set up all the "first" dots (setting up the second and third is similar).

CSS


@keyframes show-first-dot {
  /* Start all the animations transparent */
  0% {
    color: rgba(0, 0, 0, 0);
  }

  /* End transparency at a different % for each dot to control when it fades in */
  50% {
    color: rgba(0, 0, 0, 0);
  }

  /* End all the animations opaque */
  100% {
    color: rgba(0, 0, 0, 1);
  }
}

/* keep dot transparent by default */
.nav > p a {
  color: rgba(0, 0, 0, 0);
}

/* Keep each dot opaque after animation ends */
.nav > p:hover a {
  color: rgba(0, 0, 0, 1);
}

/* Use CSS selectors to assign animations to each dot */
.nav > p:hover a:first-of-type {
  animation-name: show-first-dot;
  animation-duration: 1s;
}

/* ... set up an animation for nth-of-type(2), etc. for as many dots as you want */

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