Check if navbar got clicked - javascript

I have a navbar and want to close it when clicking outside. The only thing I need to check is the click event of the body.
var navBtnActive = true;
function toggleMenu(){
navBtnActive = !navBtnActive;
$("#navContent").slideToggle();
}
$('body').click(function() {
// if( clicked target is NOT the menu ){
// if(navBtnActive){ // just if the menu is open
// toggleMenu();
// }
// }
});
#navContainer {
position: relative;
display: inline-block;
}
#navContent button {
display: block;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navContainer">
<button onclick="toggleMenu()">Menu</button>
<div id="navContent">
<button onclick="toggleMenu()">Slider</button>
<button onclick="toggleMenu()">Calculator</button>
<button onclick="toggleMenu()">Imageupload</button>
<button onclick="toggleMenu()">Settings</button>
<button onclick="toggleMenu()">Search</button>
<button onclick="toggleMenu()">Servercall</button>
</div>
</div>
As you can see below, my $('body').click(function() got the code for closing it. I just want to get a way checking if the clicked object is the menu itself or not. If not, close the menu.

Hi you can try this code
var navBtnActive = true;
function toggleMenu(e) {
navBtnActive = !navBtnActive;
$("#navContent").slideToggle();
}
jQuery(document).on('click', function() {
$("#navContent").slideUp();
});
jQuery('#navContainer').on('click', function(e) {
e.stopPropagation();
});
#navContainer {
position: relative;
display: inline-block;
}
#navContent button {
display: block;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navContainer">
<button onclick="toggleMenu()">Menu</button>
<div id="navContent">
<button onclick="toggleMenu()">Slider</button>
<button onclick="toggleMenu()">Calculator</button>
<button onclick="toggleMenu()">Imageupload</button>
<button onclick="toggleMenu()">Settings</button>
<button onclick="toggleMenu()">Search</button>
<button onclick="toggleMenu()">Servercall</button>
</div>
</div>

just check the click targer jQuery event targer
$('body').click(function(e){
var $elem = $(e.target);
if ($elem.attr('id') === 'my_nav_bar_id') {
doSomething();
}
});

Here you go with a solution https://jsfiddle.net/ap7m4xnu/
var navBtnActive = true;
$('#menuToggle').click(function(e){
e.stopPropagation();
navBtnActive = !navBtnActive;
$("#navContent").slideToggle();
})
$('body').not('#menuToggle').click(function(e) {
e.preventDefault();
$("#navContent").slideUp();
});
#navContainer {
position: relative;
display: inline-block;
}
#navContent button {
display: block;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navContainer">
<button id="menuToggle">Menu</button>
<div id="navContent">
<button onclick="toggleMenu()">Slider</button>
<button onclick="toggleMenu()">Calculator</button>
<button onclick="toggleMenu()">Imageupload</button>
<button onclick="toggleMenu()">Settings</button>
<button onclick="toggleMenu()">Search</button>
<button onclick="toggleMenu()">Servercall</button>
</div>
</div>

You can use the compareDocumentPosition method. You can read its documentation here: https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
You can test if the clicked element is contained by the menu by doing the following:
var DOCUMENT_POSITION_CONTAINED_BY = 16;
if ((navContainer.compareDocumentPosition(clickedElement) & DOCUMENT_POSITION_CONTAINED_BY) !== 0) {
// clicked element is inside the menu
} else {
// clicked element is outside of the menu
}
In your example it would work like this:
var navBtnActive = true;
function toggleMenu(){
navBtnActive = !navBtnActive;
$("#navContent").slideToggle();
}
$('body').click(function(event) {
var DOCUMENT_POSITION_CONTAINED_BY = 16,
navContainer = document.getElementById('navContainer'),
compareResult = navContainer.compareDocumentPosition(event.target) & DOCUMENT_POSITION_CONTAINED_BY;
if (compareResult === 0) {
// clicked element is outside of the menu
toggleMenu();
}
});
#navContainer {
position: relative;
display: inline-block;
}
#navContent button {
display: block;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navContainer">
<button onclick="toggleMenu()">Menu</button>
<div id="navContent">
<button onclick="toggleMenu()">Slider</button>
<button onclick="toggleMenu()">Calculator</button>
<button onclick="toggleMenu()">Imageupload</button>
<button onclick="toggleMenu()">Settings</button>
<button onclick="toggleMenu()">Search</button>
<button onclick="toggleMenu()">Servercall</button>
</div>
</div>

function toggleMenu(){
$("#navContent").slideToggle();
}
$('body').click(function(e) {
if(document.querySelector('body')== e.toElement && $("#navContent").is(':visible')){
$("#navContent").slideToggle();
}
});
#navContainer {
position: relative;
display: inline-block;
}
#navContent button {
display: block;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navContainer">
<button onclick="toggleMenu()">Menu</button>
<div id="navContent">
<button onclick="toggleMenu()">Slider</button>
<button onclick="toggleMenu()">Calculator</button>
<button onclick="toggleMenu()">Imageupload</button>
<button onclick="toggleMenu()">Settings</button>
<button onclick="toggleMenu()">Search</button>
<button onclick="toggleMenu()">Servercall</button>
</div>
</div>

Related

Can't remove event listener dynamically

I am building a game and on a certain condition I need to remove the event listener from a <div> that has just been clicked. I don't want the user to click twice on the same div. I'm trying to use .removeEventListener
Here's my code.
let Divs = document.querySelectorAll(".data")
Divs.forEach((v, k) => {
v.addEventListener("click", (e) => {
clic(e, v, k)
});
});
function clic(e, v, k) {
console.log("CLICK");
Divs[k].removeEventListener("click", (e) => {
clic(e, v, k)
});
}
a game with 9 div! Are you making a tictactoe?:)
little snippet with 9 div, I've added a button in div 6 to remove event for div5
I put the remove in a function, so you can call it with a condition somewhere in your code. You have to pass the name of the div
Array.from(document.querySelectorAll('.grid>div')).forEach(el => {
el.addEventListener('click', divclickadd);
});
function divclickadd(ev) {
console.log(ev.target);
}
document.querySelector('button').addEventListener('click', function(evt) {
evt.stopImmediatePropagation();
console.log(evt.target.className);
divclickremove(evt.target.className);
});
function divclickremove(div) {
const el = document.querySelector('#' + div);
console.log(el);
el.removeEventListener('click', divclickadd);
}
*,
*:before,
*:after {
box-sizing: border-box;
}
html,
body {
overflow: hidden;
margin: 0;
padding: 0;
}
body {
width: 100vw;
height: 100vh;
}
.grid {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
gap: 10px;
width: 100%;
height: 100%;
}
.grid>div {
display: flex;
justify-content: center;
align-items: center;
}
<div class="grid">
<div id="div1" style="background-color: red">div 1</div>
<div id="div2" style="background-color: blue">div 2</div>
<div id="div3" style="background-color: green">div 3</div>
<div id="div4" style="background-color: yellow">div 4</div>
<div id="div5" style="background-color: purple">div 5</div>
<div id="div6" style="background-color: brown">div 6
<button class="div5">remove event 5</button>
</div>
<div id="div7" style="background-color: darkolivegreen">div 7</div>
<div id="div8" style="background-color: orangered">div 8</div>
<div id="div9" style="background-color: cadetblue">div 9</div>
</div>
as I said, I put a button to remove event as example to call the function. You can call the function to remove other way. As the function is written at the moment, you just need to pass the name of the id. Regarding what you are saying it you need to remove event listener of a specific clicked button...
let condition = false;
Array.from(document.querySelectorAll('button.game')).forEach(el => {
el.addEventListener('click', divclickadd);
});
function divclickadd(ev) {
ev.stopImmediatePropagation();
console.log(ev.target);
if (condition) {
divclickremove(ev.target);
}
}
document.querySelector('button.condition').addEventListener('click', function(evt) {
evt.stopImmediatePropagation();
condition = true;
console.log(condition);
});
function divclickremove(el) {
console.log(el);
el.removeEventListener('click', divclickadd);
}
button {
display: block;
}
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<br>
<button class="condition">change condition value</button>
if you click on change condition value, next time you click on button event, it'll fire because remove not yet fired. Next next time, it's not remove event has been done.

JS remove div with button after cloning

I have problem with removing div containing button. First I clone and add button, then change its class from 'add' to 'remove'. Then I try to remove div containing button with 'remove' but I can't access remove functions.
<div class="margin"></div>
<div class='new'>
<button type="button" class="btn btn-success add"><i class="fas fa-plus"></i></button>
</div>
<script>
$(document).ready(function() {
var div = document.getElementById('new');
$(".add").click(function(){
clone = div.cloneNode(true);
$(clone).insertAfter(".margin");
$("button.add:not(:last)).removeClass('add').addClass('remove');
$(".remove").click(function(){
console.log('inside')
//$(this).parent('div').remove();
});
});
</script>
document.getElementById('new') ... ur element does not have an ID. Its class-name is 'new' but not its ID. Some corrections should make it work:
$(document).ready(function() {
var div = document.getElementById('new');
$(".add").click(function(){
clone = div.cloneNode(true);
$(clone).insertAfter(".margin");
$("button.add:not(:last)").removeClass('add').addClass('remove');
$(".remove").click(function(){
console.log('inside')
//$(this).parent('div').remove();
});
})
});
.add {
background: green;
}
.remove {
background: red;
}
button {
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="new">
<button type="button" class="btn btn-success add">
<i class="fas fa-plus"></i> new
</button>
</div>
<div class="margin"></div>
Edit:
Is there a more elegant way to do this?
Maybe like so:
$('.add').on('click', function() {
$(this).clone()
.toggleClass('add remove')
.on('click', function() {
$(this).remove()
})
.prependTo('#new');
})
.add {
background: green;
}
.remove {
background: red;
}
button {
color: white;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="new">
<button type="button" class="btn btn-success add">
<i class="fas fa-plus"></i> new
</button>
</div>

style.display = "none" not working in javascript

function showTodos(e) {
document.getElementById('modal_todos').style.display = "block";
}
function closeTodoDiv(e) {
document.getElementById('modal_todos').style.display = "none";
}
<div class=" modal modal-todos" id="modal_todos">
<button style="float: right; margin-top:3px;margin-right:8px;">x</button>
<button class="btn btn-secondary btn-sm">Add new Todo</button>
<h2>dfdfdf</h2>
<h2>dfdfdf</h2>
</div>
I can't close my popuped up div on button click.Can't understand why "none" is not working, though my showTodos() is working fine. Also the ID used in unique.
You need to attach a click event for the buttons using the onclick attribute.
function showTodos(e) {
document.getElementById('modal_todos').style.display = "block";
}
function closeTodoDiv(e) {
document.getElementById('modal_todos').style.display = "none";
}
* {
margin: 0;
}
.modal {
background-color: #ccc;
}
.o-btn {
position: absolute;
top: 0;
z-index: -1;
}
<div class="modal modal-todos" id="modal_todos">
<!-- added onclick="closeTodoDiv()" -->
<button style="float: right; margin-top:3px;margin-right:8px;" onclick="closeTodoDiv()">x</button>
<button class="btn btn-secondary btn-sm">Add new Todo</button>
<h2>dfdfdf</h2>
<h2>dfdfdf</h2>
</div>
<!-- button to open the modal. added onclick="showTodos()" -->
<button class="o-btn" onclick="showTodos()">open modal</button>
A modern and better approach is to use addEventListener method instead of the inline events and also to store a reference for the modal to improve performance.
const modal = document.getElementById('modal_todos'),
btnOpen = document.getElementById('open'),
btnClose = document.getElementById('close');
btnOpen.addEventListener('click', () => modal.style.display = 'block');
btnClose.addEventListener('click', () => modal.style.display = 'none');
* {
margin: 0;
}
.modal {
background-color: #ccc;
}
.o-btn {
position: absolute;
top: 0;
z-index: -1;
}
<div class="modal modal-todos" id="modal_todos">
<button style="float: right; margin-top:3px;margin-right:8px;" id="close">x</button>
<button class="btn btn-secondary btn-sm">Add new Todo</button>
<h2>dfdfdf</h2>
<h2>dfdfdf</h2>
</div>
<button class="o-btn" id="open">open modal</button>
You should use this logic using listeners on your buttons:
const $modalTodos = document.getElementById('modal_todos')
const $btnOpenModal = document.getElementById('btn-open-modal')
const $btnCloseModal = document.getElementById('btn-close-modal')
$btnOpenModal.addEventListener('click', showTodos)
$btnCloseModal.addEventListener('click', closeTodoDiv)
function showTodos() {
$modalTodos.style.display = "block";
}
function closeTodoDiv() {
$modalTodos.style.display = "none";
}
.modal {
display: none
}
<button id="btn-open-modal">open</button>
<div class=" modal modal-todos" id="modal_todos">
<button id="btn-close-modal" style="float: right; margin-top:3px;margin-right:8px;">x</button>
<button class="btn btn-secondary btn-sm">Add new Todo</button>
<h2>dfdfdf</h2>
<h2>dfdfdf</h2>
</div>

How could I add a border to make element look like a tree and keep it positioned correctly when resizing?

I am trying to step away from jsTree as this is not as much as configurable as having my own custom code. I am making use of Bootstrap to have a somewhat similar functionality as jsTree. I am also stepping away from jQuery (for now), because of debugging reasons.
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
JSFiddle
I added a border in a .column-*-1 to allow for some spacing for the border:
The spacing however, I find a bit too much. How could I address this problem? I would like to refrain from styling Bootstrap's grid system (meaning I preferably would not want to touch any styling behind .col-* and .row classes etc.) because this might break the responsiveness or anything else related to Bootstrap.
Edit:
I also noticed that when adding a lot of buttons by just clicking them, the layout of tree will start failing as well. (I am aware this is a different question, so if I need to post another question regarding this problem, please do let me know) Is there a way I could address this so that the element works correctly?
Add this little CSS
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
Here I have used absolute positioning and increased height by 5px which kind of makes it touches the next div element.
Here is the Fiddle Link
and the Code Snippet:
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: calc(100% + 5px);
margin-left: 20px;
position: absolute;
}
.flex {
position: relative;
display: flex;
}
.col-xs-11 .col-xs-12 {
padding-left: 0;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>

Show a hidden div while making another hidden

I am looking for a way to toggle through three stacked div's where a button press will trigger an onclick function to make that specific div visible and hiding the others. I have included a jsfiddle below with the code I currently have any help on this would be amazing!
function togglediv(id1, id2, id3) {
var idOne = document.getElementById(id1);
var idTwo = document.getElementById(id2);
var idThree = document.getElementById(id3);
idOne.style.display = idOne.style.display == "block" ? "none" : "block";
idTwo.style.display = idTwo.style.display == "none";
idThree.style.display = idThree.style.display == "none";
}
<div class="table-responsive">
<button type="button" class="btn btn-primary" onclick="togglediv('inner-dung', 'inner-boss', 'inner-item')">
Dungeon
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-boss', 'inner-dung', 'inner-item')">
Boss
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-item', 'inner-dung', 'inner-boss')">
Item
</button>
</div>
<div id="search-dung">
<div id="inner-dung">
DUNGEON
</div>
<div id="inner-boss">
BOSS
</div>
<div id="inner-item">
ITEM
</div>
</div>
JSFiddle
You can pass the ID you want to show to the function, use a CSS class to toggle display: none/block, toggle that class on the element you click on and hide the rest by removing the class.
.table-responsive {
margin: 0px auto;
width: 90%;
}
#search-dung {
margin: 0px auto;
width: 90%;
height: 50%;
background-color: white;
border: 1px solid red;
}
#inner-dung,
#inner-item,
#inner-boss {
position: absolute;
margin: 0px auto;
width: 90%;
height: 50%;
background-color: white;
border: 1px solid red;
display: none;
}
#inner-dung.show,
#inner-item.show,
#inner-boss.show {
display: block;
}
<div class="table-responsive">
<button type="button" onclick="togglediv('inner-dung')">
Dungeon
</button>
<button type="button" onclick="togglediv('inner-boss')">
Boss
</button>
<button type="button" onclick="togglediv('inner-item')">
Item
</button>
</div>
<div id="search-dung">
<div id="inner-dung">
DUNGEON
</div>
<div id="inner-boss">
BOSS
</div>
<div id="inner-item">
ITEM
</div>
</div>
<script>
var els = document.getElementById('search-dung').getElementsByTagName('div');
function togglediv(id) {
var el = document.getElementById(id);
for (var i = 0; i < els.length; i++) {
var cur = els[i];
if (cur.id == id) {
cur.classList.toggle('show')
} else {
cur.classList.remove('show');
}
}
}
</script>
function togglediv(id1, id2, id3) {
var idOne = document.getElementById(id1);
var idTwo = document.getElementById(id2);
var idThree = document.getElementById(id3);
idOne.style.display = "block";
idTwo.style.display = "none";
idThree.style.display = "none";
}
https://codepen.io/anon/pen/NjOpJw
a couple of of problems there.
use onClick rather than onclick
idOne.style.display = idOne.style.display == "block" ? "none" : "block"; will return a boolean so you should change it for this
idOne.style.display = "block";
set your javascript to load in the body.
here's a working version
https://jsfiddle.net/83qwrk70/1/
You can use a switch case, passing only the element you want to show in toggle div
//index.html
<button type="button" class="btn btn-primary" onclick="togglediv('inner-dung')">
Dungeon
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-boss')">
Boss</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-item')">
Item </button>
//index.js
function show(el) {
el.style.display = 'block';
}
function hide(el) {
el.style.display = 'none';
}
function togglediv(selected) {
var idOne = document.getElementById('inner-dung');
var idTwo = document.getElementById('inner-boss');
var idThree = document.getElementById('inner-item');
switch(selected) {
case 'inner-dung': {
show(idOne);
hide(idTwo);
hide(idThree);
break;
}
case 'inner-boss': {
hide(idOne);
show(idTwo);
hide(idThree);
break;
}
case 'inner-item': {
hide(idOne);
hide(idTwo);
show(idThree);
break;
}
}
}
Here is another option that is scaleable:
var active = "inner-dung",
inactive = ["inner-boss", "inner-item"];
var toggleDiv = function (id) {
active = inactive.splice(inactive.indexOf(id), 1, active);
document.getElementById(active).style.display = "block"; // or use style sheet
for (var i = 0; i < inactive.length; i++) {
document.getElementById(inactive[i]).style.display = "none"; // or use style sheet
}
}
If there is no default active item, you can put "inner-dung" in the array as well. If you do that, the "inactive" array will receive "undefined" the first time, but it will not get in the way of the purpose.
You don't have to use a for-loop of course, but if you have more items you would.
"Teach your children well"
Apply a rule to the parent to influence the children.
document.querySelector( "form" ).addEventListener( "click", function( evt ) {
var n = evt.target.name;
if ( n ) {
document.querySelector( "#foobarbaz" ).setAttribute( "class", n );
}
}, false );
#foo,
#bar,
#baz {
display: none;
}
#foobarbaz.foo #foo,
#foobarbaz.bar #bar,
#foobarbaz.baz #baz {
display: block;
}
<div id="foobarbaz" class="foo">
<div id="foo">Foo!</div>
<div id="bar">Bar?</div>
<div id="baz">Baz.</div>
</div>
<form>
<input type="button" value="Foo" name="foo">
<input type="button" value="Bar" name="bar">
<input type="button" value="Baz" name="baz">
</form>

Categories

Resources