How to fade between divs on click, starting with display none? - javascript

I came across this JSFiddle online whilst searching for a solution. It almost does what I need except I need to start with the div being hidden. I've tried playing around with it but being new to JS I've not had much luck.
I thought I'd put this here as a starting point to see if anyone could advise on the route I would need to take?
Any help would be appreciated.
$(document).ready(function () {
$('.pbox:gt(0)').hide();
$('#menu').on('click', 'a', function () {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
var $this = $(this);
// fade out all open subcontents
$('.pbox:visible').fadeOut('slow', function () {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
});
});
});
ul#menu {
margin:0;
padding:0;
list-style-type:none;
text-align: center;
}
ul#menu li {
position:relative;
float:left;
border-bottom:4px solid #efefef;
margin-right: 10px;
padding-right: 0px;
padding-bottom: 5px;
display: inline-block;
}
ul#menu .current {
border-bottom:4px solid #3d496a;
}
ul#menu li:hover {
border-bottom:4px solid #3d496a;
}
ul#menu li a {
padding:2px 2px;
text-decoration:none;
font:bold 8px Verdana, Georgia, "Times New Roman", Times, serif;
color:#68759c;
}
ul#menu li a:hover {
color:#8895b8;
border:none;
}
#div1 {display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li>Description
</li>
<li>Shipping and payment
</li>
<li>Returns
</li>
<li>Feedback
</li>
</ul>
<br>
<br>
<div class="pbox" id="div1">First Div</div>
<div class="pbox" id="div2">Second Div</div>
<div class="pbox" id="div3">Third Div</div>
<div class="pbox" id="div4">Fourth Div</div>

Just add display: none; in css to an element which you want to be hidden.
And remove class="active" from first li so that it's not chosen.
And modify js a little bit. See your function only shows a div if previously it hid. And if you start with all hidden it won't hide anything therefore it won't show anything.
$(document).ready(function() {
$('.pbox:gt(0)').hide();
$('#menu').on('click', 'a', function() {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
var $this = $(this);
// fade out all open subcontents
var visibleElements = $('.pbox:visible');
if (visibleElements.length <= 0) {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
} else {
visibleElements.fadeOut('slow', function() {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
});
}
});
});
ul#menu {
margin: 0;
padding: 0;
list-style-type: none;
text-align: center;
}
ul#menu li {
position: relative;
float: left;
border-bottom: 4px solid #efefef;
margin-right: 10px;
padding-right: 0px;
padding-bottom: 5px;
display: inline-block;
}
ul#menu .current {
border-bottom: 4px solid #3d496a;
}
ul#menu li:hover {
border-bottom: 4px solid #3d496a;
}
ul#menu li a {
padding: 2px 2px;
text-decoration: none;
font: bold 8px Verdana, Georgia, "Times New Roman", Times, serif;
color: #68759c;
}
ul#menu li a:hover {
color: #8895b8;
border: none;
}
.pbox {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li>Description
</li>
<li>Shipping and payment
</li>
<li>Returns
</li>
<li>Feedback
</li>
</ul>
<br>
<br>
<div class="pbox" id="div1">First Div</div>
<div class="pbox" id="div2">Second Div</div>
<div class="pbox" id="div3">Third Div</div>
<div class="pbox" id="div4">Fourth Div</div>
EDIT
If you want to hide all the divs on click anywhere else here is how to:
It's actually pretty easy.
We bind click event to document and check what was clicked.
If it was div with content (#div1, #div2 etc.) or if it is menu element we do not want to hide the div, but else we do.
$(document).on('click', function(e) {
if (!$(e.target).hasClass("pbox") && $(e.target).closest("#menu").length <= 0) {
$('.pbox').fadeOut('slow');
$("#menu .current").removeClass("current");
}
});
e.target returns an element which (in this case) was clicked. If it has class pbox it means this is a div with content.
Second condition is menu element. If .closest() function
Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
returns an element with id="menu" it means that we clicked on an element inside the menu.
Notice the exclamation mark. It means that if the condition is false return true. So if we did not click the div with content and if we did not click menu element then we hide the div.
I hope you understand what I mean :)
$(document).ready(function() {
$('#menu').on('click', 'a', function() {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
var $this = $(this);
// fade out all open subcontents
var visibleElements = $('.pbox:visible');
if (visibleElements.length <= 0) {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
} else {
visibleElements.fadeOut('slow', function() {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
});
}
});
$(document).on('click', function(e) {
if (!$(e.target).hasClass("pbox") && $(e.target).closest("#menu").length <= 0) {
$('.pbox').fadeOut('slow');
$("#menu .current").removeClass("current");
}
});
});
ul#menu {
margin: 0;
padding: 0;
list-style-type: none;
text-align: center;
}
ul#menu li {
position: relative;
float: left;
border-bottom: 4px solid #efefef;
margin-right: 10px;
padding-right: 0px;
padding-bottom: 5px;
display: inline-block;
}
ul#menu .current {
border-bottom: 4px solid #3d496a;
}
ul#menu li:hover {
border-bottom: 4px solid #3d496a;
}
ul#menu li a {
padding: 2px 2px;
text-decoration: none;
font: bold 8px Verdana, Georgia, "Times New Roman", Times, serif;
color: #68759c;
}
ul#menu li a:hover {
color: #8895b8;
border: none;
}
.pbox {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li>Description
</li>
<li>Shipping and payment
</li>
<li>Returns
</li>
<li>Feedback
</li>
</ul>
<br>
<br>
<div class="pbox" id="div1">First Div</div>
<div class="pbox" id="div2">Second Div</div>
<div class="pbox" id="div3">Third Div</div>
<div class="pbox" id="div4">Fourth Div</div>

i just delete the class "current". but first div still appear, so i create another div, empty, and it works :)
$(document).ready(function () {
$('.pbox:gt(0)').hide();
$('#menu').on('click', 'a', function () {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
var $this = $(this);
// fade out all open subcontents
$('.pbox:visible').fadeOut('slow', function () {
$('.pbox[id=' + $this.data('id') + ']').fadeIn('slow');
});
});
});
ul#menu {
margin:0;
padding:0;
list-style-type:none;
text-align: center;
}
ul#menu li {
position:relative;
float:left;
border-bottom:4px solid #efefef;
margin-right: 10px;
padding-right: 0px;
padding-bottom: 5px;
display: inline-block;
}
ul#menu .current {
border-bottom:4px solid #3d496a;
}
ul#menu li:hover {
border-bottom:4px solid #3d496a;
}
ul#menu li a {
padding:2px 2px;
text-decoration:none;
font:bold 8px Verdana, Georgia, "Times New Roman", Times, serif;
color:#68759c;
}
ul#menu li a:hover {
color:#8895b8;
border:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li>Description
</li>
<li>Shipping and payment
</li>
<li>Returns
</li>
<li>Feedback
</li>
</ul>
<br>
<br>
<div class="pbox" id="div5"></div>
<div class="pbox" id="div1">First Div</div>
<div class="pbox" id="div2">Second Div</div>
<div class="pbox" id="div3">Third Div</div>
<div class="pbox" id="div4">Fourth Div</div>

Delete class="current", so none is active at the beginning,
and then set the first div to display:none;

Related

onClick JS not go to top of the page

I have a page with an initial description, followed by 2 buttons, where the user can choose typeA or typeB. They work by "target": when the user clicks typeA comes the content relative to typeA, bellow the buttons; same to typeB.
typeA is the most common selection, then, when the page loads, a javascript emulates the click to typeA and opens respective content. To avoid hidden the initial description, there is another javascript to put the page at the top. Worked on Chrome and Edge, not on Firefox.
I would like to repeat the same process when the user clicks: opens the respective content, but positioning the page at the top, or, at least, showing the buttons. I thought event onClick calling the same js backToTop would worked - but not.
I put an alert on js and enters there but not execute: always keeps the content of the button selected in its better visibility.
I tried:
window.location.href = '#top';
window.scrollBy(0, -500);
document.html.scrollTop = document.documentElement.scrollTop = 0;
without success.
What am I doing wrong?
<head>
<meta charset="UTF-8">
<title>TOP PAGE TEST</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body,html {margin-left:auto; margin-right:auto;width:70%; font-family:verdana; font-size:1.2em;}
.menuFAQ {background:#aaa; font-size:2em; width:100%;}
.menuFAQ ul {list-style-type:none; position:relative; margin-left:-40px; /* to avoid user agent chrome */}
.menuFAQ li {display:inline-block; margin-top:10px; margin-bottom:10px; width:49%; background:#fff; text-align:center; box-shadow:2px 3px 4px 0px rgba(170,170,170,1); font-weight:400; line-height:80px;}
.menuFAQ li a {display:block; color:#020062; background:#fff; font-weight:400; text-decoration:none;}
.menuFAQ li .active,.menuFAQ li:hover a {color:#fff; font-weight:400; background-image:linear-gradient(#165686, #0f3a5a); }
:target {color:#fff;font-size:1em;}
div.items>div:not(:target) {display:none}
div.items>div:target {display:block; margin-left:auto; margin-right:auto; color:#000; border:1px solid #aaa;}
</style>
</head>
<body>
<div id="top">Top Page</div>
<br>textExp1<br>textExp2<br>textExp3<br>textExp4<br>textExp5
<div class="menuFAQ">
<ul>
<li><a id="preferedFAQ" onclick="backToTop()" class="target" href="#typeA">TypeA</a></li>
<li><a onclick="backToTop()" class="target" href="#typeB">TypeB</a></li>
</ul>
</div>
<div class="items">
<div id="typeA">
<nav>
A long and variable text size to explain TypeA <br>text1A<br>text2A<br>text3A<br>text4A<br>text5A<br>text6A<br>text7A<br>text8A<br>text9A<br>textAA<br>textBA<br>textCA<br>textDA
<br>[...]
</nav>
</div>
</div>
<div class="items">
<div id="typeB">
<nav>
A long and variable text size to explain TypeB
<p>text1B</p><p>text2B</p><p>text3B</p>
<br>[...]
</nav>
</div>
</div>
<script>
const allTargetLinks = document.querySelectorAll('.target')
allTargetLinks.forEach(targetLink => {
targetLink.addEventListener('click', () => {
allTargetLinks.forEach(targetLink => {
targetLink.classList.remove('active')
})
targetLink.classList.add('active')
})
})
window.onload = function() {assignPreferedFAQ()};
function assignPreferedFAQ() {
document.getElementById("preferedFAQ").click();
backToTop();
};
function backToTop() {
//document.html.scrollTop = document.documentElement.scrollTop = 0;
//document.body.scrollTop = document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
};
</script>
You had a real mess there regarding how you process click events and href attribute, i.e:
You had onclick attribute on your links, and you were adding yet another listener to them in JS
You didn't event.preventDefault() in your function, and default browser behavior when you click on a link is to get you to its href path
I've cleaned up a bit and changed some things. Since we need to prevent default behavior :target selector will no longer work, so instead I did what you've already been doing with links, and added an active class to your content. clickHandler() will now remove and add class active as necessary. At the end just scroll to the top. Here's the snippet:
document.querySelectorAll('.target').forEach(targetLink => targetLink.addEventListener('click', clickHandler, false));
function clickHandler(ev) {
ev.preventDefault(); // prevent browser from automatically scrolling to href pos
if (!ev.currentTarget.classList.contains('active')) {
// disable active elements
document.querySelector('.target.active').classList.remove('active');
document.querySelector('.items div.active').classList.remove('active');
// add class to the clicked on button and its corresponding content tab
ev.currentTarget.classList.add('active');
// to prevent pointless string slicing below, you'd have to store ids somewhere else i.e in the data-id attribute
const id = ev.currentTarget.href.slice(ev.currentTarget.href.lastIndexOf('#') + 1);
document.getElementById(id).classList.add('active');
}
window.scrollTo(0,0);
}
* {
font-family: verdana;
font-size: 1em;
}
.menuFAQ {
background: #aaa;
font-size: 2em;
width: 100%;
}
.menuFAQ ul {
list-style-type: none;
text-align: center;
padding: 0;
/* to avoid user agent chrome */
}
.menuFAQ li {
display: inline-block;
width: 48%;
margin-top: 10px;
margin-bottom: 10px;
background: #fff;
text-align: center;
box-shadow: 2px 3px 4px 0px rgba(170, 170, 170, 1);
font-weight: 400;
line-height: 80px;
}
.menuFAQ li a {
display: block;
color: #020062;
background: #fff;
font-weight: 400;
text-decoration: none;
}
.menuFAQ li .active,
.menuFAQ li:hover a {
color: #fff;
font-weight: 400;
background-image: linear-gradient(#165686, #0f3a5a);
}
div.items>div {
display: none;
}
div.items>div.active {
display: block;
margin-left: auto;
margin-right: auto;
color: #000;
border: 1px solid #aaa;
}
<div id="top">Top Page</div>
<br>textExp1<br>textExp2<br>textExp3<br>textExp4<br>textExp5
<div class="menuFAQ">
<ul>
<li><a class="target active" href="#typeA">TypeA</a></li>
<li><a class="target" href="#typeB">TypeB</a></li>
</ul>
</div>
<div class="items">
<div class="active" id="typeA">
<nav>
A long and variable text size to explain TypeA <br>text1A<br>text2A<br>text3A<br>text4A<br>text5A<br>text6A<br>text7A<br>text8A<br>text9A<br>textAA<br>textBA<br>textCA<br>textDA
<br>[...]
</nav>
</div>
</div>
<div class="items">
<div id="typeB">
<nav>
A long and variable text size to explain TypeB
<p>text1B</p>
<p>text2B</p>
<p>text3B</p>
<br>[...]
</nav>
</div>
</div>
Note that instead of artificially clicking at the page load, now your content just loads with class active.
Hope this help you.
< script >
window.onload = function() {
document.getElementById("preferedFAQ").click();
backToTop();
};
function backToTop() {
document.documentElement.scrollTop = document.body.scrollTop = 0;
//alert("enter backToTop");
var elmnt = document.getElementById("top");
var x = elmnt.scrollLeft;
var y = elmnt.scrollTop;
}; <
/script>
body,
html {
margin-left: auto;
margin-right: auto;
width: 70%;
font-family: verdana;
font-size: 1.2em;
}
.menuFAQ {
background: #aaa;
font-size: 2em;
width: 100%;
}
.menuFAQ ul {
list-style-type: none;
position: relative;
margin-left: -40px;
/* to avoid user agent chrome */
}
.menuFAQ li {
display: inline-block;
margin-top: 10px;
margin-bottom: 10px;
width: 49%;
background: #fff;
text-align: center;
box-shadow: 2px 3px 4px 0px rgba(170, 170, 170, 1);
font-weight: 400;
line-height: 80px;
}
.menuFAQ li a {
display: block;
color: #020062;
background: #fff;
font-weight: 400;
text-decoration: none;
}
.menuFAQ li .active,
.menuFAQ li:hover a {
color: #fff;
font-weight: 400;
background-image: linear-gradient(#165686, #0f3a5a);
}
:target {
color: #fff;
font-size: 1em;
}
div.items>div:not(:target) {
display: none
}
div.items>div:target {
display: block;
margin-left: auto;
margin-right: auto;
color: #000;
border: 1px solid #aaa;
}
<div id="top">Top Page</div> <br>textExp1<br>textExp2<br>textExp3<br>textExp4<br>textExp5<br>textExp6<br>textExp7<br>textExp8<br>textExp9<br>textExpA<br>textExpB<br>textExpC<br>textExpD
<br>textExpE
<div class="menuFAQ">
<ul>
<li><a id="preferedFAQ" onclick="backToTop()" class="target" href="#typeA">TypeA</a></li>
<li><a onclick="backToTop()" class="target" href="#typeB">TypeB</a></li>
</ul>
</div>
<div class="items">
<div id="typeA">
<nav>
A long and variable text size to explain TypeA <br>text1A<br>text2A<br>text3A<br>text4A<br>text5A<br>text6A<br>text7A<br>text8A<br>text9A<br>textAA<br>textBA<br>textCA<br>textDA
<br>[...]
</nav>
</div>
</div>
<div class="items">
<div id="typeB">
<nav>
A long and variable text size to explain TypeB
<p>text1B</p>
<p>text2B</p>
<p>text3B</p>
<br>[...]
</nav>
</div>
</di

How to change hover action to click action?

Hello people I created two divs and when i hover to h3 shows me something. I want display this only when i click on h3. How i can do this?
How to change hover to click? When i do this doesn't working.
Sorry for my bad language.
$(document).ready(function () {
$('li.requirement').hover(function () {
$(this).find('span').show();
}, function () {
$(this).find('span').hide();
});
});
#wrap {
background: #e7e7e7;
padding: 0px;
text-align: center;
width: 100%;
}
#left, #right {
background: #ccc;
display: inline-block;
padding: 20px;
}
li {
list-style-type: none;
padding: 0px;
margin: 0px;
}
span.lewy {float:right; background:red; padding:20px;}
span.prawy {float:left; background:red; padding:20px;}
h3 {text-align:center;}
h3.praw {float:left;}
h3.lew {float:right;}
.calosc {max-width:500px; margin: 0 auto; border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<div id="left"><div class="lef">
<li class="requirement" id="requirement_1">
<h3 class="lew">SPR</h3>
<span class="fr drag lewy" style="display:none;">1 kontakt</span>
</li>
</div></div>
<div id="right"><div class="praf">
<li class="requirement" id="requirement_2">
<h3 class="praw">SPR 2</h3>
<span class="fr drag prawy" style="display:none;">2 kontakt</span>
</li>
</div></div>
</div>
You can use .on('click', function(){}); and then inside this function you check to see if it's already visible or not. Take a look here
EDIT
As you want to be just the <h3> clickable, i made an adjustment in the code below, and now you need to cehck for the visibility of the h3 parent, because now the context of this is now h3 and no more the li
$(document).ready(function () {
$('.clickableH3').on('click', function () {
if ($(this.parentElement).find('span').is(":visible")){
$(this.parentElement).find('span').hide();
}else{
$(this.parentElement).find('span').show();
}
});
});
#wrap {
background: #e7e7e7;
padding: 0px;
text-align: center;
width: 100%;
}
#left, #right {
background: #ccc;
display: inline-block;
padding: 20px;
}
li {
list-style-type: none;
padding: 0px;
margin: 0px;
}
span.lewy {float:right; background:red; padding:20px;}
span.prawy {float:left; background:red; padding:20px;}
h3 {text-align:center;}
h3.praw {float:left;}
h3.lew {float:right;}
.calosc {max-width:500px; margin: 0 auto; border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<div id="left"><div class="lef">
<li class="requirement" id="requirement_1">
<h3 class="lew clickableH3">SPR</h3>
<span class="fr drag lewy" style="display:none;">1 kontakt</span>
</li>
</div></div>
<div id="right"><div class="praf">
<li class="requirement" id="requirement_2">
<h3 class="praw clickableH3">SPR 2</h3>
<span class="fr drag prawy" style="display:none;">2 kontakt</span>
</li>
</div></div>
</div>
Well you see, in your js code, where you have "hover" ? Well you type "click" there instead ...
The jQuery hover function can have 2 parameters, which is your case. The first one for the hover, the second is for the unhover
So if you want to be able to close and hide on click I advise to use some css and use toggleClass. But if you wan to keep only javascript you can do like this:
$(document).ready(function () {
$('li.requirement').click(function () {
var $elm = $(this);
if( $elm.hasClass('showed') ){
$elm.find('span').removeClass('showed').hide();
}else{
$elm.find('span').addClass('showed').show();
}
});
});

How to collapse current tab if clicked second time?

First time posting to this website :)
I found this piece of code which is almost what I'm looking for, but I'd like the tab-menu to close completely if the current tab clicked a second time.
I'm not very experienced with javascript or jQuery, and can't figure out how to solve this.
Thanks for any help!
Best regards,
Trym
$(function() {
$('.tab-panels .tabs li').on('click', function() {
var $panel = $(this).closest('.tab-panels');
$panel.find('.tabs li.active').removeClass('active');
$(this).addClass('active');
//figure out which panel to show
var panelToShow = $(this).attr('rel');
//hide current panel
$panel.find('.panel.active').slideUp(300, showNextPanel);
//show next panel
function showNextPanel() {
$(this).removeClass('active');
$('#'+panelToShow).slideDown(300, function() {
$(this).addClass('active');
});
}
});
});
body {
background: #fafafa;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;
}
.tab-panels ul {
margin: 0;
padding: 0;
}
.tab-panels ul li {
list-style-type: none;
display: inline-block;
background: #999;
margin: 0;
padding: 3px 10px;
border-radius: 10px 10px 0 0;
color: #fff;
font-weight: 200;
cursor: pointer;
}
.tab-panels ul li:hover {
color: #fff;
background: #666;
}
.tab-panels ul li.active {
color: #fff;
background: #666;
}
.tab-panels .panel {
display:none;
background: #c9c9c9;
padding: 30px;
border-radius: 0 0 10px 10px;
}
.tab-panels .panel.active {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab-panels">
<ul class="tabs">
<li rel="panel1" class="active">panel1</li>
<li rel="panel2">panel2</li>
<li rel="panel3">panel3</li>
<li rel="panel4">panel4</li>
</ul>
<div id="panel1" class="panel active">
content1<br/>
content1<br/>
content1<br/>
content1<br/>
content1<br/>
</div>
<div id="panel2" class="panel">
content2<br/>
content2<br/>
content2<br/>
content2<br/>
content2<br/>
</div>
<div id="panel3" class="panel">
content3<br/>
content3<br/>
content3<br/>
content3<br/>
content3<br/>
</div>
<div id="panel4" class="panel">
content4<br/>
content4<br/>
content4<br/>
content4<br/>
content4<br/>
</div>
</div>
Try using slideToggle()
$('#'+panelToShow).slideToggle(800).addClass('active');
https://codepen.io/anon/pen/LQVQga
Hope this helps

Show and hide active class in li when clicked on input button

I want to go for next tab when i clicked on next button which is in first tab.Likewise for other two tabs as well.
I searched all stuffs and tried a lot to add active class to particular li when i clicked on button.
Please see the below code
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script>
<script>
$(document).ready(function() {
$('.nav-tabs > li > a').click(function(event){
event.preventDefault();//stop browser to take action for clicked anchor
//get displaying tab content jQuery selector
var active_tab_selector = $('.nav-tabs > li.active > a').attr('href');
//find actived navigation and remove 'active' css
var actived_nav = $('.nav-tabs > li.active');
actived_nav.removeClass('active');
//add 'active' css into clicked navigation
$(this).parents('li').addClass('active');
//hide displaying tab content
$(active_tab_selector).removeClass('active');
$(active_tab_selector).addClass('hide');
//show target tab content
var target_tab_selector = $(this).attr('href');
$(target_tab_selector).removeClass('hide');
$(target_tab_selector).addClass('active');
});
});
</script>
<style>
/** Start: to style navigation tab **/
.nav {
margin-bottom: 18px;
margin-left: 0;
list-style: none;
}
.nav > li > a {
display: block;
}
.nav-tabs{
*zoom: 1;
}
.nav-tabs:before,
.nav-tabs:after {
display: table;
content: "";
}
.nav-tabs:after {
clear: both;
}
.nav-tabs > li {
float: left;
}
.nav-tabs > li > a {
padding-right: 12px;
padding-left: 12px;
margin-right: 2px;
line-height: 14px;
}
.nav-tabs {
border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
margin-bottom: -1px;
}
.nav-tabs > li > a {
padding-top: 8px;
padding-bottom: 8px;
line-height: 18px;
border: 1px solid transparent;
-webkit-border-radius: 4px 4px 0 0;
-moz-border-radius: 4px 4px 0 0;
border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
border-color: #eeeeee #eeeeee #dddddd;
}
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover {
color: #555555;
cursor: default;
background-color: #ffffff;
border: 1px solid #ddd;
border-bottom-color: transparent;
}
li {
line-height: 18px;
}
.tab-content.active{
display: block;
}
.tab-content.hide{
display: none;
}
/** End: to style navigation tab **/
</style>
<h1>CUSTOMIZE</h1>
<div>
<ul class="nav nav-tabs">
<li class="active">
Show Tab 1
</li>
<li>
Show Tab 2
</li>
<li>
Show Tab 3
</li>
</ul>
</div>
<section id="tab1" class="tab-content active">
<div>
Content in tab 1
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab2" class="tab-content hide">
<div>
Content in tab 2
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab3" class="tab-content hide">
<div>
Content in tab 3
<input type="button" name="next" value="next">
</div>
</section>
Please help me to find the solution.Thanks
You can find the next tab / li of the current active element and add / remove class accordingly. See below solution
$(document).ready(function() {
//register click event handler for input with name=next
$('.tab-content input[name="next"]').click(function(event){
event.preventDefault();//stop browser to take action for clicked anchor
//get parent tab of next button clicked
var $parent = $('.tab-content.active');
//get next tab
var $nextTabParent = $parent.next('.tab-content');
//check if next tab exist or not
if($nextTabParent.length > 0)
{
//remove active class from current tab and add active class to next tab
$parent.removeClass('active').addClass('hide');
$nextTabParent.removeClass('hide').addClass('active');
//remove active class from current li and add it to next li
var $activeLi = $('ul.nav.nav-tabs').find('li.active');
$activeLi.removeClass('active');
$activeLi.next('li').addClass('active');
}
});
});
.nav {
margin-bottom: 18px;
margin-left: 0;
list-style: none;
}
.nav > li > a {
display: block;
}
.nav-tabs{
*zoom: 1;
}
.nav-tabs:before,
.nav-tabs:after {
display: table;
content: "";
}
.nav-tabs:after {
clear: both;
}
.nav-tabs > li {
float: left;
}
.nav-tabs > li > a {
padding-right: 12px;
padding-left: 12px;
margin-right: 2px;
line-height: 14px;
}
.nav-tabs {
border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
margin-bottom: -1px;
}
.nav-tabs > li > a {
padding-top: 8px;
padding-bottom: 8px;
line-height: 18px;
border: 1px solid transparent;
-webkit-border-radius: 4px 4px 0 0;
-moz-border-radius: 4px 4px 0 0;
border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
border-color: #eeeeee #eeeeee #dddddd;
}
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover {
color: #555555;
cursor: default;
background-color: #ffffff;
border: 1px solid #ddd;
border-bottom-color: transparent;
}
li {
line-height: 18px;
}
.tab-content.active{
display: block;
}
.tab-content.hide{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1>CUSTOMIZE</h1>
<div>
<ul class="nav nav-tabs">
<li class="active">
Show Tab 1
</li>
<li>
Show Tab 2
</li>
<li>
Show Tab 3
</li>
</ul>
</div>
<section id="tab1" class="tab-content active">
<div>
Content in tab 1
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab2" class="tab-content hide">
<div>
Content in tab 2
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab3" class="tab-content hide">
<div>
Content in tab 3
<input type="button" name="next" value="next">
</div>
</section>
Add this to your code:
$(".next").click(function () {
if ($(".nav").find("li.active").next().length == 0) {
$(".nav").find("li").first().find("a").trigger("click");
} else {
$(".nav").find("li.active").next().find("a").trigger("click");
}
});
Here is the JSFiddle demo
You already wrote the codes for adding and removing classes.
So all you have to do is find the next li element that is not active, and trigger a click on its a tag (which in turn triggers your already written code).
The if statement is used to select the first li in case next is clicked when the last li is active
You can use trigger() to simulate click on tabs that already have click event
See the Fiddle
HTML
<h1>CUSTOMIZE</h1>
<div>
<ul class="nav nav-tabs">
<li class="active"> Show Tab 1
</li>
<li> Show Tab 2
</li>
<li> Show Tab 3
</li>
</ul>
</div>
<section id="tab1" class="tab-content active">
<div>Content in tab 1
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab2" class="tab-content hide">
<div>Content in tab 2
<input type="button" name="next" value="next">
</div>
</section>
<section id="tab3" class="tab-content hide">
<div>Content in tab 3
<input type="button" name="next" value="next">
</div>
</section>
JS
$(document).ready(function () {
$('.nav-tabs > li > a').click(function (event) {
event.preventDefault(); //stop browser to take action for clicked anchor
//get displaying tab content jQuery selector
var active_tab_selector = $('.nav-tabs > li.active > a').attr('href');
//find actived navigation and remove 'active' css
var actived_nav = $('.nav-tabs > li.active');
actived_nav.removeClass('active');
//add 'active' css into clicked navigation
$(this).parents('li').addClass('active');
//hide displaying tab content
$(active_tab_selector).removeClass('active');
$(active_tab_selector).addClass('hide');
//show target tab content
var target_tab_selector = $(this).attr('href');
$(target_tab_selector).removeClass('hide');
$(target_tab_selector).addClass('active');
});
$('.tab-content input').click(function (event) {
$(".nav.nav-tabs li.active").next("li").find("a").trigger("click");
});
});
The following, verbose answer restructures your script to help distinguish the pattern of defining and using selectors, the modifying of your control states (i.e. adding and removing class), the usage of inline functions to depict a strategy pattern, and declarative (non-anonymous) event handling..
I also modified your html structure slightly: using button in place of input type='button' and wrapping text with span tags.
Demo Sample
(function(window, $) {
function OnClickNavTabLink(e) { // this = e.target
e.preventDefault();
var $target_tabs = $(this); // 'a'
var $target_nav = $target_tabs.parents('li');
var $target_tabs_content = $($target_tabs.attr('href')); //i.e. $('#tab1') or $('#tab2') or $('#tab3');
// note: 'attr' will return the attr of the first item in the selectors
ClearAllControlStates();
SetControlState();
function SetControlState()
{
$target_nav
.addClass('active');
$target_tabs
.addClass('active');
$target_tabs_content
.removeClass('hide')
.addClass('active');
}
}
function OnClickNextButton(e)
{
e.preventDefault();
// this = button in $target_tabs_content
var $target_tabs_content = $(this).parents('section[id*="tab"]').next();
// in this sample/demo, when clicking button in 'section#tab3', next will return 'script';
if ($target_tabs_content.attr('id')) // simple check,
{
var $target_tabs = $('.nav-tabs > li > a[href*="' + $target_tabs_content.attr('id') + '"]'); // 'a'
var $target_nav = $target_tabs.parents('li');
ClearAllControlStates();
SetControlState();
}
function SetControlState()
{
$target_nav
.addClass('active');
$target_tabs
.addClass('active');
$target_tabs_content
.removeClass('hide')
.addClass('active');
}
}
function ClearAllControlStates()
{
var $navs = $('.nav-tabs > li');
var $tabs = $navs.children('a');
var tabs_content = [];
$tabs.each(GetHrefAttr);
var $tabs_content = $(tabs_content);
//console.log("$navs:= %o - $tabs:= %o - $tabs_content:= %o", $navs, $tabs, $(tabs_content));
$navs.removeClass('active');
$tabs.removeClass('active');
$tabs_content.each(HideEach);
function GetHrefAttr(i, item)
{
tabs_content.push($(item).attr('href'));
}
function HideEach(i, item)
{
$(item).removeClass('active').addClass('hide');
}
}
function ClearActiveControlStates()
{
var $activated_nav = $('.nav-tabs > li.active'); //listitem
var $activated_tabs = $activated_nav.children('a'); //hyperlinks
var activated_tabs_content = [];
$activated_tabs.each(GetHrefAttr);
var $activated_tabs_content = $(activated_tabs_content); //section_ids
$activated_nav.removeClass('active');
$activated_tabs.removeClass('active');
$activated_tabs_content.each(HideEach);
function GetHrefAttr(i, item)
{
activated_tabs_content.push($(item).attr('href'));
}
function HideEach(i, item)
{
$(item).removeClass('active').addClass('hide');
}
}
function OnReadyDocument() {
$('.nav-tabs > li > a')
.click(OnClickNavTabLink);
$('.tab-content button[name="next"]')
.click(OnClickNextButton);
}
$(window.document).ready(OnReadyDocument);
})(window, $ || jQuery.noConflict());
/** Start: to style navigation tab **/
.nav {
margin-bottom: 18px;
margin-left: 0;
list-style: none;
}
.nav > li > a {
display: block;
}
.nav-tabs{
*zoom: 1;
}
.nav-tabs:before,
.nav-tabs:after {
display: table;
content: "";
}
.nav-tabs:after {
clear: both;
}
.nav-tabs > li {
float: left;
}
.nav-tabs > li > a {
padding-right: 12px;
padding-left: 12px;
margin-right: 2px;
line-height: 14px;
}
.nav-tabs {
border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
margin-bottom: -1px;
}
.nav-tabs > li > a {
padding-top: 8px;
padding-bottom: 8px;
line-height: 18px;
border: 1px solid transparent;
-webkit-border-radius: 4px 4px 0 0;
-moz-border-radius: 4px 4px 0 0;
border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
border-color: #eeeeee #eeeeee #dddddd;
}
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover {
color: #555555;
cursor: default;
background-color: #ffffff;
border: 1px solid #ddd;
border-bottom-color: transparent;
}
li {
line-height: 18px;
}
.tab-content.active {
display: block;
}
.tab-content.hide{
display: none;
}
/** End: to style navigation tab **/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<h1>CUSTOMIZE</h1>
<div>
<ul class="nav nav-tabs">
<li class="active">
Show Tab 1
</li>
<li>
Show Tab 2
</li>
<li>
Show Tab 3
</li>
</ul>
</div>
<section id="tab1" class="tab-content active">
<div>
<span>Content in tab 1</span>
<button name="next">next</button>
</div>
</section>
<section id="tab2" class="tab-content hide">
<div>
<span>Content in tab 2</span>
<button name="next">next</button>
</div>
</section>
<section id="tab3" class="tab-content hide">
<div>
<span>Content in tab 3</span>
<button name="next">next</button>
</div>
</section>

How to insert text anchor inside attributes onclick?

I have a jquery tab and it's working fine.
Fiddle here
$(document).ready(function() {
$('.nnntabs ul a').on('click', function(e) {
var current = $(this).attr('href');
$('.tab-content > div' + current).fadeIn('slow').show().siblings().hide();
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
I just wanted to add more feature. The text anchor should be dynamically inserted inside the href and id attributes to activate the tab, or maybe replaced if there is a default value... The source of the value of href and id will be the text anchor of the menu. My fiddle sample is working fine because I inserted the values manually. Please help me turn this into reality... Thank you.
I think what you are looking for is
$(document).ready(function() {
var $content = $('.nnntabs > .tab-content > div');
$('.nnntabs > ul a').each(function(i) {
$(this).data('tab', 'tab-' + i);
$content.eq(i).attr('id', 'tab-' + i)
})
$('.nnntabs ul a').on('click', function(e) {
var current = $(this).data('tab');
$('#' + current).fadeIn('slow').show().siblings().hide();
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
.nnntabs {
width: 100%;
}
.nnntabs ul {
width: 100%;
margin: 0;
padding: 0;
}
.nnntabs ul li {
display: inline-block;
list-style: none;
border: 1px solid #ddd;
border-bottom: 0
}
.nnntabs ul li a {
padding: 8px 10px;
display: block;
font-size: 1em;
font-weight: bold;
color: #4c4c4c;
background: #eee;
}
.nnntabs ul li.active > a {
background: #fff;
color: #4c4c4c;
margin-bottom: -1px;
padding-bottom: 9px;
}
.tab-content {
padding: 10px;
border: 1px solid #ddd;
}
.tab-content > div {
display: none;
}
.tab-content > .active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="nnntabs">
<ul>
<li class="active">tab1</li>
<li>tab2</li>
<li>tab3</li>
</ul>
<div class="tab-content">
<div class="active">
content1
</div>
<div>
content2
</div>
<div>
cotent3
</div>
</div>
</div>

Categories