Проблемы с анимацией в Safari (iPhone) - при первом нажатии анимация срабатывает только один раз - PullRequest
0 голосов
/ 06 февраля 2019

Я играл с CSS-анимациями, так как хотел освежить в памяти (я на самом деле не использовал их, поскольку они были просто прототипами!)

У меня есть простая страница с 5 кнопками.Камень, Бумага, Ножницы, Ящерица, Спок.Когда нажимается каждая кнопка, вызывается функция JS, передавая имя действия, например, «камень», который добавляет несколько классов в мой div.Одна из которых имеет анимацию.Эта часть отлично работает.

У меня есть кнопка тестирования, которая переключает действия, изменяет классы и добавляет анимацию "встряхивания".

Мне удалось получить ее кросс-браузерсовместимо, кроме как через мой телефон (браузер Safari), где при начальной загрузке страницы не будет запускаться первая из двух анимаций (shake2) 5 раз (animation-iteration-count: 5).Дело в том, что ... с последующими щелчками, это, кажется, работает отлично!

Мне удалось найти способ обойти это, добавив эти классы в div при загрузке страницы, с дополнительным классом, заставляя это "показывать: никто".Единственная проблема заключается в том, что если я затем нажимаю одну из кнопок, чтобы установить действие, то при следующем нажатии кнопки тестирования у меня возникает та же проблема, что и при загрузке страницы.Итерация для моего встряхивания запускается только один раз.

Я добавил «консоль» внизу страницы, чтобы отслеживать, какие классы присоединены.Мой код очень грязный, так как я много пробовал и добавил несколько вещей, пытаясь предотвратить возникновение этого глюка.

Добавление «battleHide» к элементу поля боя при начальной загрузке исправило эту проблему,но это - последующие щелчки, которые сбивают меня с толку.

    $(document).ready(function() {
  $('[data-toggle="tooltip"]').tooltip();
});

// Declare variables
var audio = document.getElementsByTagName("audio")[0];
var rpslsList = ["rock", "paper", "scissors", "lizard", "spock"];
var lastElement = rpslsList[rpslsList.length - 1];
var element = document.getElementById("battlefield");

// playBattleAnimation Function (Cycles through attacks)
function playBattleAnimation() {
  logClasses("before");

  if (element.classList.contains("battlefield")) {
    element.classList.remove("battlefield");
  }

  if (element.classList.contains("elementToFadeIn")) {
    element.classList.remove("elementToFadeIn");
  }

  if (element.classList.contains("battleHide")) {
    element.classList.remove("battleHide");
  } else {
    element.classList.add("battleHide");
    void element.offsetWidth;
    logClasses("none");
    alert(element.classList);
    element.classList.remove("battleHide");
  }

  void element.offsetWidth;
  element.classList.add("battlefield");
  loopThroughAttacks(rpslsList);

  // LOOK AT ADDING BATTLEHIDE AFTER ITEM SELECTED? Only issue is this will hide it...
  window.setTimeout(function(){logClasses("after");}, 2500);
}

// Function to log classes attached to Battlefield during each state
function logClasses(state) {
  var classString = element.classList;
  classString = classString
    .toString()
    .split(" ")
    .join(", ");

  if (classString === "") {
    classString = "No Classes";
  }

  document.getElementById("test").innerHTML +=
    (state === "before" ? "<hr />" : "") +
    (state != "none"
      ? state.charAt(0).toUpperCase() + state.slice(1) + ": ["
      : " [") +
    classString +
    "] - " +
    element.classList.length +
    " Classes" +
    (state === "after" ? "<hr /><br />" : "<br />");
}

// setBattlefield Function - Sets main area to specific icon
function setBattlefield(action) {
  // declare the variables we want to use
  var name, arr;

  // Call our log class to set an entry before processing
  logClasses("before");

  // Reset & play our sound effect
  audio.currentTime = 0;
  audio.play();

  // If no action has been passed in, set the class to be added to empty
  if (action === undefined) {
    name = "";
  } else {
    name = "far fa-hand-" + action;
  }

  // Clear all classes from element
  element.className = "";

  // Reset the animation process
  void element.offsetWidth;

  // Add the new class containing our animation
  element.classList.add("elementToFadeIn");

  //alert(element.classList);

  // Split className on spaces
  arr = element.className.split(" ");

  // If class isn't in our new split array, add it.
  if (arr.indexOf(name) == -1) {
    element.className += " " + name;
  }

  // Write log record for classes "after"
  window.setTimeout(function(){logClasses("after");}, 1000);
}

// Function to loop through our attacks array
function loopThroughAttacks(rpslsList) {
  for (var i = 0; i < rpslsList.length; i++) {
    (function(i) {
      setTimeout(function() {
        document.getElementById("test").innerHTML +=
          "<i class='far fa-hand-" + rpslsList[i] + "'></i> ";
        element = document.getElementById("battlefield");

        audio.currentTime = 0;
        audio.play();

        if (i > 0) {
          name = "fa-hand-" + rpslsList[i - 1];
          element.classList.remove("far", name);
        } else if (element.classList.contains("far")) {
          rpslsList.forEach(function(entry) {
            //console.log(entry);
            if (element.classList.contains("fa-hand-" + entry)) {
              element.classList.remove("far", "fa-hand-" + entry);
            }
          });
        }

        void element.offsetWidth;
        name = "far fa-hand-" + rpslsList[i];
        arr = element.className.split(" ");

        if (arr.indexOf(name) == -1) {
          element.className += " " + name;
        }

        logClasses("none");
      }, 500 * i);
    })(i);
  }
}

Существует много кода, поэтому я только что включил js и имею кодовую ручку для CSS и т. д .: https://codepen.io/IDemixI/pen/jdVaBM

Мне бы хотелось, чтобы это завершило 5 итераций первой анимации, как это происходит в любом другом браузере, в котором я пробовал.

...