CSS tabs with jQuery: displaying just the content of current tab - javascript

I have this HTML file with some CSS styles, now I am trying to create vertical tabs but when the page loads all the content is being displayed then if I select any particular tab only content of that tab is display but I am just worried when the page. How come all the tab content is being displayed? Below is the code.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Follow me!</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<style type="text/css">
ul.tabs {
margin-top: 20px;
padding: 0;
list-style: none;
height: 32px; /*--Set height of tabs--*/
/*border-bottom: 1px solid #999;
border-left: 1px solid #999;*/
float:left;
}
ul.tabs li a {
text-decoration: none;
color: #000;
font-size: 1.2em;
padding: 0 20px;
border: 1px solid #fff; /*--Gives the bevel look with a 1px white border inside the list item--*/
outline: none;
}
ul.tabs li a:hover {
background: #ccc;
}
html ul.tabs li.active, html ul.tabs li.active a:hover { /*--Makes sure that the active tab does not listen to the hover properties--*/
background: #fff;
border-bottom: 1px solid #fff; /*--Makes the active tab look like it's connected with its content--*/
}
.tab_container {
border: 1px solid #999;
border-top: none;
overflow: hidden;
clear: both;
float: left; width: 100%;
background: #fff;
}
.tab_content {
padding: 20px;
font-size: 1.2em;
}
.spacing {
margin-left:90px;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
//When page loads...
$("ul.tabs li:first-child a").addClass("active").show(); //Activate first tab
$(".tab_content #link1").css("display", "block"); //Show first tab content
//On Click Event
$("ul.tabs li a").click(function() {
$("ul.tabs li a").removeClass("active"); //Remove any "active" class
$(".tab_content div").css("display","none");
$(this).addClass("active"); //Add "active" class to selected tab
var activeTab = $(this).attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
</script>
</head>
<body>
<ul class="tabs">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
</ul>
<div class="tab_content spacing">
<div id="link1">
<p>Link1</p>
</div>
<div id="link2">
<p>Link2</p>
</div>
<div id="link3">
<p>Link3</p>
</div>
</div>
</body>
</html>

Try adding this to your css:
div.spacing > div {
display: none;
}
This hides all the divs that are children of the div with the class spacing.
Or, for better 'graceful degredation', hide them in your document.ready function:
$('div.spacing > div').hide();

you might want to use :
$(".tab_content div")live(,"ready",function(){
.... hide tabs that are not link1
})
or as your tabs need javascript to work you can hide them at start and show the first one when ready (just don't forget your noscript tag)

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();
}
});
});

Load div content on show in a tabbed page

I've made a tabbed web page with a switch using jQuery. The tab switch works nice, but now what i want to achieve is to dinamically load div content with AJAX only when the user clicks on a tab for the first time. I've though of putting a flag as an attribute on tab content div, something like data-loaded="0" so that when a user clicks for a second time on the same tab, the data isn't loaded a second time. But what's the best way to dinamically load the data into the div? I'd like to make it general so that the JS (jQuery) function to load data can change for each tab.
Below i've put the code snippet
If someone wants to play with it i've loaded in jsfiddle:
https://jsfiddle.net/ofwvr0hq/
jQuery(document).ready(function() {
$('ul.tabs li').click(function(){
var tab_id = $(this).attr('data-tab');
$('ul.tabs li').removeClass('current');
$('.tab-content').removeClass('current');
$(this).addClass('current');
$("#"+tab_id).addClass('current');
$('ul.tabs li').each(function () {
var nimg = $(this).find('img').attr('src');
$(this).find('img').attr('src', nimg.replace('_r', '_g'));
});
var img = $(this).find( 'img' ).attr('src');
$(this).find( 'img' ).attr('src', img.replace('_g', '_r'));
});
});
ul.tabs{
margin: 0px;
padding: 0px;
list-style: none;
}
ul.tabs li{
line-height: 24px;
background: #ededed;
color: #777;
display: inline-block;
padding: 10px 40px;
cursor: pointer;
font: 16pt arial,verdana !important;
border: 1px solid rgb(164, 162, 162);
border-right: medium none;
margin-right: -5px;
}
ul.tabs li.current{
background: none;
color: rgb(227,32,46);
border-bottom: 0;
border-top: 3px solid rgb(227,32,46);
padding-top: 8px;
}
.tab-content{
display: none;
padding-top: 15px;
}
.tab-content.current{
display: inherit;
}
ul.tabs > li > img {
margin-right: 5px;
width: 24px;
height: 24px;
}
.tabLast {
border-right: 1px solid rgb(164, 162, 162) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="tabs">
<li data-tab="tab-1" class="tab-link"><img style="float:left;" src="http://fantamondi.it/silcam/images/pencil_g.png"> Amministratore</li>
<li data-tab="tab-2" class="tab-link current"><img style="float:left;" src="http://fantamondi.it/silcam/images/pencil_r.png"> Letture</li>
<li data-tab="tab-3" class="tab-link"><img style="float:left;" src="http://fantamondi.it/silcam/images/pencil_g.png"> Unità immobiliari</li>
<li data-tab="tab-5" class="tab-link tabLast"><img style="float:left;" src="http://fantamondi.it/silcam/images/pencil_g.png"> Riparti</li>
</ul>
<div id="tab-1" class="tab-content">TAB 1</div>
<div id="tab-2" class="tab-content current">TAB 2</div>
<div id="tab-3" class="tab-content">TAB 3</div>
<div id="tab-5" class="tab-content">TAB 4</div>
Thanks in advance
You could use jQuery .load(). Basically, you would have a page with the div's with the content you want per page and just load that id when the tab is clicked.
Ex:
$("#tab-container").load( "ajax/tabs.html #tab-1" );
Also see: http://api.jquery.com/load/

js segment function no longer working

All of a sudden I have unintentionally been causing a piece of code to no longer work. I am using the below in order to show and simultaneously hide content within the same website file:
<script type="text/javascript">
$('.tabs').on('click', 'a', function(){
$('section').hide();
$($(this).attr('data-url')).show();
var $this = $(this),
$ul = $this.parents('ul');
$ul.find('a').removeClass('active');
$this.addClass('active');
});
</script>
Below is the html-code that is being displayed and hidden:
<ul class="tabs">
<li><a class="active" href="javascript:void(0);" data-url="#content1">Content1</a></li>
<li>Content2</li>
<li>Content3</li>
</ul>
<section id="content1">
Some content 1
</section>
<section id="content2">
Some content 2
</section>
<section id="content3">
Some content 3
</section>
Below is the CSS code:
section {
display: none;
}
section:first-of-type {
display: block;
}
ul.tabs {
list-style: none;
text-align: center;
}
ul.tabs li {
display: inline-block;
}
ul.tabs li a {
display: inline-block;
width: 100px;
margin-right: 25px;
margin-bottom: 25px;
padding: 5px 5px 5px 5px;
background-color: #ffffff;
border: 1px;
border-style: solid;
border-color: #000000;
text-align: center;
text-decoration: none;
color: #000000;
}
ul.tabs li a:hover {
color: #349cf0;
}
ul.tabs li a.active {
color: #349cf0;
}
I have no idea why this suddenly stopped working. Now I have not included all the stuff thats on the website. Can anyone of you perhaps explain to me what could possibly be interfering with the code? Maybe I accidentally changed something in the js. I received the code from someone else and am not able to spot any errors myself. I would very much appreciate if anyone here will be able to spot any errors!
Thanks in advance
Looks like it is working: http://jsfiddle.net/L0Lnav2t/1/
<script type="text/javascript">
$('.tabs').on('click', 'a', function(){
$('section').hide();
$($(this).attr('data-url')).show();
var $this = $(this),
$ul = $this.parents('ul');
$ul.find('a').removeClass('active');
$this.addClass('active');
});
</script>
I assume your code causes another error before the onclick listener is initialized, rendering it dysfunctional.
On its own it seems to be fine though

how to set a tab to show automatically upon loading webpage

Jsfiddle: http://jsfiddle.net/87YGW/
At present I have to click tab 1 to show content however I want tab 1 content to display automatically upon opening the page.
HTML:
<div id="tab2" class="css-tabs">
<ul class="noint11_menu">
<li id="item-1"> Tab 1
<div>tab conten1
</div>
</li>
<li id="item-2"> Tab 2
<div>
<p>Tab Content 2</p>
</div>
</li>
<li id="item-3"> Tab 3
<div id="notice">
<p>tab content 3 </p>
</div>
</li>
<li id="item-4" title="click for Tab 4"> Tab 4
<div>
<p>Tab Content 4</p>
</div>
</li>
</ul>
</div>​
CSS:
.css-tabs {
position: relative;
text-align: left; /* This is only if you want the tab items at the center */
height: auto
}
.css-tabs ul.noint11_menu {
list-style-type: none;
display: inline-block; /* Change this to block or inline for non-center alignment */
}
.css-tabs ul.noint11_menu > li {
display: block;
float: left;
}
.css-tabs ul.noint11_menu li > a {
color: #EEEEEE;
text-shadow: 1px 1px 1px #000;
font-family: 'MuliLight', Arial, sans-serif;
font-size: 14px;
text-decoration: none;
display: block;
}
.css-tabs ul.noint11_menu li > div {
display: none;
position: absolute;
width: 100%;
}
.css-tabs ul.noint11_menu li > div > p {
border: transparent;
padding: 10px;
margin: 0;
}
.css-tabs ul.noint11_menu li > a:focus {
border-bottom: 1px solid #fff;
}
.css-tabs ul.noint11_menu li:target > a {
cursor: default;
border-bottom: 1px solid #fff;
}
.css-tabs ul.noint11_menu li:target > div {
display: block;
}​
I cannot use Javascript, Jquery or iframe
I cannot demo it in the fiddle (because iframe), but if you link to the first tab directly, eg: http://www.yoururl.com/page#item-1, the first tab's content will be visible on page load.
You can test this by putting all your code inside a new blank html file (CSS and markup in their correct places) and saving it as "test.html". Then make another html file inside the same folder with this code:
<html>
<body>
link
</body>
</html>
Save and open the second file and click the link to go to your styled page. Note the first tab's content is visible, and tab switching still works as expected.
Without JS to redirect or to change the window location, I don't believe you can get the same result through CSS alone.
This article explains why it works: The :target pseudo selector in CSS matches when the hash in the URL and the id of an element are the same.
edit to add another hacky, but pure CSS "solution":
Make the first tab always visible with #item-1 div {display: block}, and set a background colour on all tabs:
.css-tabs ul.noint11_menu li > div {
display: none;
position: absolute;
width: 100%;
left: 0;
color: #ccc;
text-align: left;
padding: 0;
margin-left: 32px;
background: #fff; /* added this */
}
Now the other tabs will hide the first tab when they are selected. demo: http://jsfiddle.net/87YGW/3/
In your CSS add:
#item-1 div {display: block}

Categories