Nested element in button element are not clickable - javascript

I am having this problem, I created a button, and inside I have a for Icon, and inside the element I have span to style the text next to the Icon (the Icon from is humberger from awesome font)
the issue is:
in javascript, I created an onclick function for the button element using the ID btnm, but when I click on the text or the icon in the button does work though when I click around the text and the icon in the button the onclick works fine.
I cannot understand why the icon and text are in the button.
please help
document.addEventListener('DOMContentLoaded', function(){
var menubtn = document.getElementById('btnm');
var mobilemenu = document.getElementById('navigation-mobile');
// When the user clicks on the button, open the modal
menubtn.onclick = function() {
if (mobilemenu.style.display == 'block') {
mobilemenu.style.display = "none";
}
else {
mobilemenu.style.display = 'block';
}
}
}
.mobile-menu-btn {
float: right;
display: block;
padding: 3px 3px 0px 0px;
}
.humberger {
background-color: $identity-color;
font-size: 20px;
border: $identity-color;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
.menu-pargraph {
font-size: 14px;
vertical-align: middle;
padding-left: 5px;
margin: 0;
width: 100%;
}
<div class ="mobile-menu-btn">
<button class="humberger" id="btnm">
<i class="menu-btn fas fa-bars">
<span class="menu-pargraph">Menu</span>
</i>
</button>
</div>
<div id="navigation-mobile">
<ul>
<li>home</li>
<li>video</li>
<li>contact</li>
</ul>
</div>

Explanations in comments below. You had the id (and click listener) on the div, not the button and your 'Menu' text was probably looking funky b/c it was inside the icon element, inheriting the icon font family.
<div class ="mobile-menu-btn">
<button class="humberger" id="btnm"> <!-- put the id here -->
<i class="menu-btn fas fa-bars"></i>
<span class="menu-pargraph">Menu</span> <!-- move outside of the fontawesome icon -->
</button>
</div>
Also you can make your life easier with the show/hide using a class
css:
#navigation-mobile{
display:none;
/* and whatever other styles you have here */
}
.show {
display:block;
}
then in your script:
menubtn.onclick = function() {
mobilemenu.classList.toggle('show');
}

You missed a ")" in your JS code.
document.addEventListener('DOMContentLoaded', function(){
var menubtn = document.getElementById('btnm');
var mobilemenu = document.getElementById('navigation-mobile');
// When the user clicks on the button, open the modal
console.log("ok")
}
) // Here you have to add parenthesis

Related

How to hide navigation bar on link click?

I have 3 buttons and a responsive hamburger menu. Everything works as expected, but I can't think of a way to make a navigation bar go away as soon as I click on a button.
The program is supposed to work like this: clicking hamburger menu activates 3 buttons, whenever user clicks on any of those 3 buttons it hides the buttons and only leaves the button that was clicked.
This is the wanted outcome:
This is my code so far.
html:
<div class="selectSection">
<button type="button" data-number="1" class="active">1</button>
<button type="button" data-number="2">2</button>
<button type="button" data-number="3">3</button>
</div>
<div class="hamburger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div>
<div class="content" data-number="1">
<p>1st page</p>
</div>
<div class="content" data-number="2">
<p>2nd page</p>
</div>
<div class="content" data-number="3">
<p>3rd page</p>
</div>
</div>
css
.content:not(:first-child) {
display: none;
}
.active {
color: orange !important;
}
.hamburger {
display: none;
}
#media all and (max-width: 800px) {
.hamburger {
display: inline-block;
cursor: pointer;
z-index: 7;
}
.hamburger .line {
width: 30px;
height: 3px;
background: black;
margin: 6px 0px;
}
.selectSection {
display: none;
overflow: hidden;
}
.selectSection.active {
display: block;
}
}
js
// change active class, show the clicked element only and hide the others
// grab all the buttons
let Buttons = document.querySelectorAll(".selectSection button");
// loop through the buttons using for..of
for (let button of Buttons) {
// listen for a click event
button.addEventListener("click", (e) => {
// et = event target
const et = e.target;
// slect active class
const active = document.querySelector(".active");
// check for the button that has active class and remove it
if (active) {
active.classList.remove("active");
}
// add active class to the clicked element
et.classList.add("active");
// select all classes with the name content
let allContent = document.querySelectorAll(".content");
// loop through all content classes
for (let content of allContent) {
// display the content if the class has the same data-attribute as the button
if (
content.getAttribute("data-number") ===
button.getAttribute("data-number")
) {
content.style.display = "block";
}
// if it's not equal then hide it.
else {
content.style.display = "none";
}
}
});
}
hamburger = document.querySelector(".hamburger");
hamburger.onclick = function () {
navBar = document.querySelector(".selectSection");
navBar.classList.toggle("activate");
};
This is the demo:
https://codepen.io/f4kermak3r/pen/ExRPKzJ
you are using the wrong css class in your js file. At line 44, you must change navBar.classList.toggle("activate") to navBar.classList.toggle("active"). That should work.

How can I delete an element in Javascript

I am trying to implement this site to imitate a survey creation application. In this website you can add questions and then add some options to each question and edit the text in both Question Titles and Options.
But user should be able to remove an option as well. I have implemented the addition of the option but I don't know how to let the user delete a specific option. After this I can imagine it will be the same to do for deletion of questions.
I have done so each option has it's own remove option button but I just don't know how I should actually delete the current option.
If someone has done or knows how this problem should be approached I would appreciate the help.
This is my code:
const questionnaire = document.getElementById('questionaire');
newQuestion();
function newQuestion() {
questionnaire.insertAdjacentHTML('beforeend',
`<div class="question"> <div contenteditable="true">Your Question</div>
<ul> </ul>
<button class="addButton" type="button">Add Option</button>
</div>`);
newOption(questionnaire.querySelector("div.question:last-child ul"));
}
function newOption(q) {
q.insertAdjacentHTML('beforeend',
`<li class="optionName">
<span contenteditable="true">Option</span>
<input type="checkbox">
<button class="removeButton" type="button">Remove Option</button>
</li>`);
}
questionnaire.onclick = ev => {
if (ev.target.tagName === "BUTTON") {
if (ev.target.className === "addButton") {
newOption(ev.target.closest(".question").querySelector('ul'))
}
else if (ev.target.className === "removeButton") {
/* HERE I DON'T KNOW WHAT TO WRITE */
}
}
}
document.getElementById("addQuButton").onclick = newQuestion
body {
background-color: #00ffaa;
}
#myText {
margin-top: 15px;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
text-align: center;
}
.question {
border: 3px solid black;
border-radius: 25px;
margin: 30px 200px 20px 200px;
text-align: center;
}
.question ul li {
display: block;
}
<h1 id="myText" contenteditable="true">Survey Name</h1>
<button type="button" id="addQuButton">Add Question</button>
<form>
<div id="questionaire"></div>
</form>
To remove an option just add any element with a specific class like I am adding the span tag with the class name of remove-li in your option code.
and add the condition in the click event, which you've already set to the main container to check the event's clicked target, and only remove when the event's target has the given class which in our case is remove-li.
/* Getting the questionaire container*/
const questionnaire = document.getElementById('questionaire');
/*call the 'newQuestion' to add a question with options in container */
newQuestion();
/*define the 'newQuestion' method to insert the new question html in the container at the last position */
function newQuestion() {
questionnaire.insertAdjacentHTML('beforeend',
`<div class="question">
<div contenteditable="true">Your Question</div>
<ul></ul>
<button type="button">Add Option</button>
</div>`);
/*calling the 'newOption' method where adding the option into the last child of question's unorderd list */
newOption(questionnaire.querySelector("div.question:last-child ul"));
}
/*defining the newOption method where we insert the option html into provided selector as q */
function newOption(q) {
//Add the span with a class of 'remove-li'
q.insertAdjacentHTML('beforeend',
`<li class="optionName">
<span contenteditable="true">Option</span>
<input type="checkbox"><span class="remove-li">X<span>
</li>`);
}
//set the onclick listener on main container
questionnaire.onclick = ev => {
// check the target with tag is button to add the new option only when the click on button
if (ev.target.tagName === "BUTTON") {
newOption(ev.target.closest(".question").querySelector('ul'))
}else if(ev.target.className == 'remove-li'){ //Check the clicked target is remove button for the option to remove it
ev.target.parentNode.remove();
}
}
//set the onclick event on add question button
document.getElementById("addQuButton").onclick = newQuestion
body {
background-color: #00ffaa;
}
#myText {
margin-top: 15px;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
text-align: center;
}
.question {
border: 3px solid black;
border-radius: 25px;
margin: 30px 200px 20px 200px;
text-align: center;
}
.question ul li {
display: block;
}
/*Add some style for the remove button*/
.remove-li{
padding: 5px;
background-color:red;
color:white;
cursor: default;
}
<h1 id="myText" contenteditable="true">Survey Name</h1>
<button type="button" id="addQuButton">Add Question</button>
<form>
<div id="questionaire"></div>
</form>
Please check the added code.
May it helps to learn :)

Tab content not showing properly with CSS Grid areas and JS

I want to set up a JS based tab navigation but somehow the Tab content doesnt show properly.
The JS code seems off but I cannot find the error.
I just want the Tab Content to show that belongs to one tab.
The Code looks like this:
function openPage(e, pageName) {
// Declare all variables
let i, content, tabLinks;
// Get all elements with class="tabs_content" and hide them
content = document.getElementsByClassName("tabs_content");
for (i = 0; i < content.length; i++) {
content[i].style.display = "none";
}
// Get all elements with class="tabs_button" and remove the class "active"
tabLinks = document.getElementsByClassName("tabs_button");
for (i = 0; i < tabLinks.length; i++) {
tabLinks[i].className = tabLinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(pageName).style.display = "block";
e.currentTarget.className += " active";
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
.wrapper{
display: grid;
grid-template-columns: 150px 1fr;
border:1px solid #cccccc;
padding: 15px;
margin: 0 auto;
grid-template-areas:
'nav main '
'nav main'
}
.tabs_sidebar {
grid-area: nav;
display: flex;
flex-direction: column;
background: #cccccc;
}
section {
display: flex;
flex-direction: row;
flex-shrink: 0;
min-height: 400px;
}
.tabs_content {
grid-area: main;
background: #f6e3e3;
padding-left: 15px;
font-size: 1rem;
}
.tabs_button {
display: block;
padding: 10px;
background: #eeeeee;
border: none;
width: 100%;
outline: none;
cursor: pointer;
font-size: 1rem;
}
.tabs_button:active {
background: #dddddd;
}
.tabs_button:not(:last-of-type){
border-bottom: 1px solid #cccccc;
}
<div class="wrapper">
<nav class="tabs_sidebar">
<button class="tabs_button" onclick="openPage(e, 'Home')" id="defaultOpen">Home</button>
<button class="tabs_button" onclick="openPage(e, 'News')">News</button>
<button class="tabs_button" onclick="openPage(e, 'Contact')">Contact</button>
</nav>
<section class="tabs_content tabs_content--active">
<div id="Home" class="tabs_content">
<h2>Tab #1</h2>
<p>Content Page 1 </p>
</div>
<div class="tabs_content">
<h2>Tab #2</h2>
<p>Content Page 2 </p>
</div>
<div class="tabs_content">
<h2>Tab #3</h2>
<p>Content Page 3</p>
</div>
</section>
</div>
I cannot find the error, but the problem seems to be the <section>. Any help is much appreciated.
Your code has more than one problem.
The one you're currently stuck on is that e is not defined in this template bit:
<button class="tabs_button" onclick="openPage(e, 'Home')" id="defaultOpen">Home</button>
The default name of the event when you want to pass it to the function is event, not e (and you can't change it, it's a convention - you can only change its name in the function). In other words, even if in the function it's named e, you still have to reference it as event in the template.
Here are the rest of the problems, in the order I encountered them as I worked my way into making it work:
the .tabs_button:active selector is wrong. You probably want to use .tabs_button.active (since you're applying the class active to it).
you have tabs_content class on the tabs wrapper, so the entire wrapper is hidden, when you probably only want to set display:none onto its children.
you're missing the ids on second and third tab
you need width: 100% on .tabs_content
See it here:
function openPage(e, pageName) {
let i, content, tabLinks;
content = document.getElementsByClassName("tabs_content");
for (i = 0; i < content.length; i++) {
content[i].style.display = "none";
}
tabLinks = document.getElementsByClassName("tabs_button");
for (i = 0; i < tabLinks.length; i++) {
tabLinks[i].className = tabLinks[i].className.replace(" active", "");
}
document.getElementById(pageName).style.display = "block";
e.currentTarget.className += " active";
}
document.getElementById("defaultOpen").click();
.wrapper {
display: grid;
grid-template-columns: 150px 1fr;
border: 1px solid #cccccc;
padding: 15px;
margin: 0 auto;
grid-template-areas: 'nav main ' 'nav main'
}
.tabs_sidebar {
grid-area: nav;
display: flex;
flex-direction: column;
background: #cccccc;
}
section {
display: flex;
flex-direction: row;
flex-shrink: 0;
min-height: 400px;
}
.tabs_content {
grid-area: main;
background: #f6e3e3;
padding-left: 15px;
font-size: 1rem;
width: 100%;
}
.tabs_button {
display: block;
padding: 10px;
background: #eeeeee;
border: none;
width: 100%;
outline: none;
cursor: pointer;
font-size: 1rem;
}
.tabs_button.active {
background: #dddddd;
}
.tabs_button:not(:last-of-type) {
border-bottom: 1px solid #cccccc;
}
body {
margin: 0;
}
<div class="wrapper">
<nav class="tabs_sidebar">
<button class="tabs_button" onclick="openPage(event, 'Home')" id="defaultOpen">Home</button>
<button class="tabs_button" onclick="openPage(event, 'News')">News</button>
<button class="tabs_button" onclick="openPage(event, 'Contact')">Contact</button>
</nav>
<section class="tabs_content--active">
<div id="Home" class="tabs_content">
<h2>Tab #1</h2>
<p>Home</p>
</div>
<div id="News" class="tabs_content">
<h2>Tab #2</h2>
<p>News</p>
</div>
<div id="Contact" class="tabs_content">
<h2>Tab #3</h2>
<p>Contact</p>
</div>
</section>
</div>
Apart from that, in my estimation, you're doing too much by JavaScript. Instead of applying inline styles, you should only apply and remove classes which, in turn, apply styles. You end up writing less code and it's easier to manage & debug.
Another thing I would personally change is replace className usage with classList, which has a more powerful and more expressive syntax.
This doesn't mean it's not doable the way you set out to do it.
The main problem when mixing stylesheet CSS with inline styles is that inline styles can only be overwritten with !important, which leads to a whole new level of problems. By only applying classes you keep the specificity battle inside your stylesheet, which is where it should take place.
Here's how I'd write it:
function openPage(e) {
const target = e.target.dataset['target'];
if (target) {
[...document.querySelectorAll('.tabs_sidebar > button')].forEach(el => {
el.classList[el.dataset['target'] === target ? 'add' : 'remove']('active');
document.getElementById(el.dataset['target'])
.classList[el.dataset['target'] === target ? 'add' : 'remove']('active');
})
}
}
document.querySelector('.tabs_sidebar').addEventListener('click', openPage);
.wrapper {
min-height: 100vh;
display: grid;
grid-template-columns: 150px 1fr;
border: 1px solid #cccccc;
padding: 15px;
grid-template-areas: 'nav main'
}
.tabs_sidebar {
grid-area: nav;
display: flex;
flex-direction: column;
background: #cccccc;
}
section {
display: flex;
flex-direction: row;
}
.tabs_content--active > div {
width: 100%;
grid-area: main;
background: #f6e3e3;
padding-left: 15px;
font-size: 1rem;
display: none;
}
.tabs_content--active > div.active {
display: block;
}
.tabs_sidebar > button {
display: block;
padding: 10px;
background: #eeeeee;
border: none;
width: 100%;
outline: none;
cursor: pointer;
font-size: 1rem;
}
.tabs_sidebar > button.active {
background: #dddddd;
}
.tabs_sidebar > button:not(:last-of-type) {
border-bottom: 1px solid #cccccc;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<div class="wrapper">
<nav class="tabs_sidebar">
<button data-target="Home" class="active">Home</button>
<button data-target="News">News</button>
<button data-target="Contact">Contact</button>
</nav>
<section class="tabs_content--active">
<div id="Home" class="active">
<h2>Tab #1</h2>
<p>Home</p>
</div>
<div id="News">
<h2>Tab #2</h2>
<p>News</p>
</div>
<div id="Contact">
<h2>Tab #3</h2>
<p>Contact</p>
</div>
</section>
</div>
Note I've also made changes to markup (HTML) and CSS, not just JavaScript.
As requested in comments, here's an explanation on what the JavaScript code does:
Instead of placing a click handler on each individual button, I've placed one on their parent. It has the advantage of working on future buttons as well, should your page be dynamic. If you bind on each button, once the buttons change you have to figure out which ones are new and only bind the handler on those (you don't want to bind the handler twice on the same element).
When a click is performed inside that button container, you first have to determine which button was clicked (or if the click was outside of any existing buttons). See how data attributes work here. If the click was performed on a button (if (target)), instead of having two loops (one through the buttons and one through the tabs), I only used one loop (through the buttons).
Instead of doing a classic for loop I chose to cast the NodeList returned by querySelectorAll to an array which I can then iterate using .forEach().
Note: To be totally fair, I suspect the for loop (what you used) is more performant but the difference is quite small and I tend to go for the shorter syntax:
[...document.querySelectorAll('.tabs_sidebar > button')].forEach(el => {
// do stuff with each looped element. In this case, a button
})
Now that we have the element, let's do something with it: Add or remove the class active based on whether or not the current button's target matches the one that was clicked (which we already have saved in target const).
I personally prefer classList to className. It works on the classes array, rather than on the resulting classes string. Has add, remove and replace methods and you don't end up having to worry about adding spaces manually (or trimming them). I'm using
el.classList[el.dataset['target'] === target ? 'add' : 'remove']('active');
instead of
if (el.dataset['target'] === target) {
el.classList.add('active');
} else {
el.classList.remove('active');
}
I used the array notation to call add and remove methods on classList. (i.e: in Javascript you can write foo.bar(arg) as foo['bar'](arg) - all methods are still object properties). The advantage is that inside the array notation you can switch the method being called, based on a ternary condition, which is exactly what I'm doing above.
Using the same technique, I'm also adding/removing the active class from the corresponding tab, which I'm selecting by id.
document.getElementById(el.dataset['target'])
.classList[el.dataset['target'] === target ? 'add' : 'remove']('active');
The only thing that could slightly be improved about my code is saving the result of the ternary condition instead of doing it twice. Like this:
if (target) {
[...document.querySelectorAll('.tabs_sidebar > button')].forEach(el => {
const isActive = el.dataset['target'] === target;
el.classList[isActive ? 'add' : 'remove']('active');
document.getElementById(el.dataset['target'])
.classList[isActive ? 'add' : 'remove']('active');
})
}
Hope that makes sense.

javascript - remove element from div when button inside is pressed

I have a div that looks like this:
<div id="contact-segments">
<div class="contact-segment-item doesnt-include">
<div class="segment-content pull-left" style="width: 80%">
<p>LOL</p>
</div>
<div class="pull-right">
<a href="your link here">
<i class="white-segment-icon fa fa-times"></i>
</a>
</div>
</div>
</div>
Whenever someone presses an add button, I add another contact-segment-item div to the contact-segments div through JavaScript with this function:
function createUserSegment(tags) {
var div = document.createElement("div");
div.className = 'contact-segment-item includes'
div.innerHTML = "<div class='segment-content pull-left' style='width: 80%''> <p>" + tags + "</p> </div> <div class='pull-right'> <a href='your link here'> <i class='white-segment-icon fa fa-times'></i></a> </div>";
document.getElementById("contact-segments").appendChild(div);
}
As you can see, the divs that are getting added through JavaScript have an a tag that shows a button with an "x".
How can I remove the contact-segment-item when the "x" is pressed inside of it?
Here's how each of them look so it's easier to picture.
I can link the "x" button click to javascript but how do I know which child of contact-segments to delete and also how do I get the p of it before it's deleted.
When the user presses the "x" on this div, I want to get the p or in this case Woop! so I can do something with it but then also delete that contact-segment-item
Thanks
Instead of using .innerHTML we nest nodes with appendChild. Finally for our close i button we add onClick event handler. We pass there our div node, and use remove() method to remove the node.
EDIT:
Added css.
Do not use a if your anchors only needs to delete your segments. For example use only i without wrapping a and add a cursor: pointer style to it.
See working example:
function createUserSegment(tags){
var div = document.createElement("div");
div.className = 'contact-segment-item includes';
var tagInfo = document.createElement("div");
tagInfo.className = 'contact-segment-item__text';
tagInfo.innerHTML = tags;
var closeButton = document.createElement("i");
closeButton.className = 'contact-segment-item__closeButton white-segment-icon fa fa-times';
closeButton.onclick = function() {
div.remove();
};
div.appendChild(tagInfo);
div.appendChild(closeButton);
document.getElementById("contact-segments").appendChild(div);
}
#contact-segments {
max-width:350px;
width: 100%;
}
.contact-segment-item {
display: block;
position: relative;
width: 100%;
background: #00B792;
border-radius: 8px;
line-height: 40px;
clear: both;
padding: 20px 30px;
margin-bottom: 10px;
}
.contact-segment-item__anchor::after {
clear: both;
}
.contact-segment-item__text {
display: inline-block;
color: #fff;
}
.contact-segment-item__closeButton {
display: inline-block;
cursor: pointer;
color: #fff;
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<button id="add-new" onClick="createUserSegment('new one')">Add new segment</button>
<br/>
<div id="contact-segments">
</div>

JavaScript: any tips on improving this code on opening/closing menu?

I've been lurking w3schools for some time and studying javaScript. I've struggled for a few days with a code of which the function is to open and then close the opened menu on click again. I couldn't do this with a single , but I've managed to it with two.
I've managed to do this with the following method:
<div id="menuClosed" style="background: blue; color: white; width: 500px; height: 50px; transition: 0.3s">
<p id="menuString" style="margin: auto; text-align:center;">
Click on the button to open the menu
</p>
<button id="menuButton" onclick="changeStyle('Closed')" style="margin-left:250px;">Open</button>
<div>
<p style="font-size: 30px; text-align:center;">Bonefish</p>
</div>
<button id="menuButton2" onclick="changeStyle('Open')" style = "margin-left:250px; display: none;">Close</button>
</div>
<script>
function changeStyle(idMenu) {
//compresses OPEN and CLOSE buttons ID into a var
var menuButton = document.getElementById("menuButton");
var menuBotton2 = document.getElementById("menuButton2");
//Compresses menu DIV's ID into a var
var menuConfig = document.getElementById("menu" + idMenu);
//styles that will serve as factor for opening/closing the menu
var style1 = "background: blue; color: white; width: 500px; height: 50px; transition: 0.3s";
var style2 = "background: blue; color: white; width: 500px; height: 150px; transition: 0.3s";
//opens Menu and changes ID to "menuOpen"
if (idMenu === "Closed") {
menuConfig.style = style2;
menuConfig.id = "menuOpen";
menuButton.style = "display: none; margin-left:250px;";
menuButton2.style = "margin-left:250px; display: initial;"
}
//Closes menu and chages ID to "menuClosed"
if (idMenu === "Open") {
menuConfig.style = style1;
menuConfig.id = "menuClosed";
menuButton.style = "display: initial; margin-left:250px;";
menuButton2.style = "margin-left:250px; display: none;";
}
}
</script>
What I actually wanted to do, is to be able to both open and close the menu with the same button, but I can't figure out how.
I believe it can be done through changing <button id="menuButton" onclick="changeStyle('Closed')" style="margin-left:250px;">Open</button> changeStyle('Closed') into changeStyle('Open') and making necessary adjustments, but, again, my tries on that have failed.
Thanks by advance.
If you could use jQuery and some css, it you'll get what you want
UPDATED WITH JAVASCRIPT
var divmenu=document.getElementById('menu');
function toggleMenu(btn){
if(btn.className=='open'){
btn.className='close';
divmenu.className='close';
btn.innerText='Open';
}else{
btn.className='open';
divmenu.className='open';
btn.innerText='Close';
}
}
div{
padding:10px 0;
color: white;
transition: 0.3s;
background: blue;
}
div.open{
height: 150px;
}
div.close{
height: 20px;
overflow:hidden;
}
<div id="menu" class="close">
<p id="menuString" style="margin: auto; text-align:center;">
Click on the button to open the menu
</p>
<p style="font-size: 30px; text-align:center;">Bonefish</p>
</div>
<p style="text-align:center; margin:0; padding:5px 0;"><button type="button" class="close" onclick="toggleMenu(this);">Open</button></p>

Categories