Create a reusable javascript function - javascript

At the moment I'm using the below function to perform a simple slide...
function jeans(jean, links) {
$(links).hide();
$(jean).hover(
function() {
$(links).show('slow');
},
function() {
$(links).hide('slow');
});}
And calling it where required with...
jeans('#red-jeans', '#red-jeans ul');
jeans('#blue-jeans', '#blue-jeans ul');
jeans('#yellow-jeans', '#yellow-jeans ul');
I'd like to be able to perform this by just attaching a class on the parent "#red-jeans".
I'm tring something like
function jeans(selector) {
$(selector 'ul').hide();
$(selector).hover(
function() {
$(selector 'ul').show('slow');
},
function() {
$(selector 'ul').hide('slow');
});}
...but my syntax is atrocious!
If someone can point me in the right direction it would be very much appreciated!
The issue is now that the slide runs on every element I've got the class on. Can anyone recommend an amend that would only activate it on the current hover? I presume a (this) is needed somewhere...
Thanks!

This:
$(selector 'ul').hide();
should be
$('ul', selector).hide();
Along with all the other similar places. What this does is looks for ul elements within selector

There are several ways you could achieve this in a clean way:
$(selector).find('ul')
$(selector + ' ul')
$('ul', selector)
are all equivalent.
In general I recommend you cache the selectors if you use them more often, because calling $() with a selector inside might be quite expensive. This way you have better performance and less trouble when refactoring.
To make the slides dependent on your current hover, use $(this) instead of the general selector.
function(selector){
var $element = $('ul', selector);
$element.hide();
$(selector).hover(
function() {
$(this).find('ul').show('slow');
},
function() {
$(this).find('ul').hide('slow');
});
}

Already answered, but this is a nice way of doing the same thing. You can create your own jQuery plugin like this...
$.fn.jeans = function() {
$(this).find("ul").hide();
$(this).hover(
function() {
$(this).find("ul").show('slow');
},
function() {
$(this).find("ul").hide('slow');
}
);
}
You call it by selecting the elements to apply it to and using it like a regular jQuery function...
$("#red-jeans, #blue-jeans, #yellow-jeans").jeans();
Just for future reference ;)

Just append string:
$(selector + ' ul').hide('slow');

you can try updating your JavaScript function as below:
function jeans(selector) {
// you will have to use 'find' and it wil only be for the first 'ul' as well
$(selector).find('ul:first').hide();
$(selector).hover(
function() {
$(selector).find('ul:first').show('slow');
},
function() {
$(selector).find('ul:first').hide('slow');
});
}
And then call it like this...
jeans('#red-jeans');
jeans('#blue-jeans');
jeans('#yellow-jeans');
I Hope this would help

Related

jQuery - how to delegate a toggle

How can I provide a toggle for a dynamically created element?
My code does not work:
JS
$("body").on('toggle', ".buttonA", function(){
function() {
..do stuff
},
function() {
.. revert stuff
}
});
Try this:
$('body').on('click','.buttonA', function () {
var toggled = $(this).data('toggled');
$(this).data('toggled', !toggled);
if (!toggled) {
//..do stuff
}
else {
//.. revert stuff
}});
If you are using jQuery,you can use .live() methods for binding a dynamically created element.
$('#hello').live("click", function() {
alert( "Goodbye!" ); // jQuery 1.3+
});
I didn't use jQuery for a long time.So I don't know the method is valid or not.But it is very easy to write a new method to resolve this requirement.The more important thing is you bind the element whether or not.

Remove Scroll Binding Without Removing Others with Jquery

Is there a way to remove the binding below, without removing other bindings on that element that deal with scroll? I tried the unbind('scroll', scrollHandler) and it didnt work also. I have another scroll binding that is removed because of this. Is there a way to do this with a namespace?
var scrollHandler = function () {
// Inner Logic
};
windowElement.unbind('scroll').scroll(scrollHandler);
Fixed it by using this.
windowElement.unbind('scroll.fixedTop').bind('scroll.fixedTop', scrollHandler);
You can use on() and off():
http://jsfiddle.net/STPcy/
var handler1 = function() {
console.log('handler1');
};
var handler2 = function() {
console.log('handler2');
};
$('#myDiv').on('click', handler1);
$('#myDiv').on('click', handler2);
$('#myDiv').off('click', handler1);
This results in only handler2() being called.

Need Help for better practice Jquery codes

I am trying to make my jquery codes look better here. My functions are working correctly but I was wondering if anyone can make my codes less ugly. Thanks a lot!
HTML
<div class='image_layout'>
<a href='#'><img src=' a.jpg '/></a>
<br><p class='credits'>hahahah
<br>Agency: Agency1
<br>Picture ID: 5 </p>
</div>
jQuery
$('#image_layout').on('hover', 'img', function() {
$(this).parent().next().next().fadeIn('fast');
})
$('#image_layout').on('mouseout', 'img', function() {
$(this).parent().next().next().fadeOut('fast');
})​
You can pass two functions to jQuery hover - one for mousein, one for mouseout. You can make this change as long as you don't have dynamically added images. Your code would also be a lot simpler if the element you are fading has an ID or class:
$('#image_layout img').hover(
function () {
$(this).closest('.someClass').fadeIn('fast');
},
function () {
$(this).closest('.someClass').fadeOut('fast');
}
);
$('.image_layout').on('hover', 'img', function (e) {
if(e.type == 'mouseover') {
$(this).closest('.image_layout').find('.credits').stop().fadeIn('fast');
} else {
$(this).closest('.image_layout').find('.credits').stop().fadeOut('fast');
}
})
You could also have done:
$('.image_layout').on('hover', 'img', function() {
$(this).closest('.image_layout').find('.credits').stop().fadeIn('fast');
}, function() {
$(this).closest('.image_layout').find('.credits').stop().fadeOut('fast');
});
If you're sure that nothing other than hovering the image will cause the element to fade, you could simply write:
$('.image_layout').on('hover', 'img', function() {
$(this).closest('.image_layout').find('.credits').stop().fadeToggle('fast');
});
Look into Douglas Crockford's JS Style Guide. He'd make your code look something like (with improvements):
var obj = $('#image_layout img');
obj.mouseover( function(){
$(this).parent([selector]).next([selector]).fadeIn('fast');
});
obj.mouseout( function(){
$(this).parent([selector]).next([selector]).fadeOut('fast');
});
You don't need the on, just call the function directly.
I would use .eq as opposed to two next statements, additionally, hover takes two functions, the first being for the mouseenter event, and the second for mouseout
$('#image_layout').hover('hover', 'img', function () {
$(this).parent().eq(2).fadeIn('fast');
}, function () {
$(this).parent().eq(2).fadeOut('fast');
})
References
Take a look at eq here
Read over hover here

Adding delay to jquery event on mouseover

I am trying to add a simple delay to a mouseover event of a child and having difficulties. (Still learning!)
This enables me to show the popup after a delay, but shows all of them simultaneously:
onmouseover='setTimeout(function() { $(\".skinnyPopup\").show(); }, 600)'
and this works to show only the popup I want with no delay:
onmouseover='$(this).children(\".skinnyPopup\").show()'
but the combination does not:
onmouseover='setTimeout(function() { $(this).children(\".skinnyPopup\").show(); }, 600)'
Any help would be appreciated. Thanks!
You need to define what this is when it executes, something like this would work:
setTimeout($.proxy(function() { $(this).children(".skinnyPopup").show(); }, this), 600)
Or just use .delay(), like this:
$(this).children(".skinnyPopup").delay(600).show(0);
Both of the above are quick fixes, I suggest you move away from inline handlers and check out an unobtrusive method (see this answer by Russ Cam for some great reasons), for example:
$(function() {
$('selector').mouseover(function() {
$(this).children(".skinnyPopup").delay(600).show(0);
});
});
It's because this is bound to the global context, not the element. Use something like the following instead:
// put this in your document head -- replace element with a selector for the elements you want
$(function () {
$(element).bind("mouseover", function () {
var e = $(this);
setTimeout(function () { e.children(".skinnyPopup").show(); }, 600);
});
});
If you're adamant about inline event handlers, the following should also work:
onmouseover='var self = this; setTimeout(function() { $(self).children(\".skinnyPopup\").show(); }, 600)'

jQuery ancestors using jQuery objects

I'd like to check ancestry using two jQuery objects. They don't have IDs, and are only going to be available as jQuery objects (or DOM nodes if you called get()). jQuery's is() only works with expressions, so this code would be ideal but will not work:
var someDiv = $('#div');
$('a').click(function() {
if ($(this).parents().is(someDiv)) {
alert('boo');
}
}
Just want to see if one element is a child of another and I'd like to avoid stepping back into DOM land if possible.
You can use the index() method to check if an element exists in a list, so would the following work?
var someDiv = $('#div');
$('a').click(function() {
if ($(this).parents().index(someDiv) >= 0) {
alert('boo');
}
}
From #index reference.
Checking for (this).parents().index(someDiv) >= 0, as #Gareth suggests, will work just fine.
However, using the jQuery ancestry plugin is way faster / more efficient.
Along those lines, parents() optionally accepts a selector itself:
$('a').click(function() {
if ($(this).parents("#div").length) {
alert('boo');
}
});
One way would be to use the filter function
$('a').click(function() {
$(this).parents().filter(function() {
return this == someDiv[0];
}).each(function() {
alert('foo');
})
}
I think you may also be able to get away with using jQuery.inArray
if ($.inArray( someDiv, $(this).parents() ) ) {
alert('boo');
}
Would you not get the result you want from simply using a CSS selector?
$( '#div a' ).click( function() { ... } );
Try this:
var someDiv = $('#div');
$('a').click(function() {
if ($.inArray($(this).parents().get(), someDiv.get(0)) {
alert('boo');
}
}
var $element = $('a');
while ($element && !$element.is('someDiv')) {
var $element = $element.parent();
};

Categories