Reputation: 75
i have a new problem with a menu that i am making. I am trying to make it hide when the user clicks outside of the menu itself. I can't check the display value of the element, as it is always visible but translated to the right of the element, thus not being in the visible DOM.
The problem is that the button in itself is not working and that the menu is activating when clicking on the screen, so my attempt at making a verification whether the div is visible or not isn't working.I have also tried to use a function with getBoundingClientRect();
that a lot of people are suggesting, but i stuck around with document.body.contains(MyElement)
.
This is my JavaScript:
function myFunction(x) {
x.classList.toggle("change");
document.getElementById("dropdown-meniu-content").classList.toggle("show");}
$(document).click(function(event) {
if ( document.body.contains(document.getElementById('dropdown-meniu-content') ) ) {
if(!$(event.target).closest('#dropdown-meniu-content').length) {
document.getElementById("dropdown-meniu-content").classList.toggle("show");
document.getElementById("buton-meniu").classList.toggle("change");
}
}
}); The CSS is :
.logo {
float: left;
margin-top: 10px;
margin-left: 5px;
width: 200px;
height: 100px;
}
.meniu {
float: right;
width: auto;
}
.buton-meniu {
display: block;
cursor: pointer;
width: 35px;
margin-right: 30px;
margin-top: 40px;
}
.bar1, .bar2, .bar3 {
width: 35px;
height: 5px;
background-color: black;
margin: 6px 0;
transition: 0.4s;
}
.change .bar1 {
-webkit-transform: rotate(-45deg) translate(-9px, 6px);
transform: rotate(-45deg) translate(-9px, 6px);
}
.change .bar2 {
opacity: 0;
}
.change .bar3 {
-webkit-transform: rotate(45deg) translate(-8px, -8px);
transform: rotate(45deg) translate(-8px, -8px);
}
.dropdown-meniu {
position: relative;
display: inline-block;
}
.dropdown-meniu-content {
top: 110px;
position: fixed;
background-color: #d6d6d6;
width: 30%;
max-width: 10000px;
height: 100%;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
overflow: hidden;
right: 0;
transform: translateX(100%);
transition: transform 0.5s ease;
}
.show {
transform: translateX(0%);
}
And the HTML:
<div class="meniu">
<div class="dropdown-meniu">
<div id="buton-meniu" class="buton-meniu" onclick="myFunction(this)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<div id="dropdown-meniu-content" class="dropdown-meniu-content">
<div class="dropdown-ferestre">
<div id="buton-ferestre" class="buton-ferestre">Ferestre</div>
<div id="dropdown-ferestre-content" class="dropdown-ferestre-content">
<p id="demo"></p>
</div>
</div>
</div>
</div>
</div>
If you don't want to look through the code, the JSFiddle is here: https://jsfiddle.net/1qrtb424/18/
Thanks for helping!
Upvotes: 0
Views: 681
Reputation: 329
Checking to see if an element is visible on the screen is a hard problem to solve, but I don't think you need to solve it to accomplish your task. There may be some reason you need to do it that way, but, if there isn't, rather than checking whether an element is visible on the screen, you could just check for the presence of the class that makes that element visible.
I meant to rework your javascript less, but it took me a bit to remember the solution to the propagation issue (clicking a button also, by default, counts as a click on the document, unless you add event.stopPropagation
), and it was easier for me to rewrite. The same principles could be applied in your solution, though.
That's a very nice burger-bar/x button transition, by the way.
var button = document.querySelector('#buton-meniu');
var content = document.querySelector('#dropdown-meniu-content');
button.addEventListener('click', function(e) {
e.stopPropagation();
e.currentTarget.classList.toggle('change');
content.classList.toggle('show');
}, true)
document.addEventListener('click', function() {
if (content.classList.contains('show')) {
content.classList.remove('show');
button.classList.remove('change');
}
})
content.addEventListener('click', function(e) {
e.stopPropagation();
})
.logo {
float: left;
margin-top: 10px;
margin-left: 5px;
width: 200px;
height: 100px;
}
.meniu {
float: right;
width: auto;
}
.buton-meniu {
display: block;
cursor: pointer;
width: 35px;
margin-right: 30px;
margin-top: 40px;
}
.bar1, .bar2, .bar3 {
width: 35px;
height: 5px;
background-color: black;
margin: 6px 0;
transition: 0.4s;
}
.change .bar1 {
-webkit-transform: rotate(-45deg) translate(-9px, 6px);
transform: rotate(-45deg) translate(-9px, 6px);
}
.change .bar2 {
opacity: 0;
}
.change .bar3 {
-webkit-transform: rotate(45deg) translate(-8px, -8px);
transform: rotate(45deg) translate(-8px, -8px);
}
.dropdown-meniu {
position: relative;
display: inline-block;
}
.dropdown-meniu-content {
top: 110px;
position: fixed;
background-color: #d6d6d6;
width: 30%;
max-width: 10000px;
height: 100%;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
overflow: hidden;
right: 0;
transform: translateX(100%);
transition: transform 0.5s ease;
}
.show {
transform: translateX(0%);
}
<div class="meniu">
<div class="dropdown-meniu">
<div id="buton-meniu" class="buton-meniu" >
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<div id="dropdown-meniu-content" class="dropdown-meniu-content">
<div class="dropdown-ferestre">
<div id="buton-ferestre" class="buton-ferestre">Ferestre</div>
<div id="dropdown-ferestre-content" class="dropdown-ferestre-content">
<p id="demo"></p>
</div>
</div>
</div>
</div>
</div>
Upvotes: 1