Reputation: 99
I've managed to code a dropdown button to display texted when clicked then disappear if clicked anywhere else on the page. But I'm have one issue with it, for some reason the button won't work unless you click on the outer edge of the button not in the centre. (E.g if you click in the middle of the button, nothing happens but if you click near the edge of the button, the dropdown displays.)
Does anyone know why this happens and how do I fix it so that no matter where you click on the button the dropdown displays.
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
cursor: pointer;
background-color: #fafafa;
border: none;
text-align: left;
margin-bottom: 5px;
padding-left: 0px;
}
.dropdown {
position: absolute;
display: inline-block;
text-align: left;
}
.dropdown-content {
display: none;
position: relative;
overflow: auto;
margin-top: 10px;
margin-bottom: 10px;
z-index: 1;
background-color: #eeeeee;
padding: 10px;
}
.show {
display: block;
}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn"><p>Dropdown Button</p></button>
<div id="myDropdown" class="dropdown-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.
</div>
</div>
Upvotes: 2
Views: 605
Reputation: 68923
Since the text inside the button is inside another p element, you can add another condition to check the p element:
!(event.target.nodeName == 'P')
Demo:
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn') && !(event.target.nodeName == 'P')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
cursor: pointer;
background-color: #fafafa;
border: none;
text-align: left;
margin-bottom: 5px;
padding-left: 0px;
}
.dropdown {
position: absolute;
display: inline-block;
text-align: left;
}
.dropdown-content {
display: none;
position: relative;
overflow: auto;
margin-top: 10px;
margin-bottom: 10px;
z-index: 1;
background-color: #eeeeee;
padding: 10px;
}
.show {
display: block;
}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn"><p>Dropdown Button</p></button>
<div id="myDropdown" class="dropdown-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.
</div>
</div>
Upvotes: 2
Reputation: 50326
That is because the event is originating from the p
tag. Remove that one and add padding to dropbtn
for similar style
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
cursor: pointer;
background-color: #fafafa;
border: none;
text-align: left;
padding: 10px;
}
.dropdown {
position: absolute;
display: inline-block;
text-align: left;
}
.dropdown-content {
display: none;
position: relative;
overflow: auto;
margin-top: 10px;
margin-bottom: 10px;
z-index: 1;
background-color: #eeeeee;
padding: 10px;
}
.show {
display: block;
}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">
Dropdown Button</button>
<div id="myDropdown" class="dropdown-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.
</div>
</div>
Upvotes: 2