I just known that jQuery onmouseenter
/ onmouseleave
event will also fire every time the position/size of element changes during animation , so I use a simple validation by using if (img$.is(':animated')) return false;
in the beginning of both event handlers.
But, this causes another problem, which is sometimes the mouseleave
event will never been executed just because of the mouseleave
has returned false early while the mouseenter
isn’t finished yet.
$(function() {
$("img[data-alt-src]").on('mouseenter', function(e) {
e.stopPropagation();
e.preventDefault();
var img$ = $(e.currentTarget);
if (img$.is(':animated')) return false; // the validation
img$.finish().animate({
opacity: '-=1.0',
deg: '+=90'
}, {
duration: 250,
step: function(now) {
img$.css({
'-moz-transform': 'rotateY(' + now + 'deg)',
'-webkit-transform': 'rotateY(' + now + 'deg)',
'-o-transform': 'rotateY(' + now + 'deg)',
'-ms-transform': 'rotateY(' + now + 'deg)',
transform: 'rotateY(' + now + 'deg)'
});
},
complete: function() {
img$.data('tmp-src', img$.attr('src'));
img$.attr('src', img$.data('alt-src'));
}
});
img$.animate({
opacity: '+=1.0',
deg: '-=90'
}, {
duration: 250,
step: function(now) {
img$.css({
'-moz-transform': 'rotateY(' + now + 'deg)',
'-webkit-transform': 'rotateY(' + now + 'deg)',
'-o-transform': 'rotateY(' + now + 'deg)',
'-ms-transform': 'rotateY(' + now + 'deg)',
transform: 'rotateY(' + now + 'deg)'
});
}
});
})
.on('mouseleave', function(e) {
e.stopPropagation();
e.preventDefault();
var img$ = $(e.currentTarget);
if (img$.is(':animated')) return false; // the validation
img$.finish().animate({
opacity: '-=1.0',
deg: '+=90'
}, {
duration: 250,
step: function(now) {
img$.css({
'-moz-transform': 'rotateY(' + now + 'deg)',
'-webkit-transform': 'rotateY(' + now + 'deg)',
'-o-transform': 'rotateY(' + now + 'deg)',
'-ms-transform': 'rotateY(' + now + 'deg)',
transform: 'rotateY(' + now + 'deg)'
});
},
complete: function() {
img$.attr('src', img$.data('tmp-src'));
}
});
img$.animate({
opacity: '+=1.0',
deg: '-=90'
}, {
duration: 250,
step: function(now) {
img$.css({
'-moz-transform': 'rotateY(' + now + 'deg)',
'-webkit-transform': 'rotateY(' + now + 'deg)',
'-o-transform': 'rotateY(' + now + 'deg)',
'-ms-transform': 'rotateY(' + now + 'deg)',
transform: 'rotateY(' + now + 'deg)'
});
}
});
});
});
img {
width: 150px;
height: 150px;
margin-right: 1.5em;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div style="position: relative; display: inline-block">
<img
src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_1-270x270.jpg"
data-alt-src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_3-270x270.jpg"
alt="">
<img
src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_1-270x270.jpg"
data-alt-src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_3-270x270.jpg"
alt="">
<img
src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_1-270x270.jpg"
data-alt-src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_3-270x270.jpg"
alt="">
<img
src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_1-270x270.jpg"
data-alt-src="http://mcenter.lazim.org/image/cache/catalog/demo/nikon_d300_3-270x270.jpg"
alt="">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>
I was get stucked how to get rid of this condition?