I got this dropdown menu which works, but I would also like it to close when I click outside it… I've tried some answered solutions but something's wrong and I can't figure it out..Could someone point what am I missing out here? Thanks a lot
$("#toggle").on('click', function() {
$(".dropdown").toggleClass("dropdown--visible");
});
$(document).click(function(){
$(".dropdown").hide();
});
$(".dropdown").click(function(e){
e.stopPropagation();
});
.dropdown {
background: red;
display: none;
}
.dropdown--visible {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="toggle">Toggle dropdown</button>
<div class="dropdown">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
$("#toggle").on('blur click', function() {
$(".dropdown").toggleClass("dropdown--visible");
});
$(document).click(function(){
});
.dropdown {
background: red;
display: none;
}
.dropdown--visible {
display: block!important;
}
.dropdown--invisible {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="toggle">Toggle dropdown</button>
<div class="dropdown">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
You have setup a click event listener for document and it will execute all the time when you click anywhere.
You can use a common class to filter out the dropdown events.
<button id="toggle" class="dd">Toggle dropdown</button>
<div class="dropdown dd">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
$(document).click(function(e){
if (!$(e.target).hasClass('dd')) {
$(".dropdown").removeClass("dropdown--visible");
}
});
Also better use removeClass() without using hide() since hide() adds a display:none; directly to the element and will be hard to control.
This vanilla-flavored solution uses a handleDropdown function that checks two conditions:
- Was the toggle button clicked?
- Is the dropdown currently hidden?
If both are true, it shows the dropdown. Otherwise, it hides the dropdown.
const dropdown = document.getElementsByClassName("dropdown")[0],
toggle = document.getElementById("toggle");
document.addEventListener("click", handleDropdown);
function handleDropdown(event){
if(event.target == toggle && dropdown.style.display != "block"){
dropdown.style.display = "block";
}
else{
dropdown.style.display = "none";
}
}
.dropdown {
background: red;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="toggle">Toggle dropdown</button>
<div class="dropdown">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
Related
So i have made a custom selector like
<div class="search">
<input class="custom-selector" type="text" autocomplete="off" >
<ul class="custom-options hidden">
<li>New York</li>
<li>Moscow</li>
<li>Baku</li>
</ul>
</div>
and whenever i focus on the input the class hidden(only has display:none;) gets removed, and on blur(unfocus) it gets added back
$('.custom-selector').focus(function() {
$(".custom-options").removeClass("hidden");
}).blur(function() {
$(".custom-options").addClass("hidden");
})
On the next step i needed a function to onclick get the li value and copy it to the input ,but whenever i click on the li ,the input gets unfocused and the onclick function cant work on a display none,one solution i found was opacity 0 instead of display none for hidden class,is there more optimal and correct way to fix this issue?
Edit: You can add a timeout maybe?
$('.custom-selector').focus(function() {
$(".custom-options").removeClass("hidden");
}).blur(function() {
setTimeout(function () { $(".custom-options").addClass("hidden") }, 350);
})
$('.custom-options > li').click(function(e) {
$('.custom-selector').val($(this).text());
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search">
<input class="custom-selector" type="text" autocomplete="off">
<ul class="custom-options hidden">
<li>New York</li>
<li>Moscow</li>
<li>Baku</li>
</ul>
</div>
You could use a combination of focusable elements and the :focus-within pseudo-class to not lose focus.
$('.custom-options a').click(function (ev) {
const selected = ev.target.textContent;
$('.custom-selector').val(selected);
ev.target.blur();
});
.custom-options {
display: none;
}
.search:focus-within .custom-options {
display: block;
}
.custom-options a {
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search">
<input class="custom-selector" type="text" autocomplete="off">
<ul class="custom-options">
<li>
New York
</li>
<li>
Moscow
</li>
<li>
Baku
</li>
</ul>
</div>
Following is my code. I am trying for a simple drop down when clicking on to li and slideup when clicking li back again. But it's not working. I don't know whats wrong. Can anyone comment on this? On top, I am trying to click on the body to get the menu slide back up again. But not when clicking inside the actual menu box (in green).
$(document).ready(function(){
let list = $('ul li');
let mega = $('.megamenu');
list.click(function(e){
e.preventDefault();
mega.slideDown(400);
if((e.target) == list){
mega.slideUp(400);
}
})
});
li{
list-style:none;
display:inline-block;
padding-right: 5rem;
}
.megamenu{
background:green;
padding:5rem;
color:white;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul>
<li>Page 1
<div class ='megamenu'><h1>Mega menu</h1></div>
</li>
<li>Page 2
<div class ='megamenu'><h1>Mega menu</h1></div>
</li>
</ul>
</div>
Could you change like this for click to li to dropdown and click li slideup again
$(document).ready(function(){
let list = $('.menu');
let mega = $('.submenu');
list.click(function(e){
e.preventDefault();
var menuDisplay = mega.css('display');
if(menuDisplay == 'block') {
mega.slideUp(400);
} else {
mega.slideDown(400);
}
})
});
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul>
<li class='menu'>Page 1
<div class ='submenu'><h1>Mega menu</h1></div>
</li>
<li class='menu'>Page 2
<div class ='submenu'><h1>Mega menu</h1></div>
</li>
</ul>
</div>
CSS
.menu{
list-style:none;
display:inline-block;
padding-right: 5rem;
}
.submenu{
background:green;
padding:5rem;
color:white;
display:none;
}
And click Page1 or Page2 to see slideUp and slideDown
I have the following dropdown code:
$(document).ready(function(){
$(".dropbtn").hover(function(){
$(".dropdown-content").slideDown("fast");
});
$(".dropdown").mouseout(function(){
$(".dropdown-content").slideUp("fast");
});
});
.dropdown-content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="dropdown">
##
<div class="dropdown-content">
##
##
</div>
</li>
</ul>
But when I hover over the dropdown-content, it contracts, as if dropdown-content is not a part of the li class "dropdown" out of which the slideup is triggered in jquery. How can I make it so that the dropdown-content only slides up when the mouse leaves the nav element or dropdown content?
If you add a container, you can ensure the events only fire in relation to the whole item. In addition, use mouseleave to prevent the child elements from firing the event as well.
$(document).ready(function() {
$(".container").mouseover(function() {
$(".dropdown-content").slideDown("fast");
});
$(".container").mouseleave(function() {
$(".dropdown-content").slideUp("fast");
});
});
.dropdown-content {
display: none;
}
.container {
background: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="dropdown">
<div class="container">
##
<div class="dropdown-content">
##
##
</div>
</div>
</li>
</ul>
I had the same problem, it was because I didn't have jquery included to the html.
<script type="text/javascript" src="scripts/libs/jquery/jquery-1.8.2.min.js"></script>
Make sure you had that in your html.
You forgot to include jQuery
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
Add this line to the button of the page. It works.
I have a function that on hover, it shows the image next to the list item. That works fine. However, I need to have it so that when the user clicks the link, the image stays there. As of right now when the user clicks the link the hover function still prevails and the image will only show if the link is being hovered over.
$('[href]').hover(function() {
$(this).closest('li').prev('li').removeClass('hidden');
}, function() {
$(this).closest('li').prev('li').addClass('hidden');
});
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).closest('li').prev('li').removeClass('hidden');
});
ul, li {
list-style: none;
display: inline-block;
}
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="hidden"><img src="https://placehold.it/30x30" /></li>
<li>Link</li>
</ul>
This happening because hover overwrites click. I create this solution so when click the link the image remains visible:
var clickHref = false;
$('[href]').hover(function() {
$(this).closest('li').prev('li').removeClass('hidden');
}, function() {
if (!clickHref)
$(this).closest('li').prev('li').addClass('hidden');
});
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).closest('li').prev('li').removeClass('hidden');
clickHref = !clickHref;
});
ul,
li {
list-style: none;
display: inline-block;
}
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="hidden">
<img src="https://placehold.it/30x30" />
</li>
<li>Link
</li>
</ul>
Probably the off method fit your needs:
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).off("mouseenter mouseleave").closest('li').prev('li').removeClass('hidden');
});
I am making a CSS based menu, with submenu items that pop up when the root element is hovered. the problem I have is that I want the CSS menu to close when I click an item in the list, but at that point I am still technically hovering over the top element, so I figured I had to use javascript to hide the menu. But when I set the display property, I set it forever and it overrides the hover selector of the parent node. And so the submenu doesn't show up anymore.
This must be pretty common, but I can't find any answers...
Any help much appreciated!
html:
<ul class="level1">
<li>one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
css:
.level1 li:hover > ul {
display: inline;
}
.level2 {
display: none;
}
js:
document
.getElementById('test')
.addEventListener('click',function () {
this.parentNode.style.display = 'none';
// After this the menu doesn't open anymore
// because the style is overriden
});
Here's the jsfiddle
You can try this.
<ul class="level1">
<li class="hoverMe">one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
.hoverMe:hover > ul {
display: inline;
}
var test = document.getElementById('test');
test.onclick = function () {
this.parentNode.parentNode.className = "";
};
var level1 = document.getElementsByClassName('level1')[0];
level1.getElementsByTagName("li")[0].onmouseover = function () {
if (this.className != "hoverMe") {
this.className = "hoverMe";
}
};