简体   繁体   中英

Multiple jQuery nav sliders

How do I get both nav sliders working independently ? As you can see the second nav buttons control the slides from the first post but I need them to work independently without having to change the class structure.

 $(function() { $('.post a').on('click', function(e) { e.preventDefault() showSlide($(this).index()); }); showSlide(0); function showSlide(index) { // Make the post__slide post__slide--visible $('.post .post__slide').removeClass('post__slide--visible'); $('.post .post__slide').eq(index).addClass('post__slide--visible'); // Set the tab to post__nav--selected $('.post a').removeClass('post__nav--selected'); $('.post a').eq(index).addClass('post__nav--selected'); } }); 
 .post { position: relative; } .post .post__nav { display: flex; border: 2px solid; flex-wrap: wrap; align-items: stretch; width: 100px; } .post .post__nav a { padding: 20px 0px; text-align: center; width: 100%; cursor: pointer; } .post .post__nav a:hover, .post .post__nav a.post__nav--selected { color: #737d8b; font-weight: 700; } .post .post__slide { position: absolute; top: 0px; left: 100px; width: 0px; display: flex; flex-direction: column; height: 100%; overflow: hidden; opacity: 0; transition: opacity 0.1s linear 0s; } .post .post__slide.post__slide--visible { width: calc(100% - 100px); overflow: scroll; opacity: 1; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="post"> <div class="post__menu"> <nav class="post__nav"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide"> <p>post__slide #1</p> </div> <div class="post__slide"> <p>post__slide #2</p> </div> <div class="post__slide"> <p>post__slide #3</p> </div> </div> <div class="post"> <div class="post__menu"> <nav class="post__nav"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide"> <p>post__slide #1</p> </div> <div class="post__slide"> <p>post__slide #2</p> </div> <div class="post__slide"> <p>post__slide #3</p> </div> </div> 

If I understand correctly, you want to display one slide only inside its slide container.

The issue your codes have:

$('.post .post__slide') will find out all .post__slide within those two div with class=post. You expected result should be only query out the .post__slide within the slide container which the user clicks.

My idea,

use the second parameter for .jQuery() to control the selector context.

As JQuery defined:

Selector Context

By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function. For example, to do a search within an event handler,the search can be restricted like so: 1 2 3

$( "div.foo" ).click(function() { $( "span", this ).addClass( "bar" ); });

When the search for the span selector is restricted to the context of this, only spans within the clicked element will get the additional class.

Internally, selector context is implemented with the .find() method, so $( "span", this ) is equivalent to $( this ).find( "span" ).

The working snippet :

 // first parameter: slide container // second parameter: the index of the slide function showSlide(slideContainer, index) { // Make the post__slide post__slide--visible $('.post__slide', slideContainer).removeClass('post__slide--visible'); $('.post__slide', slideContainer).eq(index).addClass('post__slide--visible'); // Set the tab to post__nav--selected $('a', slideContainer).removeClass('post__nav--selected'); $('a', slideContainer).eq(index).addClass('post__nav--selected'); } $(function() { $('.post a').on('click', function(e) { e.preventDefault() showSlide($(this).parent().parent().parent(),$(this).index()); }); // load default slide $('.post').each(function(index, item) { showSlide(item, 0); }); }); 
 .post { position: relative; } .post .post__nav { display: flex; border: 2px solid; flex-wrap: wrap; align-items: stretch; width: 100px; } .post .post__nav a { padding: 20px 0px; text-align: center; width: 100%; cursor: pointer; } .post .post__nav a:hover, .post .post__nav a.post__nav--selected { color: #737d8b; font-weight: 700; } .post .post__slide { position: absolute; top: 0px; left: 100px; width: 0px; display: flex; flex-direction: column; height: 100%; overflow: hidden; opacity: 0; transition: opacity 0.1s linear 0s; } .post .post__slide.post__slide--visible { width: calc(100% - 100px); overflow: scroll; opacity: 1; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="post"> <div class="post__menu"> <nav class="post__nav"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide"> <p>post__slide #1</p> </div> <div class="post__slide"> <p>post__slide #2</p> </div> <div class="post__slide"> <p>post__slide #3</p> </div> </div> <div class="post"> <div class="post__menu"> <nav class="post__nav"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide"> <p>post__slide #1</p> </div> <div class="post__slide"> <p>post__slide #2</p> </div> <div class="post__slide"> <p>post__slide #3</p> </div> </div> 

If you're just looking for a quick fix and don't plan on adding more sliders you can just add another option to your showSlide function and then do a quick check on the classes.

I assumed you didn't want to edit the classes because of the CSS relations - but adding an additional class to the 2nd slider won't change how it looks.

Again, this is a quick and easy way to do this - there are more complicated ways to accomplish this and that may follow the DRY principles better.

To explain, the new classes on the 2nd slider allow me to check which slider it is in (hasClass) and then I assign (2) or ('') based on the parent's class. In the showSlide function I use the number variable to build the selector - so if it's a 2 then it targets the new classes - otherwise it adds nothing.

 $(function() { $('.post a').on('click', function(e) { e.preventDefault() if ($(this).parent().hasClass('post__nav2')) { var number = '2' showSlide($(this).index(), number) } else { var number = '' showSlide($(this).index(), number); } }); showSlide(0); function showSlide(index, number) { // Make the post__slide post__slide--visible $('.post' + number + ' ' + '.post__slide' + number).removeClass('post__slide--visible'); $('.post' + number + ' ' + '.post__slide' + number).eq(index).addClass('post__slide--visible'); // Set the tab to post__nav--selected $('.post' + number + ' ' + 'a').removeClass('post__nav--selected'); $('.post' + number + ' ' + 'a').eq(index).addClass('post__nav--selected'); } }); 
 .post { position: relative; } .post .post__nav { display: flex; border: 2px solid; flex-wrap: wrap; align-items: stretch; width: 100px; } .post .post__nav a { padding: 20px 0px; text-align: center; width: 100%; cursor: pointer; } .post .post__nav a:hover, .post .post__nav a.post__nav--selected { color: #737d8b; font-weight: 700; } .post .post__slide { position: absolute; top: 0px; left: 100px; width: 0px; display: flex; flex-direction: column; height: 100%; overflow: hidden; opacity: 0; transition: opacity 0.1s linear 0s; } .post .post__slide.post__slide--visible { width: calc(100% - 100px); overflow: scroll; opacity: 1; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="post"> <div class="post__menu"> <nav class="post__nav"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide"> <p>post__slide #1</p> </div> <div class="post__slide"> <p>post__slide #2</p> </div> <div class="post__slide"> <p>post__slide #3</p> </div> </div> <div class="post post2"> <div class="post__menu post__menu2"> <nav class="post__nav post__nav2"> <a>post__slide #1</a> <a>post__slide #2</a> <a>post__slide #3</a> </nav> </div> <div class="post__slide post__slide2"> <p>post__slide #1</p> </div> <div class="post__slide post__slide2"> <p>post__slide #2</p> </div> <div class="post__slide post__slide2"> <p>post__slide #3</p> </div> </div> 

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