简体   繁体   中英

jQuery show/hide not behaving as expected

Having some trouble with showing/hiding LI elements in a list using jQuery, here is what I have so far:

$(document).ready(function(){

    $("ul.news").find("li.hidden").hide();

    $("ul.news a.show").click(function() {
        $("ul.news").find("li.hidden").toggle();
        $("ul.news").find("li.hide").show();
    });

    $("ul.news a.hide").click(function() {
        $("ul.news").find("li.hidden").toggle();
        $("ul.news").find("li.show").show();
    });



    $("ul.articles").find("li.hidden").hide();

    $("ul.articles a.show").click(function() {
        $("ul.articles").find("li.hidden").toggle();
        $("ul.articles").find("li.hide").show();
    });

    $("ul.articles a.hide").click(function() {
        $("ul.articles").find("li.hidden").toggle();
        $("ul.articles").find("li.show").show();
    });
});

And the HTML:

<h3 class="gray-default">Press Releases</h3>
<ul class="news-landing news span8">
    <li><a href="" target="_blank">xxx</a></li>
    <li><a href="" target="_blank">xxx</a></li>
    <li><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="show"> <a class="view-more show">To view more &gt;&gt;</a> </li>
    <li class="hide"> <a class="view-more hide">To view less &gt;&gt;</a> </li>
</ul>

<h3 class="gray-default">Articles &amp; Reports</h3>
<ul class="news-landing articles span8">
    <li><a href="" target="_blank">xxx</a></li>
    <li><a href="" target="_blank">xxx</a></li>
    <li><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="hidden"><a href="" target="_blank">xxx</a></li>
    <li class="show"> <a class="view-more show">To view more &gt;&gt;</a> </li>
    <li class="hide"> <a class="view-more hide">To view less &gt;&gt;</a> </li>
</ul>

But what is happening:

  • on the initial page load everything appears fine, only 3 items in each list and the correct 'view more" link

  • click view more under news & the list expand correctly, but both more and less links are visible, clicking either link will collapse the list, but both links are visible.

  • click view more under articles & the list expands, but only the view more link is visible, clicking it again collapses the list, and the more link is still visible. the less link never appears.

What have I done wrong here?

Can simplify the whole thing and remove code repetition with:

CSS:

.hidden,li.hide{display:none}

JS:

$(document).ready(function(){

    $('li.show,li.hide').click(function(){
        $(this).toggle().siblings('.hide,.hidden,.show').toggle();      
    });
}) 

DEMO

By using siblings() you keep the DOM search isolated within each UL and therefore don't need to specify different handlers for each set of controls

LIVE DEMO

Simplify your HTML:

<h3 class="gray-default">Press Releases</h3>
<ul class="news-landing span8">
    <li><a href="" target="_blank">xxx0</a></li>
    <li><a href="" target="_blank">xxx1</a></li>
    <li><a href="" target="_blank">xxx2</a></li>
    <li><a href="" target="_blank">xxx3</a></li>
    <li><a href="" target="_blank">xxx4</a></li>
    <li><a href="" target="_blank">xxx5</a></li>
    <li><a href="" target="_blank">xxx6</a></li>
</ul>
<a href="#" class="news-landing-toggle"></a>

and here's your super-simple jQuery:

$(function(){ // DOM ready

  var btnTxt = ["View more", "View less"];
  $('.news-landing').find('li:gt(2)').hide();

  $(".news-landing-toggle").click(function( e ) {

      e.preventDefault();
      $(this).text( btnTxt.reverse()[0] ).prev('ul').find('li:gt(2)').slideToggle();    

  }).text( btnTxt[0] );

});

Another solution using a bit more of CSS would be:

LIVE DEMO

.news-landing li:nth-child(n+4){
  display:none;
}
.news-landing + .news-landing-toggle:after{
  content:"View more";
}
.news-landing.opened li:nth-child(n+4){
  display:inherit;
}
.news-landing.opened + .news-landing-toggle:after{
  content:"View Less";
}

jQ:

$('.news-landing-toggle').click(function(e){
  e.preventDefault();
  $(this).prev('ul').toggleClass('opened');
});

If I understand correct, instead of using toggle() , don't you want to use show() and hide() ?

That is, when you click view more , you would use show() and when you click view less you use hide() .

Additionally, when you click view more , you need to hide() the Show more link and show() the View less link and vice versa.

You never actually hide the show more / show less links at the appropriate time in your code. Try updating your JavaScript as follows (see fiddle ):

$(document).ready(function(){

    $("ul.news").find("li.hidden").hide();
    $("ul.news").find("li.hide").hide(); // hide the hide button by default

    $("ul.news li.show").click(function() {
        $(this).hide(); // hide the show button
        $("ul.news").find("li.hidden").toggle();
        $("ul.news").find("li.hide").show(); // and show the hide button
    });

    $("ul.news li.hide").click(function() {
        $(this).hide(); // hide the hide button 
        $("ul.news").find("li.hidden").toggle();
        $("ul.news").find("li.show").show(); // and show the show button
    });



    $("ul.articles").find("li.hidden").hide();
    $("ul.articles").find("li.hide").hide();

    $("ul.articles li.show").click(function() {
        $(this).hide();
        $("ul.articles").find("li.hidden").toggle();
        $("ul.articles").find("li.hide").show();
    });

    $("ul.articles li.hide").click(function() {
        $(this).hide();
        $("ul.articles").find("li.hidden").toggle();
        $("ul.articles").find("li.show").show();
    });
});

You could refactor this to avoid the code duplication, but I think it's probably a good start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM