EDIT: The question morphed into how to optimize a massive CSS change to 700 or more divs. I'm leaving the old question below to describe my original approach.
I have the following jQuery but it is not behaving as I expect. There are around 700 divs with class gr so hiding them takes a noticeable time. I am trying to do:
"Working" goes back to "Show/hide Pronunciation"
$(document).ready(function () {
$('#togglePron').click(function() {
$('#togglePron').html("Working...");
$('div.gr').toggle();
$('#togglePron').html("Show/hide Pronunciation");
});
});
...
...
<div class="pronlink" id="togglePron">Show/hide P</div>
<div class="gr">hai</div><div class="zi">A</div>
<div class="gr">nao</div><div class="zi">B</div>
etc.
Thanks to Mike Lentini there's a jsfiddle for this question.
This is the full page I'm working on
The behavior I observe is that "Show/hide P" takes a noticeable time to change, then it changes briefly to "Working", and it goes back to "Show/hide". So is jQuery bunching together both the html() and .toggle(), instead of running html() first?
This seems to be browser specific because in Opera it does what I want. In IE 7 and Chrome 18, the behavior is as I described. Is there a way to make the behavior I want in Chrome happen? Or a better way to do what I am describing?
EDIT :
Rather than using the toggle function to bind an event, why not just swap in a class on all the elements? This should be much faster:
$(document).ready(function(){
$('#toggleP').click(function(){
$('.gr').toggleClass('hidden');
});
});
Then in your CSS, add this style:
.hidden { display: none !important; }
See this fiddle for an example.
ADDITIONAL EDIT :
As noted by kingjeffrey, class-swapping the parent element instead of the child elements is even more efficient:
JS:
$('#togglePron').click(function(){
$('table').toggleClass('hide-pron');
});
CSS:
table.hide-pron .gr { display: none !important; }
For a (relatively) small number of children, the difference between these approaches is negligible – but as the child count increases, swapping the parent class can be noticeably faster.
ORIGINAL ANSWER :
Your element isn't going to update until the click()
function returns. Here's one way (probably not the best way) to do it:
$(document).ready(function () {
$('#toggleP').click(function() {
$('#toggleP').html("Working...");
setTimeout(
"$('div.g').toggle(10,function(){$('#toggleP').html('Show/Hide P');});",
10)
});
});
The toggle()
is now asynchronous due to being "scheduled" for 10ms in the future via setTimeout()
. This means the click()
function can return almost immediately, without waiting on the toggle()
to complete.
As others have noted, the best option is probably to wrap all of your div
s in a parent (if this is feasible for your actual code) and then toggle that parent div
.
JSFiddle link: http://jsfiddle.net/5E45Q/
If you can group all your div.g
's in a parent element, you will be able to hide that single parent element without modifying the DOM 700 times. See http://jsfiddle.net/SVf5k/6/
But if that is unavoidable, you can add a short delay before you toggle the div.g
's. This will give the js engine an opportunity to change the html on #toggleP
. See http://jsfiddle.net/SVf5k/5/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With