Reputation: 113
I'd like to delay the zoomed image disappearing by a X seconds so I can fade out the image rather than it simply disappearing.
Can I simply add .delay(1000) somewhere to the mouseleave / hide lines of code?
I've tried that but unfortunately doesn't seem to work. I've also tried to wrap a setTimeout( ... , 1000); around various parts of the code, but couldn't make that work either.
Any help much appreciated!
Here is the Jsfiddle https://jsfiddle.net/mr_antlers/nh5jw5tb/2/
This is the original 'EasyZoom' .js code.
/*!
* @name EasyZoom
* @author Matt Hinchliffe <>
* @modified Tuesday, September 6th, 2016
* @version 2.4.0
*/
! function (a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function () {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function (a) {
a.preventDefault()
})
}, b.prototype.show = function (a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function () {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function (a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function (a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function () {
this.isMouseOver = !1, this.isOpen && this.hide()
}, b.prototype._onLoad = function (a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function () {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function () {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function (b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function (a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function () {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function (b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function () {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function (c) {
return this.each(function () {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function () {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom();
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
Upvotes: 4
Views: 562
Reputation: 2665
You can pass in beforeShow
and beforeHide
argument into easyZoom
when you instantiate them.
var $easyzoom = $('.easyzoom').easyZoom({
beforeHide: function() {
this.$flyout.fadeOut();
return false;
},
beforeShow: function() {
this.$flyout.show();
}
});
/*!
* @name EasyZoom
* @author Matt Hinchliffe <>
* @modified Tuesday, September 6th, 2016
* @version 2.4.0
*/
! function(a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function() {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function(a) {
a.preventDefault()
})
}, b.prototype.show = function(a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function() {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function(a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function(a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function() {
this.isMouseOver = !1, this.isOpen && this.hide()
}, b.prototype._onLoad = function(a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function() {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function() {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function(b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function(a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function() {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function(b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function() {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function(c) {
return this.each(function() {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function() {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom({
beforeHide: function() {
this.$flyout.fadeOut();
return false;
},
beforeShow: function() {
this.$flyout.show();
}
});
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
.easyzoom {
position: relative;
/* 'Shrink-wrap' the element */
display: inline-block;
*display: inline;
*zoom: 1;
}
.easyzoom img {
vertical-align: bottom;
}
.easyzoom.is-loading img {
cursor: progress;
}
.easyzoom.is-ready img {
cursor: default;
}
.easyzoom.is-error img {
cursor: not-allowed;
}
.easyzoom-notice {
position: absolute;
top: 50%;
left: 50%;
z-index: 150;
width: 10em;
margin: -1em 0 0 -5em;
line-height: 2em;
text-align: center;
background: #FFF;
box-shadow: 0 0 10px #888;
}
.easyzoom-flyout {
position: absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity: 0;
transition: 0.2s;
}
.easyzoom-flyout:hover {
position: absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity: 1;
transition: 0.8s;
}
.easyzoom--overlay .easyzoom-flyout {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.easyzoom--adjacent .easyzoom-flyout {
top: 0;
left: 100%;
width: 100%;
height: 100%;
margin-left: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="easyzoom easyzoom--overlay">
<a href="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg">
<img src="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg" alt="" width="608.917" height="405.833" />
</a>
</div>
You can refer the flyout zoomed image using this.$flyout
in the functions.
Return false if you want to stop the default hide
or show
function. Just remember to add the default behavior into your function if you are doing that.
In the example I did above, I do a fadeOut on the zoomed image and stop the flyout from detaching (default behavior is detach()
the zoomed image element). Then, as the flyout element was faded out, I have to use $.show()
or the element will be stuck at display: none
and nothing will be shown on mouseover.
Hope this helps.
Upvotes: 2
Reputation: 4516
'mouseleave' trigger _onLeave() which fire hide() which cause the zoomed div with image is removed from the DOM so any CSS transition or $().fadeOut() does not work. I removed hide() firing when mouseleave and change opacity in CSS and it seems to work now and anything else seems to be broken. Change opacity time as you wish.
/*!
* @name EasyZoom
* @author Matt Hinchliffe <>
* @modified Tuesday, September 6th, 2016
* @version 2.4.0
*/
! function (a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function () {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function (a) {
a.preventDefault()
})
}, b.prototype.show = function (a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function () {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function (a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function (a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function () {
this.isMouseOver = !1, this.isOpen
}, b.prototype._onLoad = function (a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function () {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function () {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function (b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function (a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function () {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function (b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function () {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function (c) {
return this.each(function () {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function () {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom();
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
.easyzoom {
position: relative;
/* 'Shrink-wrap' the element */
display: inline-block;
*display: inline;
*zoom: 1;
}
.easyzoom img {vertical-align: bottom;}
.easyzoom.is-loading img {cursor: progress;}
.easyzoom.is-ready img {cursor: default;}
.easyzoom.is-error img {cursor: not-allowed;}
.easyzoom-notice {
position: absolute;
top: 50%;
left: 50%;
z-index: 150;
width: 10em;
margin: -1em 0 0 -5em;
line-height: 2em;
text-align: center;
background: #FFF;
box-shadow: 0 0 10px #888;
}
.easyzoom-flyout {
position:absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity:0;
transition: opacity 1s ease-in-out;
}
.easyzoom-flyout:hover {
position:absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity:1;
}
.easyzoom--overlay .easyzoom-flyout {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.easyzoom--adjacent .easyzoom-flyout {
top: 0;
left: 100%;
width: 100%;
height: 100%;
margin-left: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="easyzoom easyzoom--overlay">
<a href="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg">
<img src="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg" alt="" width="608.917" height="405.833" />
</a>
</div>
Upvotes: 0