если еще перестает работать в определенных условиях - PullRequest
2 голосов
/ 08 января 2020

Я придумал этот простой код, но по какой-то причине он не всегда работает именно так, как мне бы хотелось.

Вот что у меня есть. Есть плитки, которые переворачиваются при наведении. Есть два возможных сценария ios и две реакции.

Если мышь наведена на плитку, плитка должна перевернуться на 180 ° и остаться в этом положении. Это происходит, если отпуск мышью происходит дольше, чем за 1 секунду. После отмены тайл должен вернуться в исходное состояние.

Если мышь наводится на плитку и сразу же появляется, мозаика должна сделать полный поворот на 180 °, прежде чем вернуться в исходное состояние. Это происходит, когда мышь уходит в течение 1 секунды. В этом случае сценарии JS ждут окончания перехода CSS, прежде чем перевернуть плитку обратно.

Теперь это работает нормально, пока не произойдет второй сценарий. Затем по какой-то причине плитка возвращается в исходное состояние после полного перехода, несмотря на то, что мышь не покидает плитку. Это почему? Любые идеи о том, как преодолеть эту проблему?

Спасибо.

$(function() {
    var timeoutId;
    $(".tile").mouseenter(function() {
        $(this).addClass("flip");
        if (!timeoutId) {
            timeoutId = window.setTimeout(function() {
                timeoutId = null;}, 1000);
        }
    });
    $(".tile").mouseleave(function() {
        if (timeoutId) {
            $(this).on('transitionend webkitTransitionEnd oTransitionEnd', function () {
                $(this).removeClass("flip");
                window.clearTimeout(timeoutId);
                timeoutId = null;
            });
        }
        else {
            $(this).removeClass("flip");
        }
    });
})
body {
    text-align: center;
    background-color: #FFFFFF;
    color: #454545;
}

.flex-container {
    padding: 0;
    margin: 0;
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-flex-flow: row;
    justify-content: space-around;
}
.tile {
    background: #454545;
    margin: 0px;
    font-weight: bold;
    flex: 1 0 auto;
    height: auto;
    border: 1px solid #454545;
    border-radius: 10%;
}
.tile:before {
    content: '';
    float: left;
    padding-top: 100%;
}
.tile-inner {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 10%;
    transform-style: preserve-3d;
    transition: transform 4s;
}

.tile.flip .tile-inner {
    transform: rotate3d(-1, 1, 0, 180deg);
    transition: transform 1s;
}

.tile-front, .tile-off, .tile-semi, .tile-rsemi, .tile-on {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    border-radius: 10%;
}

.tile-front {
    background-color: #1c1c1c;
    background-size: 100%;
}

.tile-off {
    background-color: #252525;
    transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-semi {
    background: linear-gradient(to right bottom, #252525 50%, #dedede 50%);
    transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-rsemi {
    background: linear-gradient(to right bottom, #dedede 50%, #252525 50%);
    transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-on {
    background-color: #dedede;
    transform: rotate3d(-1, 1, 0, 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<body>
  <div class="flex-container">
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-semi"></div>
      </div>
    </div>
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-on"></div>
      </div>
    </div>
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-rsemi"></div>
      </div>
    </div>
  </div>
</body>

Ответы [ 2 ]

1 голос
/ 08 января 2020

Вы используете одну переменную и используете ее для всех остальных тайлов. Таким образом, тайм-аут для тайла 1 также будет с тайлом 2, когда вы наведете на него курсор мыши. Вы должны установить таймауты для каждого из них в отдельности. Основа c идея с данными.

$(function() {
  $(".tile").mouseenter(function() {
    var elem = $(this);
    elem.addClass("flip");
    if (!elem.data('timeoutId')) {
      var tid = window.setTimeout(function() {
        elem.removeData('timeoutId')
      }, 1000);
      elem.data('timeoutId', tid)
    }
  });
  $(".tile").mouseleave(function() {
    var elem = $(this);
    var timeoutId = elem.data('timeoutId')
    if (timeoutId) {
      window.clearTimeout(timeoutId);
      elem.removeData('timeoutId')
      elem.off('transitionend webkitTransitionEnd oTransitionEnd')
      elem.on('transitionend webkitTransitionEnd oTransitionEnd', function() {
        elem.removeClass("flip");
      });
    } else {
      $(this).removeClass("flip");
    }
  });
})
body {
  text-align: center;
  background-color: #FFFFFF;
  color: #454545;
}

.flex-container {
  padding: 0;
  margin: 0;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row;
  justify-content: space-around;
}

.tile {
  background: #454545;
  margin: 0px;
  font-weight: bold;
  flex: 1 0 auto;
  height: auto;
  border: 1px solid #454545;
  border-radius: 10%;
}

.tile:before {
  content: '';
  float: left;
  padding-top: 100%;
}

.tile-inner {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 10%;
  transform-style: preserve-3d;
  transition: transform 4s;
}

.tile.flip .tile-inner {
  transform: rotate3d(-1, 1, 0, 180deg);
  transition: transform 1s;
}

.tile-front,
.tile-off,
.tile-semi,
.tile-rsemi,
.tile-on {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  border-radius: 10%;
}

.tile-front {
  background-color: #1c1c1c;
  background-size: 100%;
}

.tile-off {
  background-color: #252525;
  transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-semi {
  background: linear-gradient(to right bottom, #252525 50%, #dedede 50%);
  transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-rsemi {
  background: linear-gradient(to right bottom, #dedede 50%, #252525 50%);
  transform: rotate3d(-1, 1, 0, 180deg);
}

.tile-on {
  background-color: #dedede;
  transform: rotate3d(-1, 1, 0, 180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<body>
  <div class="flex-container">
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-semi"></div>
      </div>
    </div>
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-on"></div>
      </div>
    </div>
    <div class="tile">
      <div class="tile-inner">
        <div class="tile-front"></div>
        <div class="tile-rsemi"></div>
      </div>
    </div>
  </div>
</body>
0 голосов
/ 08 января 2020

Проблема в том, что при запуске:

if (timeoutId) {
    $(this).on('transitionend webkitTransitionEnd oTransitionEnd', function () {
        $(this).removeClass("flip");
        window.clearTimeout(timeoutId);
        timeoutId = null;
    });
}

Событие остается в элементе неопределенно долго. Таким образом, при следующем наведении на элемент, когда он завершит переход, это событие снова сработает.

Что вам, вероятно, нужно, это запустить только событие once:

if (timeoutId) {
    $(this).once('transitionend webkitTransitionEnd oTransitionEnd', function () {
        $(this).removeClass("flip");
        window.clearTimeout(timeoutId);
        timeoutId = null;
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...