Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The callback function to <code>.fadeOut()</code> and <code>.fadeIn()</code> does not work the way you might expect when there are multiple elements being faded. The callback is called not just once, but for <em>every element</em>.</p> <p>If you put a <code>console.log()</code> call in one of the <code>.fadeOut()</code> callbacks, you will see that it gets logged multiple times. (The Chrome developer tools collapse this to a single log entry with a number to the left.)</p> <p><a href="http://jqapi.com/#p=fadeOut" rel="nofollow">http://jqapi.com/#p=fadeOut</a></p> <blockquote> <h3>Callback Function</h3> <p>If supplied, the callback is fired once the animation is complete. This can be useful for stringing different animations together in sequence. The callback is not sent any arguments, but this is set to the DOM element being animated. If multiple elements are animated, it is important to note that the callback is executed once per matched element, not once for the animation as a whole.</p> <p>As of jQuery 1.6, the .promise() method can be used in conjunction with the deferred.done() method to execute a single callback for the animation as a whole when all matching elements have completed their animations ( See the example for .promise() ).</p> </blockquote> <p>Here's a version of your code that uses <code>.promise()</code> to remove the duplicate callbacks. It also incorporates j08691's suggestion to exclude from the fadeOut the elements that you will be fading in:</p> <pre><code>var groups = { Adventure: '.adv', Puzzle: '.puz', Shooter: '.sho', All: 'div' }; function fade( group ) { $('#games div') .not(group) .fadeOut() .promise() .done( function() { console.log( group ); $('#games ' + group).fadeIn(); }); } $('input[name$="group1"]').click(function () { fade( groups[ $(this).val() ] ); }); </code></pre> <p>This code is also simplified considerably over the original, by combining duplicate code into a single function. Finally, I left in a console.log() to view the calls being made.</p> <p>Also a couple of comments on the HTML: You don't need to use <code>&lt;br /&gt;</code> unless you're writing XHTML, which I hope you're not doing. <code>&lt;br&gt;</code> is fine. More importantly, you should use <code>&lt;label&gt;</code> tags on the radio button labels so the entire label is clickable:</p> <pre><code>&lt;label&gt;&lt;input type="radio" name="group1" value="All" checked&gt;Show All&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value="Adventure"&gt;Adventure&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value="Puzzle"&gt;Puzzle&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value="Shooter"&gt;Shooter&lt;/label&gt; </code></pre> <p>Here's an <a href="http://jsfiddle.net/GAGNX/1/" rel="nofollow">updated jsfiddle</a>.</p> <p>There are additional opportunities for simplification here as well. Is it a requirement that the <code>value</code> attributes in your radio buttons be the specific strings 'All', 'Adventure', etc.? If not, you could simply put the group selectors directly in the <code>value</code> attributes:</p> <pre><code>&lt;label&gt;&lt;input type="radio" name="group1" value="div" checked&gt;Show All&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value=".adv"&gt;Adventure&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value=".puz"&gt;Puzzle&lt;/label&gt;&lt;br&gt; &lt;label&gt;&lt;input type="radio" name="group1" value=".sho"&gt;Shooter&lt;/label&gt; </code></pre> <p>And then the JavaScript code is simplified to:</p> <pre><code>function fade( group ) { $('#games div') .not(group) .fadeOut() .promise() .done( function() { console.log( group ); $('#games ' + group).fadeIn(); }); } $('input[name$="group1"]').click(function () { fade( $(this).val() ); }); </code></pre> <p><a href="http://jsfiddle.net/GAGNX/3/" rel="nofollow">Latest jsfiddle</a></p> <p>Another update... As Alex points out in a comment, this version of the code causes blocks to jump around when you click back and forth between Show All and specific genres.</p> <p>That's caused by this line in the code:</p> <pre><code> .not(group) </code></pre> <p>Removing that line gives smoother transitions, as shown in this <a href="http://jsfiddle.net/GAGNX/4/" rel="nofollow">updated jsfiddle</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload