snippetjavascriptMinor
Allowing developers to quickly create image hover effects
Viewed 0 times
allowingquicklyimagecreateeffectsdevelopershover
Problem
I've created a simple jQuery plugin to allow developers to quickly create image hover effects with very simple markup. I also created an option to automatically create the mouseover or mouseout versions of the image via TimThumb.
Here is a link. for more information and a demo.
```
(function($){
$.fn.hovr = function(options) {
// Default Options
var defaults = {
speed: 'normal',
animateOver: {'opacity': '0'},
animateOut: {'opacity': '1'},
timThumb: false,
timThumbInverse: false,
timThumbPath: 'images/img.php',
timThumbParams: 'f=2'
//http://www.binarymoon.co.uk/2012/02/complete-timthumb-parameters-guide/
};
var options = $.extend({}, defaults, options);
// Create Images
if (options.timThumb) {
this.each(function() {
var strOrig = $(this).prop('src');
var strNew = options.timThumbPath +
'?src=' + strOrig +
'&w=' + $(this).prop('width') +
'&h=' + $(this).prop('height') +
'&' + options.timThumbParams;
if (options.timThumbInverse) {
$(this)
.prop('src', strOrig)
.attr('data-hovr', strNew);
}
else {
$(this)
.prop('src', strNew)
.attr('data-hovr', strOrig);
}
});
}
// Create Rollovers
return this.each(function() {
$(this).hover(
function() {
$(this).stop().animate(options.animateOver, options.speed);
},
function() {
$(this).stop().animate(options.animateOut, options.speed);
}
).each(function() {
var intWidth = ($(this).attr('width')) ? $(this).attr('width') : $(this).prop('width');
var intHeight = ($(this).attr('height')) ? $(this).attr('height') : $(thi
Here is a link. for more information and a demo.
```
(function($){
$.fn.hovr = function(options) {
// Default Options
var defaults = {
speed: 'normal',
animateOver: {'opacity': '0'},
animateOut: {'opacity': '1'},
timThumb: false,
timThumbInverse: false,
timThumbPath: 'images/img.php',
timThumbParams: 'f=2'
//http://www.binarymoon.co.uk/2012/02/complete-timthumb-parameters-guide/
};
var options = $.extend({}, defaults, options);
// Create Images
if (options.timThumb) {
this.each(function() {
var strOrig = $(this).prop('src');
var strNew = options.timThumbPath +
'?src=' + strOrig +
'&w=' + $(this).prop('width') +
'&h=' + $(this).prop('height') +
'&' + options.timThumbParams;
if (options.timThumbInverse) {
$(this)
.prop('src', strOrig)
.attr('data-hovr', strNew);
}
else {
$(this)
.prop('src', strNew)
.attr('data-hovr', strOrig);
}
});
}
// Create Rollovers
return this.each(function() {
$(this).hover(
function() {
$(this).stop().animate(options.animateOver, options.speed);
},
function() {
$(this).stop().animate(options.animateOut, options.speed);
}
).each(function() {
var intWidth = ($(this).attr('width')) ? $(this).attr('width') : $(this).prop('width');
var intHeight = ($(this).attr('height')) ? $(this).attr('height') : $(thi
Solution
As a rule of thumb, when you use a jQuery selection more than once, you should cache its value. When you do
The hard part is caching
The reason the plugin is breaking when you cache it is because you have to cache it at each point the reference changes. Watch this next example:
From what I could understand from reading your plugin, I've cached your
Anyways here's your code:
$(".someElement"), jQuery now has to go find that element in the DOM, wrap it in the jQuery object and return it. If you save what it returns, then you only do the search once - not every time you use it.The hard part is caching
this. This is relative to where you are in the code, function, callback, etc. and changes to provide context. For example:var Object = {
init: function() {
//this in here references Object
//You could call this function elsewhere by doing: "this.init();"
},
bindEvents: function() {
$(".someElement").hover(function() {
//This is a callback function
//In here "this" refers to the element your .hover() was called on - ".someElement"
});
//However, outside the callback, "this" now refers to Object again
$(".someOtherElement").each(function(){
//This is another callback
//Here "this" refers to the element in question
});
}
}The reason the plugin is breaking when you cache it is because you have to cache it at each point the reference changes. Watch this next example:
var Object = {
init: function() {
//Here "this" refers to Object
//You don't need to cache this here because the Object is already saved in a variable
},
bindEvents: function() {
$(".someElement").hover(function() {
//In here however, the reference changed
//In here "this" refers to the element your ".hover()" was called on. ie.: ".someElement"
//You would cache it in here
});
//However, outside the callback, "this" now refers to Object again so you don't need to cache it
$(".someOtherElement").each(function(){
//This is another callback
//The reference has changed again, so now we cache it again
});
}
}From what I could understand from reading your plugin, I've cached your
this references for you. I didn't change anything else except for .removeAttr() calls at the end. You can use a space and put in several attributes to be removed at once.Anyways here's your code:
(function($){
$.fn.hovr = function(options) {
// Default Options
var defaults = {
speed: 'normal',
animateOver: {'opacity': '0'},
animateOut: {'opacity': '1'},
timThumb: false,
timThumbInverse: false,
timThumbPath: 'images/img.php',
timThumbParams: 'f=2'
//http://www.binarymoon.co.uk/2012/02/complete-timthumb-parameters-guide/
};
var options = $.extend({}, defaults, options);
// Create Images
if (options.timThumb) {
this.each(function() {
var $this = $(this),
strOrig = $this.prop('src'),
strNew = options.timThumbPath +
'?src=' + strOrig +
'&w=' + $this.prop('width') +
'&h=' + $this.prop('height') +
'&' + options.timThumbParams;
if (options.timThumbInverse) {
$this
.prop('src', strOrig)
.attr('data-hovr', strNew);
}
else {
$this
.prop('src', strNew)
.attr('data-hovr', strOrig);
}
});
}
// Create Rollovers
return this.each(function() {
$(this).hover(
function() {
$(this).stop().animate(options.animateOver, options.speed);
},
function() {
$(this).stop().animate(options.animateOut, options.speed);
}
).each(function() {
var $this = $(this),
intWidth = ($this.attr('width')) ? $this.attr('width') : $this.prop('width'),
intHeight = ($this.attr('height')) ? $this.attr('height') : $this.prop('height'),
strAlign = ($this.attr('align')) ? $this.attr('align') : '',
strClass = ($this.attr('class')) ? $this.attr('class') : '',
strStyle = ($this.attr('style')) ? $this.attr('style') : '';
$this.wrap('');
$this.before($this.clone(true))
.attr('style', 'position:absolute; left:auto; top:auto;')
.prop('src', $this.attr('data-hovr'))
.removeAttr('data-hovr class');
$this.prev('img')
.attr('style', 'position:absolute; left:auto; top:auto; z-index:10;')
.removeAttr('data-hovr class');
});
});
};
})(jQuery);Code Snippets
var Object = {
init: function() {
//this in here references Object
//You could call this function elsewhere by doing: "this.init();"
},
bindEvents: function() {
$(".someElement").hover(function() {
//This is a callback function
//In here "this" refers to the element your .hover() was called on - ".someElement"
});
//However, outside the callback, "this" now refers to Object again
$(".someOtherElement").each(function(){
//This is another callback
//Here "this" refers to the element in question
});
}
}var Object = {
init: function() {
//Here "this" refers to Object
//You don't need to cache this here because the Object is already saved in a variable
},
bindEvents: function() {
$(".someElement").hover(function() {
//In here however, the reference changed
//In here "this" refers to the element your ".hover()" was called on. ie.: ".someElement"
//You would cache it in here
});
//However, outside the callback, "this" now refers to Object again so you don't need to cache it
$(".someOtherElement").each(function(){
//This is another callback
//The reference has changed again, so now we cache it again
});
}
}(function($){
$.fn.hovr = function(options) {
// Default Options
var defaults = {
speed: 'normal',
animateOver: {'opacity': '0'},
animateOut: {'opacity': '1'},
timThumb: false,
timThumbInverse: false,
timThumbPath: 'images/img.php',
timThumbParams: 'f=2'
//http://www.binarymoon.co.uk/2012/02/complete-timthumb-parameters-guide/
};
var options = $.extend({}, defaults, options);
// Create Images
if (options.timThumb) {
this.each(function() {
var $this = $(this),
strOrig = $this.prop('src'),
strNew = options.timThumbPath +
'?src=' + strOrig +
'&w=' + $this.prop('width') +
'&h=' + $this.prop('height') +
'&' + options.timThumbParams;
if (options.timThumbInverse) {
$this
.prop('src', strOrig)
.attr('data-hovr', strNew);
}
else {
$this
.prop('src', strNew)
.attr('data-hovr', strOrig);
}
});
}
// Create Rollovers
return this.each(function() {
$(this).hover(
function() {
$(this).stop().animate(options.animateOver, options.speed);
},
function() {
$(this).stop().animate(options.animateOut, options.speed);
}
).each(function() {
var $this = $(this),
intWidth = ($this.attr('width')) ? $this.attr('width') : $this.prop('width'),
intHeight = ($this.attr('height')) ? $this.attr('height') : $this.prop('height'),
strAlign = ($this.attr('align')) ? $this.attr('align') : '',
strClass = ($this.attr('class')) ? $this.attr('class') : '',
strStyle = ($this.attr('style')) ? $this.attr('style') : '';
$this.wrap('<div class="' + strClass + '" style="position:relative; display:inline-block; ' +
'width:' + intWidth + 'px; height:' + intHeight + 'px; ' +
'float:' + strAlign + '; ' + strStyle + '"></div>');
$this.before($this.clone(true))
.attr('style', 'position:absolute; left:auto; top:auto;')
.prop('src', $this.attr('data-hovr'))
.removeAttr('data-hovr class');
$this.prev('img')
.attr('style', 'position:absolute; left:auto; top:auto; z-index:10;')
.removeAttr('data-hovr class');
});
});
};
})(jQuery);Context
StackExchange Code Review Q#28832, answer score: 2
Revisions (0)
No revisions yet.