【问题标题】:How Can I get my Javascript "Animation" to Work Better?如何让我的 Javascript“动画”更好地工作?
【发布时间】:2020-04-04 01:52:40
【问题描述】:

我正在尝试为悬停在某些文本上的不断增长的省略号设置动画,然后在鼠标悬停时消失。我已经设法创建了效果,但前提是用户非常小心地将光标移动到受影响的元素上。我怎样才能让它表现得更好,这样如果用户将光标移动到所有元素上,我就不会得到你在下面看到的错误行为(尝试快速在元素上运行光标)?我已经尝试过 setInterval 并且发现问题更加严重。任何帮助表示赞赏。谢谢。

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>

【问题讨论】:

    标签: javascript jquery html css animation


    【解决方案1】:

    您的代码的主要问题是您只使用一个标志变量 (mousedOver) 来确定 3 个动画中的任何一个何时应该处于活动状态。因此,如果有人将鼠标移到其中一个元素上,它会等待 1000 毫秒并将标志设置为 1,然后说“好的,我将等待 1000 毫秒并再次检查 mousedOver 是否仍为 1”。如果用户将鼠标移开(将 mousedOver 设置为 0)然后在 1000 毫秒之前移动到另一个元素(将 mousedOver 设置为 1),那么当第一个元素再次检查并看到 mousedOver 仍然是 1 ,它没有理由停止动画。

    有几种方法可以解决这个问题:

    首先,您可以为每个元素使用不同的标志,您可以确定该特定元素何时应取消其超时。这需要做更多的工作,但可能会让事情更容易阅读和理解。

    另一种 JS 解决方案使用clearTimeout 方法:将每个超时 ID 存储在一个变量中,以便您可以在鼠标输出时“清除”/取消它们:

    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);
    
    

    请注意,您只需要一个 timeoutID 变量,因为您将在创建新的超时之前清除任何现有的超时 (onmouseout)。

    最后,一个纯 CSS 的方法。由于您使用的是 CSS flex,我假设您可以使用 CSS3。除了添加/删除这些椭圆,您可以考虑始终将它们放在那里并更改颜色或不透明度,即将 CSS colorrgba(0, 0, 0, 0) 更改为 rgba(0, 0, 0, 1)opacity0 更改为 1 .在使用其中一个 JS 进程时,这甚至可能是一个好主意,因为至少那时您知道显示点时文本不会四处移动。

    此选项与上述选项在视觉上的主要区别在于,这些选项会显示一些“淡入”,这可能不是您想要的。下面的代码展示了如何设置所有的“第一个”点(设置第二个和第三个类似)。

    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 */
    
    

    【讨论】:

    • 嘿,非常感谢!我一夜之间意识到问题可能是回调的等待时间。我最终让它工作了(到目前为止哈哈哈),但你已经指出了我还没有解决的以前的设置有什么问题。再次感谢你!我也会试试 CSS!
    猜你喜欢
    • 1970-01-01
    • 2012-01-29
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2015-08-16
    • 2012-03-24
    • 1970-01-01
    相关资源
    最近更新 更多