Skip to content

Instantly share code, notes, and snippets.

@Jiert
Last active November 29, 2023 11:40
Show Gist options
  • Save Jiert/bbddb482c28f6c79cccc to your computer and use it in GitHub Desktop.
Save Jiert/bbddb482c28f6c79cccc to your computer and use it in GitHub Desktop.
Creating Tabs with Vanilla JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<title>Tabs</title>
<style>
.nav .active a { color: red; }
.tab-pane { display: none; }
.tab-pane.active { display: block; }
</style>
</head>
<body>
<div>
<!-- Tabs -->
<ul id="nav-tab" class="nav">
<li class="active"><a href="#home">Home</a></li>
<li><a href="#profile">Profile</a></li>
<li><a href="#messages">Messages</a></li>
<li><a href="#settings">Settings</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home">Home Panel</div>
<div class="tab-pane" id="profile">Profile Panel</div>
<div class="tab-pane" id="messages">Messages Panel</div>
<div class="tab-pane" id="settings">Settings Panel</div>
</div>
</div>
<footer>
<script type="text/javascript">
(function(){
function onTabClick(event){
var actives = document.querySelectorAll('.active');
// deactivate existing active tab and panel
for (var i=0; i < actives.length; i++){
actives[i].className = actives[i].className.replace('active', '');
}
// activate new tab and panel
event.target.parentElement.className += ' active';
document.getElementById(event.target.href.split('#')[1]).className += ' active';
}
var el = document.getElementById('nav-tab');
el.addEventListener('click', onTabClick, false);
})();
</script>
</footer>
</body>
</html>
Copy link

ghost commented Jan 5, 2015

Line 46: I am getting "Uncaught TypeError: Cannot read property 'className' of null" on Chrome and "null is not an object" on Safari.

@Jiert
Copy link
Author

Jiert commented Jan 6, 2015

It sounds like parentElement isn't defined. What versions of chrome and safari are you using?

@JonathanMontane
Copy link

JonathanMontane commented Jul 4, 2016

a small warning:

40: actives[i].className = actives[i].className.replace('active', '');

will replace some-other-class-that-contains-active-keyword into some-other-class-that-contains--keyword, and will only remove the first occurence of the classname in the whole className string. A preferred solution might be to use the regex /(^|\s)active($|\s)/g

A more generic clearClass could be:

function clearClass(selector, className) {
    var selection = document.querySelector(selector);
    var re = new RegExp("(^|\\s)" + className + "($|\\s)", "g");
    for (var i = selection.length - 1; i >= 0 ; i--) {
        selection[i].className = selection[i].className.replace(re, ' ');
    }
}

Note that this clearClass function will fail if there are two instances of the className right next to each other.

@Zara603
Copy link

Zara603 commented May 8, 2020

There's few problems with this implementation, it's listening to any click on nav-tab so if user clicks on ul or li there's no href and event.target.href is undefined so you cant .split on it. Also instead of using split you could simply use getAttribute("href")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment