Making Troublesome JQuery Switcher Actually Work
I'm trying to teach myself Jquery effects to enliven my websites. I've created a practice page that looks like this:
<article><a class="front-fire" href="1"></a></article>
<article><a class="front-fire" href="2"></a></article>
<article><a class="front-fire" href="3"></a></article>
<div class="presentation-wrapper">
<div class="load"></div>
<div class="presentation"></div>
</div>
<div class="kill></div>
<article><a class="front-fire" href="4"></a></article>
<article><a class="front-fire" href="5"></a></article>
<article><a class="front-fire" href="6"></a></article>
<div class="presentation-wrapper">
<div class="load"></div>
<div class="presentation"></div>
</div>
<div class="kill></div>
It's goal is that if I click a link, it expands the nearest presentation-wrapper
fades a loading gif up, loads the content, fades out the gif, then shows the content. Once another link is clicked it hides any open presentation-wrapper
s then shows does the opening sequence afresh. I think I've got a handle on how to string animations together, but I can't figure out how to cycle through a class of div
s and hide the ones that are visible.
Here's my javascript in an external file. The #primary
appends are for my debugging purposes:
$(document).ready(function() {
$('a').click(function(e) {
e.preventDefault();
$('#primary').append("pressed");
var toLoad = $(this).attr('href')+' #post-body';
var wrap = $(this).parents().filter('article').nextUntil('.kill', '.presentation-wrapper');
var load = $(wrap).children('.load');
var pres = $(wrap).children('.presentation');
var allwraps = $(".presentation-wrapper");
$(".presentation-wrapper").each(function() {
if ($(this).is(':visible')) {
$('#primary').append("6");
$('.presentation').fadeOut(3000, function() {
$('#primary').append("7");
$('.presentation-wrapper').slideUp(3000);
});
}
});
switcher();
function switcher() {
$(wrap).slideDown(3000, loadLoader);
$('#primary').append("1");
function loadLoader() {
$(load).fadeIn(3000, loadContent);
$('#primary').append("2");
}
function loadContent() {
$(pres).load(toLoad, hideLoader);
$('#primary').append("3");
}
function hideLoader() {
$(load).fadeOut(3000, showNewContent);
$('#primary').append("4");
}开发者_运维百科
function showNewContent() {
$(pres).fadeIn(3000);
$('#primary').append("5");
}
};
});
});
I know this is a big question, and maybe this isn't the place to ask, but I've been banging my head against the wall trying to suss out what is wrong. It works on the first click, but the .each()
seems to screw the whole thing up!
::Addition: maybe this detail will help. For some reason the "7" function in .each() keeps firing whenever any of the divs are visible at any time. Like it's a policeman negating anything that happens after it is called!::
I haven't actually tried this out, but it looks like the problem is in the .each()
block - when you refer to $('.presentation')
and $('.presentation-wrapper')
in the if
statement, are you expecting this to only refer to the current .presentation-wrapper
and its child .presentation
? Because in fact, these statements are referring to all elements on the page matching those selectors. That's why the "7"
bit fires every time.
I think this should do it:
// hide all other presentation wrappers
$(".presentation-wrapper:visible").not(wrap[0]).each(function() {
$('#primary').append("6");
var otherwrap = $(this);
// scope the selector to this element's children
$('.presentation', otherwrap).fadeOut(3000, function() {
$('#primary').append("7");
otherwrap.slideUp(3000);
});
});
Fully functional example here.
But, it's actually cleaner to do this without the .each()
function at all:
// hide all other presentation wrappers
$(".presentation-wrapper:visible .presentation")
.not(pres)
.fadeOut(3000, function() {
$(this).parent().slideUp(3000);
});
Also, I realized that you're going to need additional logic if you're trying to load content into the same .presentation-wrapper
- you just want to hide the child .presentation
immediately in that case:
// hide this immediately if it's currently visible
if (wrap.is(':visible')) {
pres.hide();
}
Updated jsFiddle here.
精彩评论