Как остановить обрыв фонового изображения при слишком быстром уходе мыши с помощью jQuery

В настоящее время у меня есть div изображения, у которого меняется фоновое изображение, когда я наводю курсор мыши на определенный триггер div, используя метод jQuery css(). У меня есть переход на 0,6 с легкостью, примененный к изображению div, чтобы он плавно переходил от изображения к изображению. Однако, если я перемещаюсь между делителями триггера слишком быстро, фоновое изображение немедленно переходит к следующему и не имеет плавного затухания.

Я относительно новичок в JS и jQuery и ищу решение, которое сможет справиться с быстрым движением мыши, чтобы, когда мышь выходит из одного триггера div, следующее фоновое изображение начало плавно исчезать, даже если переход от последнего движение мыши еще не закончено. Вот скрипка (пожалуйста, не берите в голову странные изображения, которые я использовал): JSFiddle

Код:

$('.hover').hover(function() {
 $('#image').css('background-image', $(this).attr('data-attribute'));
});
*{
 margin: 0;
 padding: 0;
 font-size: 0;
}

.hover {
 height: 100px;
  width: 100px;
 font-size: 14px;
 display: inline-block;
  color: white;
  text-align: center;
  line-height: 100px;
}

#one {
  background-color: #f92;
}

#two {
  background-color: rgba(25, 140, 230, 1);
}

#three {
  background-color: #2cf;
}

#four {
  background-color: #f46;
}

#image {
 height: 400px;
 background-image: url('http://i.imgur.com/x37ckzO.jpg');
 width: 400px;
 background-size: cover;
 background-position: center;
 transition: 0.6s ease;
}
<div id="image"></div>
<div class="hover" id="one" data-attribute='url("http://i.imgur.com/x37ckzO.jpg")'>Image 1</div>
<div class="hover" id="two" data-attribute='url("http://i.imgur.com/t6WWdc2.png")'>Image 2</div>
<div class="hover" id="three" data-attribute='url("http://i.imgur.com/jA36LVy.png")'>Image 3</div>
<div class="hover" id="four" data-attribute='url("http://i.imgur.com/5a5xBLH.png")'>Image 4</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1 ответ

Должен признаться, я только частично понимаю проблему и почему мое решение работает. То, что следует, является результатом метода проб и ошибок и хорошо работает в десктопе /Chrome (в противном случае не тестировалось).

Во-первых, изображение должно быть инициализировано с фоном, который не является ни одним из четырех желаемых фонов. Если нет, то исправление не всегда будет работать при возврате к исходному изображению - "Изображение 1".

Для демонстрации я использовал один белый пиксель, который нашел на фейсбуке. Вы должны служить своим собственным.

#image {
    height: 400px;
    background-image: url('https://www.facebook.com/tr?id=742377892535530&ev=PageView&noscript=1'); /* single white pixel */
    width: 400px;
    background-size: cover;
    background-position: center;
    transition: 0.6s ease;
}

Теперь вам нужно спроектировать тройное изменение фона - два при отпускании мыши и один при вводе мыши.

var $image = $('#image');
$('.hover').on('mouseenter', function() {
    var self = this;
    setTimeout(function() {
        $image.css('background-image', $(self).data('attribute')); // (1)
    }, 0);
}).on('mouseleave', function() {
    var self = this;
    $image.css('background-image', '');  // (2)
    setTimeout(function() {
        $image.css('background-image', $(self).data('attribute')); // (3)
    }, 0);
}).eq(0).trigger('mouseenter');

Три перехода лучше всего объясняются в порядке их появления при переходе от одного .hover элемент к другому - (2) (3) (1).

  • (2) является ключевым. Это исправляет нежелательный эффект, о котором сообщалось в вопросе (я не очень понимаю, почему!)
  • (3) является следствием (2). Без (3) обычного "отпускания мышки" (не входя в другой .hover элемент) приведет к тому, что bg-изображение будет пустым (белый пиксель). Время ожидания необходимо для того, чтобы (2) время укусило.
  • (1) это эффект, который вы действительно хотите. Тайм-аут является следствием таймаута (3). (1) должен быть позже предыдущего (3).

Это столько, сколько я понимаю.

В заключение, .eq(0).trigger('mouseenter') необходимо инициализировать фоновое изображение для кнопки "Изображение 1".

var $image = $('#image');
$('.hover').on('mouseenter', function() {
 var self = this;
 setTimeout(function() {
  $image.css('background-image', $(self).data('attribute'));
 }, 0);
}).on('mouseleave', function() {
 var self = this;
 $image.css('background-image', '');
 setTimeout(function() {
  $image.css('background-image', $(self).data('attribute'));
 }, 0);
}).eq(0).trigger('mouseenter');
*{
 margin: 0;
 padding: 0;
 font-size: 0;
}

.hover {
 height: 100px;
  width: 100px;
 font-size: 14px;
 display: inline-block;
  color: white;
  text-align: center;
  line-height: 100px;
}

#one {
  background-color: #f92;
}

#two {
  background-color: rgba(25, 140, 230, 1);
}

#three {
  background-color: #2cf;
}

#four {
  background-color: #f46;
}

#image {
height: 400px;
^background-image: url('http://i.imgur.com/x37ckzO.jpg');
background-image: url('https://www.facebook.com/tr?id=742377892535530&ev=PageView&noscript=1');
width: 400px;
background-size: cover;
background-position: center;
transition: 0.6s ease;
}
<div id="image"></div>
<div class="hover" id="one" data-attribute='url("http://i.imgur.com/x37ckzO.jpg")'>Image 1</div>
<div class="hover" id="two" data-attribute='url("http://i.imgur.com/t6WWdc2.png")'>Image 2</div>
<div class="hover" id="three" data-attribute='url("http://i.imgur.com/jA36LVy.png")'>Image 3</div>
<div class="hover" id="four" data-attribute='url("http://i.imgur.com/5a5xBLH.png")'>Image 4</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Другие вопросы по тегам