0

I've created a tabbed module which works by getting content that is in the .content div (which is hidden) and displaying it in a empty div called .overview.

The idea behind this tabbed module is that, on hover (or when class active exists), the content on the right will change based on what header is being selected from the left. I.e. If I hover over a header named "Red", the .overview div on the right will spit out "red".

However, the issues I'm having are the following:

  1. In the demo below, don't hover on any of the headers. The .overview div has no content - which is obviously not ideal. If .tabs has class .active, then I want its content displayed on the right. I have a counter running which changes class active every 5 seconds. I don't only want to show stuff on hover.

  2. Having said the above, if I hover over another tabs div, I want the counter to stop - to prevent it from adding class active to another .tabs div (because the hovered on tabs is active.

Demo:

$(document).ready(function() {
 // add class .active on li hover
 $('.tabs').mouseenter(function() {
 //$('.tabs').removeClass('active');
 $(this).parents('.tabs').addClass('active');
 });
 // Change active tab every x seconds
 $(function() {
 var list = $(".tabs"),
 currentActive = 0;
 time = 5; // interval in seconds
 setInterval(function() {
 currentActive = (currentActive + 1) % list.length;
 list.removeClass('active').eq(currentActive).addClass('active');
 }, time * 1000);
 });
})
var overview = $('.overview');
$('.tabs').each(function(i) {
 var thisTab = $(this);
 var thisContent = thisTab.find('.content').html();
 // when class .active exists, change content in .overview
 if ($('.tabs').hasClass('active')) {
 overview.html(thisContent);
 }
 // on hover, change content in .overview
 thisTab.on('mouseenter', function(e) {
 thisTab.addClass('active');
 overview.html(thisContent);
 })
 .on('mouseleave', function(e) {
 thisTab.removeClass('active');
 overview.html('');
 });
});
.tabs.active {
 background: none yellow;
}
.list {
 flex-basis: 40%;
}
.list li {
 list-style-type: none;
}
.overview {
 flex-basis: 60%;
 border: 1px solid blue;
}
.content {
 display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex flex-row">
 <div class="list">
 <li class="tabs active">
 <div class="header"><span>Header</span></div>
 <div class="content">
 <p>Content 1</p>
 </div>
 </li>
 <li class="tabs">
 <div class="header"><span>Header 2</span></div>
 <div class="content">
 <p>Content 2</p>
 </div>
 </li>
 <li class="tabs">
 <div class="header"><span>Header 3</span></div>
 <div class="content">
 <p>Content 3</p>
 </div>
 </li>
 </div>
 <div class="overview"> </div>
</div>

Edit:

I've managed to make some movement on issue 1. I've added:

 if ($('.tabs').hasClass('active')) {
 overview.html(thisContent);
 }

Which now, without hover, displays content in .overview, however, the content doesn't change when another tab is .active (i.e. in the demo, don't hover over anything, wait and it just shows content 3 for all headers.

Pete
58.7k30 gold badges131 silver badges187 bronze badges
asked Aug 23, 2019 at 12:48
0

2 Answers 2

3

I would do the following (I have commented what I have changed)

$(document).ready(function() {
 var list = $(".tabs"),
 overview = $('.overview'),
 autoInterval, // interval var
 currentActive = 0; // make this global to this closure
 overview.html(list.eq(0).find('.content').html()); // set overview content
 startInterval(); // start interval straight away
 // add class .active on li hover
 list.mouseenter(function() {
 var thisTab = $(this);
 currentActive = list.index(this); // set current active
 list.removeClass('active'); // remove active class
 thisTab.addClass('active'); // add active class
 clearInterval(autoInterval); // clear the interval whilst hovering
 var thisContent = thisTab.find('.content').html(); // get content
 overview.html(thisContent); // set overview content
 });
 list.mouseleave(function() {
 startInterval(); // restart the interval on mouseleave
 });
 function startInterval() {
 // Change active tab every x seconds
 time = 5; // interval in seconds
 autoInterval = setInterval(function() {
 currentActive = (currentActive + 1) % list.length;
 list.removeClass('active');
 var currentTab = list.eq(currentActive);
 currentTab.addClass('active');
 overview.html(currentTab.find('.content').html()); // set overview content
 }, time * 1000);
 }
});
.tabs.active {
 background: none yellow;
}
.list {
 flex-basis: 40%;
}
.list li {
 list-style-type: none;
}
.overview {
 flex-basis: 60%;
 border: 1px solid blue;
}
.content {
 display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex flex-row">
 <div class="list">
 <li class="tabs active">
 <div class="header"><span>Header</span></div>
 <div class="content">
 <p>Content 1</p>
 </div>
 </li>
 <li class="tabs">
 <div class="header"><span>Header 2</span></div>
 <div class="content">
 <p>Content 2</p>
 </div>
 </li>
 <li class="tabs">
 <div class="header"><span>Header 3</span></div>
 <div class="content">
 <p>Content 3</p>
 </div>
 </li>
 </div>
 <div class="overview"> </div>
</div>

answered Aug 23, 2019 at 13:26
Sign up to request clarification or add additional context in comments.

2 Comments

Amazing, works exactly as envisioned + thank you for the comments too
No problems, happy to help :)
0

As soon as you add the mouseenter event, you need to stop the interval, you have the method clearInterval to do so.

answered Aug 23, 2019 at 13:13

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.