Как я могу заставить мою Javascript «Анимацию» работать лучше? - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь оживить растущий многоточие, добавленное к некоторому тексту при наведении курсора, а затем vani sh при наведении мыши. Мне удалось создать эффект, но только если пользователь очень деликатно относится к перемещению курсора на воздействующие элементы. Как я могу заставить это работать лучше, чтобы, если пользователь перемещает курсор по всем элементам, я не получаю ошибочное поведение, которое вы видите ниже (попробуйте быстро навести курсор на элементы)? Я уже попробовал 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>

1 Ответ

1 голос
/ 03 апреля 2020

Основная проблема с вашим кодом состоит в том, что вы используете только одну переменную флага (mousedOver), чтобы определить, когда любая из 3 анимаций должна быть активной. Поэтому, если кто-то наводит указатель мыши на один из элементов, он ждет 1000 мс и устанавливает флаг в 1, а затем говорит: «Хорошо, я подожду 1000 мс и еще раз проверим, равно ли mousedOver 1». Если пользователь отодвигает свою мышь (установка mousedOver на 0), затем перемещается на другой элемент (установка mousedOver на 1) до того, как будет установлено значение 1000 мс, тогда, когда первый элемент снова проверяет и видит, что mousedOver по-прежнему равен 1 , у него нет причин останавливать анимацию.

Есть несколько способов исправить это:

Прежде всего, вы можете использовать разные флаги для каждого элемента, который вы можете определить, когда это указывает * Элемент 1032 * должен отменить свое время ожидания. Это немного больше работы, но может облегчить чтение и понимание.

Другое решение JS использует метод clearTimeout: сохраняйте каждый ID тайм-аута в переменной, чтобы вы могли «очистить» / отмените их 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);

Обратите внимание, вам нужна только одна переменная timeoutID, так как вы будете очищать любой существующий тайм-аут (onmouseout) перед созданием нового.

Наконец, CSS -только метод. Поскольку вы используете CSS flex, я предполагаю, что вы можете использовать CSS3. Вместо добавления / удаления этих эллипсов вы можете всегда иметь их там и изменять цвет или непрозрачность, то есть CSS color с rgba(0, 0, 0, 0) на rgba(0, 0, 0, 1) или opacity с 0 на 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 */

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...