简体   繁体   中英

How can I make this more efficient? - Multiple jQuery Toggles

I have a handful of images working as jQuery toggle switches - Showing or hiding an element on a click event.

The code below mostly works as intended, but I'm fairly certain I'm using a lot of unnecessary stuff to make it happen. Any suggestions on streamlining?

Also, any suggestions on closing (toggle to hide) any visible elements that had already been toggled to visible? As it works now, if the user clicks on the first image and then the second image, it stacks the newly visible elements on top of each other. Ideally, I'd like to close (hide) the element from the first toggle when the second toggle is clicked and/or close any open elements on a scroll event.

The code below is abridged. There's actually 10+ toggles which can get a little unwieldy if the user has opened a bunch of them.

EDIT - Based on the answers below, I used common classes to tighten up the jQuery. The solution is also closing(hiding) any other open(visible) elements when the next toggle is clicked, but only within that toggle's parent. Since there are multiple UL's broken up between multiple parent div's, clicking to close wihtin "column2" will close any visible elements within "column2", but not within another column (ie: an open/visible element from column1)

UPDATED CODE:

  $(".show-wine").click(function(){ // Hide all wines except for the one that was clicked $(this).parent().siblings().find(".wine-text").hide(); // Show or hide the one that was clicked $(".wine-text", $(this).parent()).toggle(); }); $(".hide-wine").click(function(){ $('.wine-text').hide(); // Hide all wines }); 
 .wine-text { display:none; position:fixed; top:3em; left:1.5em; width:35em; padding:1em; height:auto; min-height:30em; background: rgba(0,0,0,0.95); color:#FFF; border-radius:4px; line-height:1.25em; text-align:left; } .wine-tiles li img:hover { cursor:pointer; opacity:.7; } .wine-tiles li img .unhide:hover .wine-text { display:block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="column1"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#1</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title1</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#2</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title2</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#3</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title3</h2> </li> </ul> </div> <div id="column2"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#4</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title4</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#5</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title5</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#6</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title6</h2> </li> </ul> </div> 

ORIGINAL CODE:

 $("#show-wine").click(function(){ $(".wine-text").toggle(); }); $("#show-wine2").click(function(){ $(".wine-text2").toggle(); }); $("#show-wine3").click(function(){ $(".wine-text3").toggle(); }); 
 .wine-text, .wine-text2, .wine-text3, .wine-text4, .wine-text5, .wine-text6, .wine-text7, .wine-text8, .wine-text9 { display:none; position:fixed; top:3em; left:1.5em; width:35em; padding:1em; height:auto; min-height:30em; background: rgba(0,0,0,0.95); color:#FFF; border-radius:4px; line-height:1.25em; text-align:left; } .wine-tiles li img:hover { cursor:pointer; opacity:.7; } .wine-tiles li img .unhide:hover .wine-text { display:block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="column1"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" id="show-wine" class="unhide bounce" alt="Img 1"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#1</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> <li> <img src="images/labels/image.jpg" id="show-wine2" class="unhide bounce" alt="Img 2"/> <span class="wine-text2"> <span class="wine-text-title centered">Wine#2</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> <li> <img src="images/labels/image.jpg" id="show-wine3" class="unhide bounce" alt="Img 3"/> <span class="wine-text3"> <span class="wine-text-title centered">Wine#3</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> </ul> </div> <div id="column2"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" id="show-wine" class="unhide bounce" alt="Img 1"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#4</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> <li> <img src="images/labels/image.jpg" id="show-wine2" class="unhide bounce" alt="Img 2"/> <span class="wine-text2"> <span class="wine-text-title centered">Wine#5</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> <li> <img src="images/labels/image.jpg" id="show-wine3" class="unhide bounce" alt="Img 3"/> <span class="wine-text3"> <span class="wine-text-title centered">Wine#6</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button id="hide-wine" class="button">Close</button> </span> <h2>Title</h2> </li> </ul> </div> 

Simply give a common class to the element that trigger the toggle and a common class on the toggled element. Then, for your specific case, you could use that :

$(".show-wine").click(function(){  
    var $target = $(this).next('.wine-text').toggle();
    $('.wine-text').not($target).hide()
});

That will not work if you slightly change you DOM. For a more general case, you'd need to target the common parent first :

$(".show-wine").click(function(){  
    var $target = $(this).closest('li').find('.wine-text').toggle();
    $('.wine-text').not($target).hide()
});

 $(".show-wine").click(function(){ var $target = $(this).closest('li').find('.wine-text').toggle(); $('.wine-text').not($target).hide() }); 
 .wine-text { display:none; position:fixed; top:3em; left:1.5em; width:35em; padding:1em; height:auto; min-height:30em; background: rgba(0,0,0,0.95); color:#FFF; border-radius:4px; line-height:1.25em; text-align:left; } .wine-tiles li img:hover { cursor:pointer; opacity:.7; } .wine-tiles li img .unhide:hover .wine-text { display:block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="column1"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#1</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title1</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#2</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title2</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#3</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title3</h2> </li> </ul> </div> <div id="column2"> <ul class="wine-tiles"> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#4</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title4</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#5</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title5</h2> </li> <li> <img src="images/labels/image.jpg" class="show-wine unhide bounce" alt="Img 3"/> <span class="wine-text"> <span class="wine-text-title centered">Wine#6</span><br> <span class="wine-text-winery centered">Big White House</span><br><br> <span class="wine-text-copy">Lorem Ipsum</span> <br/><br/> <button class="button hide-wine">Close</button> </span> <h2>Title6</h2> </li> </ul> </div> 

I'm not sure if this is the most efficiënt way (there are multiple ways to do it ofcourse), but this would be one of them:

http://jsfiddle.net/zah9a7xp/2/

By selecting the images by class and using it's parent you can get javascript code like this:

$(".show-wine").click(function(){
    var $target = $(".wine-text", $(this).parent());
    // Hide all wines except for the one that was clicked
    $('.wine-text').not($target).hide();
    // Show or hide the one that was clicked
    $target.toggle();
});
$(".hide-wine").click(function(){
    $('.wine-text').hide(); // Hide all wines
});

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