Avoid giant cascading in jQuery? - javascript

I feel like this is something that is solved by "deferreds" or "promises" that I've heard about in jQuery, but looking searching for related articles on that doesn't exactly show me what I'm looking for.
I want to be able to do a simple jquery function call (like animate() or slideUp()) then call another simple function when it is completed. Of course I know about slideUp(400, function(){ //onComplete... }); but if you have a large cascade of animations, that can get pretty hairy pretty quickly.
Check out the following jsfiddle:
http://jsfiddle.net/ue3daeab/
When you click the first button, you see the visual effect I want to acheive. However, I'm accomplishing it with "cascade hell," and the relevant code being:
$("#clickme").click(function(){
//Cascade hell
$("#my1").slideUp(400, function(){
$("#my2").slideUp(400, function(){
$("#my3").slideUp(400, function(){
$("#my4").slideUp(400, function(){
$("#my5").slideUp(400, function(){
$("#my6").slideUp(400, function(){
$("#my7").slideUp(400, function(){
$("#my8").slideUp(400, function(){
$("#my9").slideUp(400, function(){
$("#my10").slideUp(400);
});
});
});
});
});
});
});
});
});
});
When you click button 2, all the divs collapse at once, which isn't the effect I want. I feel like I should be able to do something like this, but obviously it doesn't work. The relevant code for the 2nd button is:
$.when($("#my1").slideUp())
.done($("#my2").slideUp())
.done($("#my3").slideUp())
.done($("#my4").slideUp())
.done($("#my5").slideUp())
.done($("#my6").slideUp())
.done($("#my7").slideUp())
.done($("#my8").slideUp())
.done($("#my9").slideUp())
.done($("#my10").slideUp());
Any advice? Thanks.

Why not use a simple array of ids to collapse, and then collapse them one item at a time?
$("#clickme").click(function(){
var toCollapse = ["#my1", "#my2", ...];
(function collapse(){
var id = toCollapse.shift();
if (!id) return;
$(id).slideUp(400, collapse);
})();
});
I edited your jsfiddle with this example too: http://jsfiddle.net/ue3daeab/2/

I would do something like this:
UNTESTED
$.each($('.item', '#container'), function(index, value) {
$(this).delay(50*index).slideUp(400);
});
This way everything doesn't try to happen all at once.

Related

One function in jquery, any step by step guides out there on how to Reset it?

jQuery.noConflict();
jQuery(document).ready(function(){
jQuery(".aj-hidden").hide();
jQuery(".aj-hidden").addClass("aj-visible");
jQuery(".aj-collapse").one( 'click', function() {
rel = jQuery(this).attr('rel');
jQuery("#" + rel).slideToggle('fast');
});
});
Sorry if this is impossible to do, I have searched all over this site with little idea if I'm even looking at the right answer.
Its taken me some time to figure out the "one" function and it gets me half the way there, I just want to know if I can possibly reset the link to be clicked again afterwards?
If you just want a function to be used multiple times why don't you use the .click() attribute of jQuery?
That would look like:
jQuery(".aj-collapse").click( function() {
rel = jQuery(this).attr('rel');
jQuery("#" + rel).slideToggle('fast');
});

Jquery Toggle & Offclick

I'm kind of a newbie when it comes to jquery so I wondered if someone could help me.
I've made a toggle function. When you click on the user_button the user_info shows, when you offclick the user_info disapears. But now I want to let the user_info disapear also when you click again on user_info (so when it is open it closes).
This is the jquery I have. Thanks in advance!
$(document).ready(function(){
$("#user_button").click(function(){
$("#user_button").addClass("active")
$("#user_box").toggle();
});
$("#user_box").mouseup(function(){
return false;
});
$(this).mouseup(function() {
$("#user_button").removeClass("active");
$("#user_box").hide();
});
});
Could you post a testable example on for example jsfiddle.net? This allows other to "play" with the actual code.
Try to take look at methods suchas show, hide, toggle toggleClass etc.
Take your code => http://jsfiddle.net/3Nxz2/3/
$(document).ready(function(){
$("#user_button").click(function(){
//alert("click");
$("#user_button").addClass("active")
$("#user_box").toggle();
});
$("#user_box").mouseup(function(){
//return false;
});
$(this).mouseup(function() {
$("#user_button").removeClass("active");
//$("#user_box").hide();
});
});

Toggle/Show one defined DIV with JS

I have a fiddle for you: http://jsfiddle.net/vSs4f/
I want to show the div.sub-menu with a simple click on a.haschildren. If the body loads the div.sub-menu should be closed. If I click a second time on a.haschildren the div.sub-menu should be close.
I have sampled so many things but I think the problems are the lot of DIV's. One idea is in the fiddle.
$(function() {
$("a.haschildren").click(function(e) {
e.preventDefault();
$('div.sub-menu:visible').hide();
$(this).next('div.sub-menu').show();
});
});
I really hope you can help me, thanks!
Try this:-
Fiddle
$(function () {
$("a.haschildren").click(function (e) {
e.preventDefault();
var subMenu = $(this).closest('div.haschildren').nextUntil('.sub-menu').next().toggle();
$('div.sub-menu:visible').not(subMenu).hide();
});
});
Using .nextUntil to reach a point till the .sub-menu, incase any other siblings come in between this will still work.
Personally there are MANY things I would have changed about the structure of your DOM. I am a strong believer that you should base your javascript structure around a well structured DOM, so the traversal is very easy and intuitive. That being said, I'm going to be slightly daring by submitting my fiddle, in the hope that if nothing else, you can look at it and gain a little insight on how to take advantage of a few DOM quirks to make your javascript a bit more intuitive and elegant.
http://jsfiddle.net/vSs4f/6/
$(function() {
$('#menu > div.item')
.find('a').click(function() {
var submenu_index = $(this).parents('.item:first').find('.sub-menu').toggle().index('.sub-menu');
// This chunk can disappear if you're not interested in hiding all of the other sub-menus
$('.sub-menu').filter(function(index) {
if(index != submenu_index)
return true;
}).hide();
}).end()
.find('div:first').after('<div class="trenner"></div>');
});
Try
$(function() {
$("a.haschildren").click(function(e) {
e.preventDefault();
var item = $(this).closest('div.haschildren').next().next('div.sub-menu').toggle();
$('div.sub-menu:visible').not(item).hide();
});
});
Demo: Fiddle
just use toggle()
$('div.sub-menu').toggle();
Ironically enough, the method you're looking for is .toggle();
http://api.jquery.com/toggle/
try it:
$(function() {
$("div.haschildren").click(function() {
if($(this).next().next('div.sub-menu').is(":hidden")){
$('div.sub-menu:visible').hide();
$(this).next().next('div.sub-menu').show();
}else{
$(this).next().next('div.sub-menu').hide();
}
return false;
});
});

Using mouseover in CSS

All,
var a='<div id="details" onmouseover="tip(this)">';
function tip(el)
{
$(this).mouseover(function() {
var b="<div id='test'>"+el.innerHTML+"</div>";
$(b).css("display", "inline");
});
}
Is anything wrong with the above code? I am trying to display el.innerhtml on mouserover next to the hyperlink
Why not try this instead :
function tip(el) {
$(this).mouseover(function() {
$("#test").html(el.innerHTML);
$("#test").css("display","inline");
}); }
Try to expand on what you want. Give us a list of requirements spell out exactly what you want. I expect a couple of the down votes will be rescided if you do this.
For my part, try this:
<div id="details">
<script type="text/javascript">
$(document).ready(function(){
$("#details").mouseover(function(){
var $this = $(this);
$this.append("<div id='test'>"+$this.html()+"</div>");
});
})
</script>
To show/hide would have been simple call to .show() or .hide()
If you really wanted this code:
var a='<div id="details" onmouseover="tip(this)">';
Then you would have to append to the DOM:
$(document).append('<div id="details">');
And then bind your event:
$("#details").mouseover(function(){
You need to append the code to your page DOM so it could be displayed. Currently you create a div, set CSS for it but it's still only in memory.
You are using $(this) inside your function, maybe it should be $(el)? And you need to do something like $('body').append(b); as well to add the <div> to the DOM.

Jquery mouse-over fade-in/out (best practices)

I've got working Jquery code to fade in/out descriptive text in a div below the question. The problem? The solution is not very elegant. Here's what I've got:
$("#home").mouseover(function() {
$("#homeText").fadeIn("slow");
});
$("#homeText").mouseout(function() {
$("#homeText").fadeOut();
});
I know there is better way to do this, I'm just not sure what it is.
you could use hover, the first function will act on a "hover over" and the second will act on a "hover out"
The documentation is located here: http://docs.jquery.com/Events/hover
$("#home").hover(function(){
$("#homeText").fadeIn("slow");
},
function(){
$("#homeText").fadeOut();
});
How about 3 lines?
<script>
$(function () {
$('#home').hover(function() {
$('#homeText').fadeToggle("slow");
});
});
</script>
Elegant enough?
Jon, Great advice! I used as a staring point though for a more complete solution. Doing this with just the basic hover would still leave me with a hover call for single menu item..A lot of redundant code. So using what you suggested, I came up with this:
$('.topMenu').hover(function()
{
$('#_'+this.id).fadeIn("slow");
},
function ()
{
$('#_'+this.id).fadeOut();
});
});
All menu items are given the topMenu class and ID. The corresponding div to display is the same id as the menu item, just prefixed with _
Example:
....
Stuff about us!
...
Thanks!
$(function () {
$('#home').hover(function() {
$('#homeText').fadeIn("slow");
});
$('#home').mouseout(function() {
$('#homeText').fadeOut("slow");
});
});

Categories