I want to make menu toggle and one item from menu is open at a time. I am able to open one item at a time but unable to do toggle at the same time.
var navclick = document.getElementsByClassName("js-dropdown");
var navContent = document.getElementsByClassName('-arrow-link-content');
for (var i = 0; i < navclick.length; i++) {
navclick[i].onclick = function () {
if (this.parentNode.querySelector('div.-arrow-link-content').classList.contains('nav-active')) {
this.parentNode.querySelector('div.-arrow-link-content').classList.remove('nav-active');
}
else {
this.parentNode.querySelector('div.-arrow-link-content').classList.add('nav-active');
}
}
}
.-arrow-link-content {
display:none;
}
.nav-active{ display:block;}
<ul class="c-icons" id="c-iconslist">
<li>
<div class="c-icons__text js-dropdown">heading 1</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 1</div>
</li>
<li>
<div class="c-icons__text js-dropdown">heading 2</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 2</div>
</li>
</ul>
if anyone have any suggestions.. please share.. Thanks in advance
For toggle to work, we need to get all the node with class name -arrow-link-content, and then remove the nav-active class first, then add nav-active to the selected item.
Check the snippet.
var navclick = document.getElementsByClassName("js-dropdown");
var navContent = document.getElementsByClassName('-arrow-link-content');
for (var i = 0; i < navclick.length; i++) {
navclick[i].onclick = function() {
if (this.parentNode.querySelector('div.-arrow-link-content').classList.contains('nav-active')) {
this.parentNode.querySelector('div.-arrow-link-content').classList.remove('nav-active');
return false
}
var el = document.querySelectorAll('div.-arrow-link-content');
for (var i = 0; i < el.length; i++) {
if (el[i].classList.contains('nav-active')) el[i].classList.remove('nav-active');
}
this.parentNode.querySelector('div.-arrow-link-content').classList.add('nav-active');
}
}
.-arrow-link-content {
display: none;
}
.nav-active {
display: block;
}
<ul class="c-icons" id="c-iconslist">
<li>
<div class="c-icons__text js-dropdown">heading 1</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 1</div>
</li>
<li>
<div class="c-icons__text js-dropdown">heading 2</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 2</div>
</li>
</ul>
Since at most one element can be open at a time, we just have to look for that one elment and close it first if it exists, before we open an unopened element
var navclick = document.getElementsByClassName("js-dropdown");
var navContent = document.getElementsByClassName('-arrow-link-content');
for (var i = 0; i < navclick.length; i++) {
navclick[i].onclick = function () {
if (this.parentNode.querySelector('div.-arrow-link-content').classList.contains('nav-active')) {
this.parentNode.querySelector('div.-arrow-link-content').classList.remove('nav-active');
}
else {
try {
// if an open element exists, close it first
this.parentNode.parentNode.querySelector('.nav-active').classList.remove('nav-active');
}
catch (error){
// Error occurs when no open elment exists, in that case: Do nothing
}
this.parentNode.querySelector('div.-arrow-link-content').classList.add('nav-active');
}
}
}
.-arrow-link-content {
display:none;
}
.nav-active{ display:block;}
<ul class="c-icons" id="c-iconslist">
<li>
<div class="c-icons__text js-dropdown">heading 1</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 1</div>
</li>
<li>
<div class="c-icons__text js-dropdown">heading 2</div>
<div class="c-icons__textdropdown -arrow-link-content"> Content 2</div>
</li>
</ul>
Related
I want to display one div at a time and hide other .
Need the same effect like:http://jsfiddle.net/cqDES/1552/
<ul class="nav-sidebar">
<li>elem1</li>
<li> elem2</li>
<li> elem3</li>
</ul>
<div id="div1">this is div 1</div>
<div id="div2">this is div 2</div>
<div id="div3">this is div 3</div>
If you don't want sliding effect use show()/hide()
$(() => {
$('div:not(#div0)').hide();
$('.nav-sidebar li').click(function () {
var index = $(this).index() + 1;
$(`div:not(#div${index})`).hide();
$(`#div${index}`).show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav-sidebar">
<li>elem1</li>
<li> elem2</li>
<li> elem3</li>
</ul>
<div id="div1">this is div 1</div>
<div id="div2">this is div 2</div>
<div id="div3">this is div 3</div>
You can use show()/hide() functions :
$(function() {
$('.nav-sidebar li').click(function() {
var index = $(this).index() + 1;
$('div:not(#div' + index + ')').hide();
$('#div' + index).show();
});
});
div[id^='div']
{
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav-sidebar">
<li>elem1</li>
<li> elem2</li>
<li> elem3</li>
</ul>
<div id="div1">this is div 1</div>
<div id="div2">this is div 2</div>
<div id="div3">this is div 3</div>
show function Documentation
hide function Documentation
I think this is what you are asking for.
JSFiddle
$(function() {
var panels = $('div').hide();
var tabs = $('.nav-sidebar li');
tabs.click(function(orgEvent) {
let clickedTabIndex = tabs.index(orgEvent.currentTarget);
panels.each((index, panel)=>{
$(panel)[index === clickedTabIndex ? "slideDown" : "slideUp"]();
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav-sidebar">
<li> elem1</li>
<li> elem2</li>
<li> elem3</li>
</ul>
<div id="div1">this is div 1</div>
<div id="div2">this is div 2</div>
<div id="div3">this is div 3</div>
How can I create a JS script that show/hidden and vice versa. Toggle divs based on it's state (display:none or display:inline) at clicking a list of elements? I'm struggling with the logic...
Here is the fiddle I tried Fiddle.
document.addEventListener('DOMContentLoaded', function() {
let panel = document.getElementsByClassName('panel');
let menu = document.getElementsByTagName('li');
console.log(menu, panel);
//recorre los elementos <li> y coloca un eventlistner 'click'
for (let i = 0; i < menu.length; i++) {
menu[i].addEventListener('click', function() {
//for(let j = 0; j < panel.length; j ++){
panel[i].style.display == 'inline' ? panel[i].style.display = 'inline' : panel[i].style.display = 'none';
//}
});
}
}, false);
#one {
display: inline;
}
#two {
display: none;
}
#three {
display: none;
}
#four {
display: none;
}
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
</ul>
<div class='panel' id='one'> ONE </div>
<div class='panel' id='two'> TWO </div>
<div class='panel' id='three'> THREE </div>
<div class='panel' id='four'> FOUR </div>
Your panel display / hide logic is wrong, I've corrected it and working example is below
document.addEventListener('DOMContentLoaded', function() {
let panel = document.getElementsByClassName('panel');
let menu = document.getElementsByTagName('li');
for (let i = 0; i < menu.length; i++) {
menu[i].addEventListener('click', function() {
panel[i].style.display == 'inline' ? panel[i].style.display = 'none' : panel[i].style.display = 'inline';
});
}
}, false);
#one {
display: inline;
}
#two {
display: none;
}
#three {
display: none;
}
#four {
display: none;
}
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
</ul>
<div class='panel' id='one'> ONE </div>
<div class='panel' id='two'> TWO </div>
<div class='panel' id='three'> THREE </div>
<div class='panel' id='four'> FOUR </div>
You could use onclick="MyFunction()" (w3schools) to get clicks from the li elements.
<ul>
<li onclick="handleClick(1)">Panel 1</li>
<li onclick="handleClick(2)">Panel 2</li>
<li onclick="handleClick(3)">Panel 3</li>
<li onclick="handleClick(4)">Panel 4</li>
</ul>
Then a simple handler function to catch the click events
var handleClick = function(index) {
let panel = document.getElementsByClassName('panel');
for (let i=0; i<panel.length; i++) {
panel[i].style.display = (index - 1) == i ? 'inline' : 'none';
}
};
Check out my working fiddle.
Also you had one div closing tag wrong in your fiddle.
<div class="one panel" id="one">
<div>
PANEL #1
</div>
<div class="two panel" id="two">
<div>
PANEL #2
</div>
</div>
</div>
I'm trying to loop through some elements with an attribute and based on which element I click, I'd like the is-active class to be added to the specific element.
The top section works, clicking on the specific tab, but the problem is with tabBody.
Right now, it adds the class to ALL elements and I cannot figure out where to put this to reference the correct div.
I just want whichever tab-body is active, to be the same tabs-bg is active, and have all that based on which tab is clicked.
I have this code (I've tried let el = this, says already defined):
const tab = document.querySelectorAll('[data-tabs-tab]');
const tabBody = document.querySelectorAll('[data-tabs-body]');
function changeMe() {
const activeTab = this.hasAttribute('data-tabs-tab');
[...tab].forEach(el => {
if (this !== el) {
el.classList.remove('is-active');
}
});
this.classList.add('is-active');
[...tabBody].forEach(el => {
if (el.hasAttribute('data-tabs-body') == activeTab) {
if (el.classList.contains('tabs-bg')) {
el.classList.add('is-active');
}
} else {
el.classList.remove('is-active');
}
});
}
tab.forEach(el => el.addEventListener('click', changeMe));
<div class="tabs" data-tabs>
<nav>
<ul class="tabs__tabs">
<li data-tabs-tab="one" class="is-active"></li>
<li data-tabs-tab="two"></li>
<li data-tabs-tab="three"></li>
</ul>
</nav>
<div class="tabs__content">
<div data-tabs-body="one" class="tab-body is-active"></div>
<div data-tabs-body="two" class="tab-body"></div>
<div data-tabs-body="three" class="tab-body"></div>
</div>
</div>
<div class="tabs__bg">
<div data-tabs-body="one" class="tabs-bg is-active"></div>
<div data-tabs-body="two" class="tabs-bg"></div>
<div data-tabs-body="three" class="tabs-bg"></div>
</div>
.hasAttribute() just checks to see if the attribute exists on the element. You should be using .getAttribute() instead to get the value of the attribute.
Also, not sure why the if (el.classList.contains('tabs-bg')) block was in there, but I commented it out to make the demo work.
const tab = document.querySelectorAll('[data-tabs-tab]');
const tabBody = document.querySelectorAll('[data-tabs-body]');
function changeMe() {
const activeTab = this.getAttribute('data-tabs-tab'); // Change here
[...tab].forEach(el => {
if (this !== el) {
el.classList.remove('is-active');
}
});
this.classList.add('is-active');
[...tabBody].forEach(el => {
if (el.getAttribute('data-tabs-body') === activeTab) { // and here
//if (el.classList.contains('tabs-bg')) {
el.classList.add('is-active');
//}
} else {
el.classList.remove('is-active');
}
});
}
tab.forEach(el => el.addEventListener('click', changeMe));
.is-active {color: red;}
<div class="tabs" data-tabs>
<nav>
<ul class="tabs__tabs">
<li data-tabs-tab="one" class="is-active">Tab 1</li>
<li data-tabs-tab="two">Tab 2</li>
<li data-tabs-tab="three">Tab 3</li>
</ul>
</nav>
<div class="tabs__content">
<div data-tabs-body="one" class="tab-body is-active">Tab Body Content 1</div>
<div data-tabs-body="two" class="tab-body">Tab Body Content 2</div>
<div data-tabs-body="three" class="tab-body">Tab Body Content 3</div>
</div>
</div>
<div class="tabs__bg">
<div data-tabs-body="one" class="tabs-bg is-active">Tab Body BG 1</div>
<div data-tabs-body="two" class="tabs-bg">Tab Body BG 2</div>
<div data-tabs-body="three" class="tabs-bg">Tab Body BG 3</div>
</div>
I want to show only a particular div by calling a function though onclick event .At a time I just want to show a single div and rest all divs should not show in my web page. I have tried this through using display css property.I just want a single function which can handle this .I can do this question by making more than one function.
<html>
<head>
</head>
<body>
<ul>
<li>1</li><!-- show div1-->
<li>2</li><!-- show div2-->
<li>3</li><!-- show div3-->
</ul>
<div id="first">content 1</div>
<div id="second">content2</div>
<div id="third">content3</div>
</body>
</html>
How about this:
Each div needs the same class so you can find and hide them all at once.
The function needs to know the id of the div to show, so pass in the id.
See changes below:
<html>
<head>
</head>
<body>
<ul id="controls">
<li>1</li><!-- show div1-->
<li>2</li><!-- show div2-->
<li>3</li><!-- show div3-->
</ul>
<div id="first" class="content">content 1</div>
<div id="second" class="content">content2</div>
<div id="third" class="content">content3</div>
<script>
$("#controls a").click(function() {
someFunction($(this).attr("data-target"));
});
function someFunction(divId) {
$(".content").hide();
$("#" + divId).show();
}
</script>
</body>
</html>
Note: You need a reference to jQuery for the $ syntax to work.
FYI, you could do this with just CSS:
.panel {display: none}
.panel:target {display: block}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div class='panel' id="first">content 1</div>
<div class='panel' id="second">content2</div>
<div class='panel' id="third">content3</div>
I think this is what you want:
<ul>
<li id="li_1">1
</li>
<li id="li_2">2
</li>
<li id="li_3">3
</li>
</ul>
<div class='panel' id="li_1_panel">content 1</div>
<div class='panel' id="li_2_panel">content2</div>
<div class='panel' id="li_3_panel">content3</div>
.panel {
display: none;
}
var panelID = "";
for (i = 1; i <= 3; i++) {
alert('#li_' + i);
$('#li_' + i).on('click', function () {
panelID = "#" + $(this).attr("id") + "_panel";
alert(panelID);
$(panelID).toggle();
});
}
Edit
Also, if you did not want to rely on a rigid naming scheme, you could use a hash.
<ul>
<li id="zeus">1
</li>
<li id="athena">2
</li>
<li id="hades">3
</li>
</ul>
<div class='panel' id="isis">content 1</div>
<div class='panel' id="thor">content 2</div>
<div class='panel' id="aphrodite">content 3</div>
var panelID = "";
var li_to_panel = {
"zeus": "isis",
"athena": "thor",
"hades": "aphrodite"
};
$.each(li_to_panel, function(key, value){
alert(key);
liID = "#" + key;
$(liID).on('click', function () {
panelID = "#" + li_to_panel[$(this).attr('id')];
alert(panelID);
$(panelID).toggle();
});
});
I need to hide the present div and show next hide
here is my codes
$(document).ready(function() {
$('#next').click(function() {
$(this).next().next().children("div").hide();
$(this).next().next().children("div").show();
});
});
#div2,
#div3 {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<button id="prev">Prev</button>
<button id="next">Next</button>
<hr />
<div id="main">
<div id="div1">Div 1</div>
<div id="div2">Div 2</div>
<div id="div3">Div 3</div>
</div>
DEMO
Look at this.
Handles start/end using css classes, kept js simple.
What about something like this?
$(document).ready(function() {
var currentDiv = 0;
$('#next').click(function() {
$('#div' + (currentDiv + 1)).hide();
currentDiv = (currentDiv + 1) % 3;
$('#div' + (currentDiv + 1)).show();
});
});
try something a little different
$(document).ready(function() {
$('#next').click(function() {
$eL=$('#main').children('div').filter(":visible");
$('#main').children().hide();
if($eL.next().length>0){
$eL.next().show();
}else{
$('#main div')[0].show();
}
});
$('#prev').click(function() {
$eL=$('#main').children('div').filter(":visible");
$('#main').children().hide();
if($eL.previous().length>0){
$eL.previous().show();
}else{
$('#main div')[$('#main div').length - 1].show();
}
});
});
edit: this function assumes one of the child divs is already visible when the page loads.
edit: added for previous button
Something like this (next and previous handled):
.item{
display:none;
}
var activeItem = 0;
function switchItem(isNext) {
if (isNext) {
activeItem++;
} else {
activeItem--;
}
activeItem = (activeItem == 3) ? 0 : activeItem;
activeItem = (activeItem == -1) ? 2 : activeItem;
showItem($("#main"), activeItem);
}
function showItem(selector, index) {
selector.find(".item").hide().eq(index).toggle();
}
<div id="main">
<div id="div1" class="item">Div 1</div>
<div id="div2" class="item">Div 2</div>
<div id="div3" class="item">Div 3</div>
</div>
Below is the code.
<ul class="grid">
<li class="object">
List Item 1<a class="show-next"> Show the next list item</a>
</li>
<li class="object">
List Item 2
<a class="show-next">Show the next list item</a>
</li>
<li class="object">
List Item 3
<a class="show-next">Show the next list item</a>
</li>
</ul>
Below is the script you should insert.
$('.grid .object').hide().filter(':lt(1)').show();
$('.show-next').click(function(){
$eL = $('.grid .object').filter(":visible");
// $(".grid").find(".object").hide().next().show();
if($eL.next().length>0){
$eL.next().show();
}else{
$('.grid .object')[0].show();
}
});