I'm trying to create a jQuery collapsible panel and, while there are plugins around for it I haven't found one that does exactly what I want so, am trying to roll my own using various examples I've found. While it works for the most part there's one bit that doesn't and I can't work out why.
(An example page is at http://www.thekmz.co.uk/misc/cpanel/index1.html)
How it works (or doesn't as the case maybe)
HTML
<div id="container">
<div class="collapsiblePanel" title="Example Collapsible Panel">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit... etc</p>
</div>
</div>
Javascript
(function($) {
$.fn.extend({
collapsiblePanel: function() {
return $(this).each(initCollapsiblePanel);
}
});
})(jQuery);
function initCollapsiblePanel() {
if ($(this).children().length == 0) {
$(this).wrapInner("<div></div>");
}
$(this).children().wrapAll("<div class='cpanelContent'></div>");
$("<div class='cpanelTitle'><div>" + $(this).attr("title") + "</div><div class='cpanelToggle'>more</div></div>").prependTo($(this));
$(".cpanelContent", this).hide();
$(".cpanelTitle", this).click(toggleCollapsiblePanel);
}
function toggleCollapsiblePanel() {
$(".cpanelContent", $(this).parent()).slideToggle();
if ($(".cpanelContent", $(this).parent()).is(":hidden")) {
$(".cpanelToggle", this).html('more');
} else {
$(".cpanelToggle", this).html('close');
}
}
CSS
开发者_C百科#container {
width:300px;
height:300px;
}
.collapsiblePanel {
width:100%;
}
.cpanelTitle {
position:relative;
width:100%;
cursor: pointer;
cursor: hand;
}
.cpanelToggle {
position:absolute;
top:0px;
right:0px;
font-style:italic;
}
So it takes a div with the class collapsiblePanel and creates various nested divs. The header div holds the Title and some toggle text floated to the right that will be 'more' or 'close' depending on whether the content panel is expaned or collapsed.
The bit that doesn't work is the
if ($(".cpanelContent", $(this).parent()).is(":hidden")) {
in the toggleCollapsiblePanel() function. The div toggles ok so It seems I'm selecting the content div alright but using the same to find out whether it is hidden or not (so I can change the text of the cPanelToggleDiv) always comes back as false - which indicates to me that I'm just not doing it correctly.
I put a load of console calls in there (in the example page linked above) to try and see what's going on but just can't see it.
Any help pointing out my hopelessness/confusion would be greatly appreciated.
Regards Nymor
You should check the hidden
state in the slideToggle
callback method. Unless the slide animation completes you cannot say whether its hidden or not. Try this
Here I did few other optimization as well, like using this
which will point to the element it is sliding.
function toggleCollapsiblePanel() {
$(".cpanelContent", $(this).parent()).slideToggle(function(){
if ($(this).is(":hidden")) {
$(this).html('more');
} else {
$(this).html('close');
}
});
}
Adding the
var open = false;
to your initCollapsiblePanel function.
Then updating the toggleCollapsiblePanel function replace:
if ($(".cpanelContent", $(this).parent()).is(":hidden")) {...
with the following:
if (!open) {
$(".cpanelToggle", this).html('more');
open = true;
} else {
$(".cpanelToggle", this).html('close');
open = false;
}
This should now change the more and close text.( i think this is what your after). Si
The problem is that your test is running before the slideToggle has finished running. That means it will either have just become visible, or be fading out, in either case it will not be hidden.
You should move your text toggling into the slideToggle callback function, e.g.:
function toggleCollapsiblePanel() {
$(".cpanelContent", $(this).parent()).slideToggle(600, function() {
if ($(this).is(":hidden")) {
$(this).html('more');
} else {
$(this).html('close');
}
});
}
WORKING DEMO
The code:
function toggleCollapsiblePanel() {
var cCp = $(".cpanelContent", $(this).parent());
var cT = $(".cpanelToggle" , this);
check = cCp.is(":hidden") ? cT.html('close') : cT.html('more') ;
cCp.slideToggle();
}
精彩评论