Making a dropdown menu using vanilla Javascript - javascript

I'm trying to figure out what is a good approach to accomplish a dropdown menu that opens when a user clicks on a div which functions as a button and hides when the user click again on it. The style in my CSS sheet is set as display: none. and this is as far as i've gone:
var xx = document.getElementById('dropdown-Container');
if (xx.display.style = 'none') {
xx.addEventListener('click', function showMenu() {
document.getElementById('dropdown-Container').style.display = 'block';
} else {
xx.style.display = 'none';
}, false);
}
<div type="button" id="dropdown-Container">
<a class="dropdown1" href="#">Link 1</a>
<a class="dropdown1" href="#">Link 2</a>
<a class="dropdown1" href="#">Link 3</a>
</div>
Search
</div>
The menu is hiding properly but when the user clicks on it, it's not opening up as I wish.

You need a double-equals in the 'none' comparison, at the very least.

You have made a mistake in the code by placing the if statement above the event listener. Use it like this.
var menu = document.getElementById('yourDropdownMenuIdHere');
var dropdown = document.getElementById('dropdown-Container');
menu.addEventListener('click', function showMenu(){
if( dropdown.style.display = 'none' ) {
dropdown.style.display = 'block';
} else {
dropdown.style.display = 'none';
}
});
Accessibility Issue: A div is not supposed to be used as a button for handling click. You can use a button tag instead

Related

How to fix "Opened sidebar when page is loaded"?

I am making a sidebar nav. There is a hamburger button when clicked opens nav. But when page is loaded, it is already opened. I don't want it to already opened. How do I fix this?
I am a noob in JS. I have tried value 'javascript:void(0)' in href attribute, but it didn't work.
<a href="javascript:void(0)" class="click-menu" onclick="openMenu()">&9776;
</a>
<div class="side-menu" id="side-menu">
<a href="#" class="cross-btn" onclick="closeMenu()" style="font-size: 50px">×
</a>
Features
Pricing
Login
</div>
<script>
function openMenu() {
document.getElementById("side-menu").style.width = "250px";
}
function closeMenu() {
document.getElementById("side-menu").style.width = "0";
}
</script>
Expected result: Sidebar nav will open only when Hamburger icon is clicked.
Actual result: When page is loaded, nav is already opened.
Add display:none to the style of div #side-menu:
<div class="side-menu" id="side-menu" style="display:none;">
And instead of resizing the width of #side-menu, change the display to block when the menu is clicked, and back to none when the cross sign is clicked.
function openMenu() {
document.getElementById("side-menu").style.display = "block";
}
function closeMenu() {
document.getElementById("side-menu").style.display = "none";
}
The full code:
☰
<div class="side-menu" id="side-menu" style="display:none;">
×
Features
Pricing
Login
</div>
<script>
function openMenu() {
document.getElementById("side-menu").style.display = "block";
}
function closeMenu() {
document.getElementById("side-menu").style.display = "none";
}
</script>
P.S. Also change &9776; to ☰

Close bootstrap dropdown only when mouse is clicked outside of dropdown

I have a bootstrap dropdown menu:
<div class="dropdown>
<a class="dropdown-toggle" href="#" id="menu1" data-toggle="dropdown"><img src="#imagePath" class="img-circle dropbtn" alt="Product" style="width:30px;height:30px;" /></a>
<ul class="dropdown-menu" id="productDD" role="menu" aria-labelledby="menu1"></ul>
</div>
Now the ul load the products on page load through ajax call. The issue is when I click any product in the dropdown, the dropdown gets closed. But I want to close dropdown only when mouse is clicked anywhere outside of the ul
Try something like this:
$(document).click(function(e) {
// get the clicked element
$clicked = $(e.currentTarget);
// if the clicked element is not a descendent of the dropdown
if ($clicked.closest('.dropdown').length === 0) {
// close the dropdown
$('.dropdown').removeClass('open');
}
});
In 2021 you do it this way:
$('.dropdown').on({
"shown.bs.dropdown": function() { /* whatever you want to do when it fires */ },
"click": function(e) { // handles click event
console.log(e.target) // just to check which element is on top
if($('.dropdown-menu').is(e.target)) { // if dropdown is clicked
this.closable = false // do not close it
return;
} else {
this.closable=true; // else close it
}
},
"hide.bs.dropdown": function() { return this.closable; } // save state
});
}
Bootstrap has a built-in solution
<a class="dropdown-toggle" href="#" id="menu1" data-toggle="dropdown" data-bs-auto-close="outside"><img ... /></a>
just place this script in your code
<script>
$(document).click(function() {
$(".dropdown").removeClass('open');
});
</script>

Open one drop-down, close another with JavaScript

I am using this script to open a drop down menu and then close it when anything else but the trigger is clicked. Now I am trying to add a second drop down to another area on the page and repeat the script but it is breaking.
For instance, I click button A (Gravatar), and drop down A opens.
However when I add the second script and click button B (category) to open drop down B, down down A stays open.
Also adding the second script breaks the drop down close function of the first script.
Here is the script:
<script>
function openAccount(event) {
event.stopPropagation();
document.getElementById("gravatar").classList.toggle("open");
}
window.onclick = function(event) {
document.getElementById("gravatar").classList.remove("open");
}
</script>
<script>
function openCategory(event) {
event.stopPropagation();
document.getElementById("category").classList.toggle("open");
}
window.onclick = function(event) {
document.getElementById("gravatar").classList.remove("open");
}
</script>
<li class="gravatar">
<a href="#" class="dropbtn" onclick="openAccount(event)">
<img src="<?php echo $gravatar; ?>" alt="" />
<span class="fa fa-icon fa-caret-down"></span>
</a>
<ul class="dropdown" id="gravatar">
<li class="header">
<?php echo $user['email']; ?>
</li>
</ul>
</li>
<div class="category">
Properties<span class="fa fa-icon fa-caret-down"></span>
<div id="category">Test</div>
</div>
Goals:
Multiple drop down menus on different parts of the page.
On click opens drop down.
Click on anywhere else on the page closes the drop down.
On click also closes any previously opened menu.
I'd do something really simple like putting a data* attribute on the element that's clicked on that contains the ID of the element to show or hide, e.g.
// Toggle hidden class on/off
function toggleVis(event) {
// Stop click on element bubbling (to body)
event.stopPropagation();
// Get target element
var el = document.getElementById(this.dataset.id);
// If non-target elements are visible, hide them
hideAll(el);
// Toggle target
el.classList.toggle('hidden');
}
// Hide all, excluding passed element
function hideAll(el) {
Array.from(document.querySelectorAll('ul:not(.hidden)')).forEach(function(node){
if (el != node) node.classList.add('hidden');
});
}
// Attach listeners
window.onload = function() {
// Add to linkLike spans
Array.from(document.querySelectorAll('.linkLike')).forEach(function(node) {
node.addEventListener('click', toggleVis, false);
});
// Add hideAll listener to wndow
window.addEventListener('click', hideAll, false);
// Run hideAll
hideAll();
}
/* style span like link */
.linkLike {
text-decoration: underline;
cursor: pointer;
}
/* class to hide element */
.hidden {
visibility: hidden;
}
<ul id="a"><li>A</ul>
<ul id="b"><li>B</ul>
<ul id="c"><li>C</ul>
<ul id="d"><li>D</ul>
<div><span class="linkLike" data-id="a">Toggle A</span></div>
<div><span class="linkLike" data-id="b">Toggle B</span></div>
<div><span class="linkLike" data-id="c">Toggle C</span></div>
<div><span class="linkLike" data-id="d">Toggle D</span></div>
Of course there are other ways to do the association, but ID is simple, explicit and doesn't depend on document layout or formatting.

Javascript if/else not working as expected

I am trying to toggle a hidden menu with a link. But when i click on the link, it reopens the hidden menu instead of closing it.
Here is how i expect it to run:
When i click labelLink
if hiddenBox 's display = 'none', then change it to display = 'block'
if hiddenBox 's display = 'block', then delete its focus by blur() and set it display='none'
When i click outside of the hiddenBox when it has the focus, set hiddenBox 's display='none'
(This part is working well.)
JsFiddle
<ul>
<li>
<a id="labelLink" href="#"
onclick="
if(document.getElementById('hiddenBox').style.display === 'block'){
document.getElementById('labelLink').focus();
document.getElementById('hiddenBox').style.display ='none';
}
else{
document.getElementById('hiddenBox').style.display = 'block';
document.getElementById('hiddenBox').focus();
}
return false;"
>
Click Me
</a>
<div id="hiddenBox" tabindex="-1"
onblur="document.getElementById('hiddenBox').style.display ='none';"
>
I was hidden
</div>
</li>
</ul>
Do it this way instead.
var labelLink = document.getElementById('labelLink');
var hiddenBox = document.getElementById('hiddenBox');
labelLink.addEventListener('click', function() {
hiddenBox.style.display = hiddenBox.style.display == 'block' ? 'none': 'block';
});
labelLink.addEventListener('blur', function() {
hiddenBox.style.display = 'none';
})
#hiddenBox {
display: none
}
<ul>
<li><a id="labelLink" href="#">Click Me</a>
<div id="hiddenBox" tabindex="-1">I was hidden</div>
</li>
</ul>
As already pointed out, the two event listeners are interfering with each other. One way of fixing this is to remove the listener on labelLink when the hidden box is shown, and restore the listener with a slight pause after the hidden box is hidden again. JSFiddle
var labelLink = document.getElementById('labelLink'),
hiddenBox = document.getElementById('hiddenBox');
labelLink.addEventListener('click', showBox);
hiddenBox.addEventListener('blur', hideBox);
function showBox(){
hiddenBox.style.display = 'block';
hiddenBox.focus();
labelLink.removeEventListener('click', showBox);
}
function hideBox() {
hiddenBox.style.display = 'none';
labelLink.focus();
window.setTimeout(function() {
labelLink.addEventListener('click', showBox);
}, 500);
}
<a id="labelLink" href="#" >Click Me</a>
<div id="hiddenBox" tabindex="-1" style="display:none" >I was hidden</div>

Linking to a section of a site that is hidden by a hide/show JavaScript function

I am using a bit of JavaScript to show/hide sections of a site when a tab is clicked. I'm trying to figure out if there is a way I can link back to the page and have a certain tab open based on that link.
Here is the JS:
var ids=new Array('section1','section2','section3','section4');
function switchid(id, el){
hideallids();
showdiv(id);
var li = el.parentNode.parentNode.childNodes[0];
while (li) {
if (!li.tagName || li.tagName.toLowerCase() != "li")
li = li.nextSibling; // skip the text node
if (li) {
li.className = "";
li = li.nextSibling;
}
}
el.parentNode.className = "active";
}
function hideallids(){
//loop through the array and hide each element by id
for (var i=0;i<ids.length;i++){
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
//safe function to show an element with a specified id
document.getElementById(id).style.display = 'block';
}
And the HTML
<ul>
<li class="active"><a onclick="switchid('section1', this);return false;">One</a></li>
<li><a onclick="switchid('section2', this);return false;">Two</a></li>
<li><a onclick="switchid('section3', this);return false;">Three</a></li>
<li><a onclick="switchid('section4', this);return false;">Four</a></li>
</ul>
<div id="section1" style="display:block;">
<div id="section2" style="display:none;">
<div id="section3" style="display:none;">
<div id="section4" style="display:none;">
I haven't been able to come up with a way to link back to a specific section. Is it even possible with this method?
Thanks!
You could run some script when your page loads that checks the url hash & loads the appropriate section:
// on page load
var sectionid = /section\d/i.exec(location.hash);
if (sectionid) {
var link = document.getElementById(switchid[0] +"_link");
switchid(sectionid[0], link);
}
& add an id to your links:
<li><a id="section2_link" onclick="switchid('section2', this);return false;">Two</a></li>
HTML functionality is entirely independent of CSS. Therefore the following code will always work even if the intended section is set to display:none.
Link to section3

Categories

Resources