Cannot Click Button after being Toggled - javascript

I cannot Close the dropdown using the button but i can close it when I clicked the outer page.
Working Demo here
var $menu = $('.menu');
$('.toggle').click(function () {
$menu.toggle();
});
$(document).mouseup(function (e) {
if (!$menu.is(e.target) // if the target of the click isn't the container...
&& $menu.has(e.target).length === 0) // ... nor a descendant of the container
{
$menu.hide();
}
});
Please help me guys.

$(document).ready(function(){
var $menu = $('.menu');
$('.toggle').click(function (e) {
e.stopPropagation();
$menu.toggle();
});
$('.container').click(function (e) {
e.stopPropagation();
$menu.toggle();
});
});
.dropdown {
margin: 200px auto;
position: relative;
width: 50%;
}
.toggle, .dropdown-menu {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="text-center col-xs-12">
<h1>jQuery: click outside to close menu</h1>
<p>Click the button to toggle the dropodown menu.</p>
<p>Then click outside dropdown menu to close.</p>
<div class="dropdown">
Toggle menu
<ul class="dropdown-menu menu">
<li class="dropdown-item">List item 1</li>
<li class="dropdown-item">List item 2</li>
<li class="dropdown-item">List item 3</li>
</div>
</div>
</div>
</div>
Use event.stopPropagation(); this will not prevent other handlers on the same element from running.

Simply U need only one action on mouse click. Your JS must be:
var $menu = $('.menu');
var $toggle = $('.toggle');
$(document).mouseup(function (e) {
if ($toggle.is(e.target)) {
$menu.toggle()
} else {
$menu.hide();
}
});

If you want to open and close on button. Just remove the second function and your code will work.
var $menu = $('.menu');
$('.toggle').click(function () {
$menu.toggle();
});

Related

How do I hide the menu when I click outside?

There is a website, there is a mobile version. The mobile version has a drop-down menu. This menu works fine, but it doesn't close when clicked outside the block.
I've been looking for a solution on the Internet for a really long time, but nothing came up( I'll be very grateful for the help!
HTML
<header class="header" id="header">
<div class="container">
<div class="header__inner" id="header">
<div class="header__logo">
<img src="Images/ActiveBox_logo.png" alt="Logo" class="img__logo">
</div>
<nav class="nav" id="nav">
Features
Works
Our Team
Testimonials
Download
</nav>
<button class="burger" type="button" id="navToggle">
<span class="burger__item">Menu</span>
</button>
</div> <!-- header__inner -->
</div>
</header>
JS
let header = $("#header");
let intro = $("#intro");
let introH = intro.innerHeight();
let scrollPos = $(window).scrollTop();
let nav = $("#nav");
let navToggle = $("#navToggle");
checkScroll(scrollPos, introH);
$(window).on("scroll resize", function() {
introH = intro.innerHeight();
scrollPos = $(this).scrollTop();
checkScroll(scrollPos, introH);
});
function checkScroll(scrollPos, introH) {
if( scrollPos > introH ) {
header.addClass("fixed");
} else {
header.removeClass("fixed");
}
}
/* Smooth scroll */
$("[data-scroll]").on("click", function(event) {
event.preventDefault();
let elementId = $(this).data('scroll');
let elementOffset = $(elementId).offset().top;
nav.removeClass("show");
$("html, body").animate({
scrollTop: elementOffset - 70
}, 700);
});
// Nav Toggle
navToggle.on("click", function(event) {
event.preventDefault();
nav.toggleClass("show");
});
How about something like this?
$(document).on('click', function (e) {
if ($(e.target).closest("#box").length === 0) {
$("#box").hide();
console.log('clicked outside the box');
}
else {
console.log('clicked on the box');
}
});
#box{
width:100px;
height:40px;
background-color:blue;
color:white;
padding:5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='box'>
click me, then click outside
</div>

Prevent multiple EventListeners from clashing on focus with Vanilla JavaScript

I'm extending my existing navigation for accessibility, but having issues when hitting "Enter" on the keyboard whilst the target are focused. The eventlisteners for the search and/or navigation toggle fire when any other element is focused on, this could be any anchor or any focused element.
Mouse clicking the individual elements (and clicking out of form) functions the way it needs to. However, on focus THEN hitting "Enter" anywhere on the page, it fires off, if not the right one, both events. Any help would be appreciated.
/* Search */
let searchToggle = document.querySelector('.search-toggle'),
searchForm = document.querySelector('.search-form');
function searchClick(event) {
event.stopPropagation();
let toggled = searchToggle.contains(event.target);
if (toggled) {
searchForm.classList.add('show-search-form');
} else if (!event.target.closest('.show-search-form')) {
searchForm.classList.remove('show-search-form');
}
}
function searchFocus(event) {
if (event.keyCode === 13) {
event.stopPropagation();
searchToggle.click();
}
}
document.addEventListener('click', searchClick, false);
document.addEventListener('keyup', searchFocus, false);
/* Navigation */
let navToggle = document.querySelector('.toggle'),
nav = document.querySelector('.nav');
navToggle.addEventListener('click', () => {
nav.classList.toggle('toggle-menu');
});
function navFocus(event) {
if (event.keyCode === 13) {
event.stopPropagation();
navToggle.click();
}
}
document.addEventListener('keyup', navFocus, false);
*:focus-visible {
outline: 5px solid #333333;
}
.search-form,
.nav {
display: none;
}
.search-form.show-search-form {
display: block;
}
.nav.toggle-menu {
display: block;
}
<div class="search-toggle" tabindex="0">
<span>Toggle Search</span>
</div>
<div class="search-form">
<span>Test Form</span>
</div>
<div class="toggle" tabindex="0">
<span>Toggle Menu</span>
</div>
<nav class="nav">
<ul>
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</nav>

How to make navigation menu disappear when clicking anywhere on the screen with HTML, CSS, and javascript

This webpage has a navigation menu that is functioning properly. When the navigation icon is clicked, the menu will appear and the icon will be replaced with an "X" icon. When the "X" is clicked the navigation menu disappears.
However, it would nice to make it so that while the navigation menu is present, clicking anywhere outside of it will make it disappear as well.
Here is a picture for context:
HMTL
<html>
<div id="sideNav">
<nav>
<ul>
<li>HOME</li>
<li>COVID-19</li>
<li>SERVICES</li>
<li>REVIEWS</li>
<li>CONTACT</li>
</ul>
</nav>
</div>
<div id="menuBtn">
<img src="images/menu.PNG" id="menu">
</div>
</html>
CSS
#sideNav{
width: 200px;
height: 100vh;
position: fixed;
right: -250px;
top:0;
background: #009688;
z-index: 2;
transition: 0.33s;
}
javascript
var menuBtn = document.getElementById("menuBtn")
var sideNav = document.getElementById("sideNav")
var menu = document.getElementById("menu")
sideNav.style.right = "-250px";
menuBtn.onclick = function(){
if(sideNav.style.right == "-250px"){
sideNav.style.right = "0";
menu.src = "images/close.PNG";
}
else{
sideNav.style.right = "-250px";
menu.src = "images/menu.PNG";
}
}
use event.stopPropagation() and add click event to the document
var menuBtn = document.getElementById("menuBtn")
var sideNav = document.getElementById("sideNav")
var menu = document.getElementById("menu")
menuBtn.onclick = function(e) {
//stop propagation of document click
e.stopPropagation()
//toggle side nav
if (!sideNav.classList.contains("open")) {
sideNav.classList.add("open");
menu.src = "images/close.PNG";
} else {
sideNav.classList.remove("open");
menu.src = "images/menu.PNG";
}
}
//stop propagation on the side nav element
sideNav.onclick = function(e) {
e.stopPropagation()
}
//close menu when document is clicked
document.onclick = function() {
sideNav.classList.remove("open");
menu.src = "images/menu.PNG";
}
#sideNav {
width: 200px;
height: 100vh;
position: fixed;
right: -250px;
top: 0;
background: #009688;
z-index: 2;
transition: 0.33s;
}
/*set the right to 0 for class open*/
#sideNav.open {
right: 0;
}
<html>
<div id="sideNav">
<nav>
<ul>
<li>HOME</li>
<li>COVID-19</li>
<li>SERVICES</li>
<li>REVIEWS</li>
<li>CONTACT</li>
</ul>
</nav>
</div>
<div id="menuBtn">
<img src="images/menu.PNG" id="menu">
</div>
</html>
To able to click anywhere on the screen and have something, then you should listen for clicks anywhere on the page. Attach an event listener to the document where you check if the clicked element is not a child of the side nav element.
You can check this with the closest() method which is like a querySelector() that runs up the DOM and evaluates each parent.
If there is no hit, then it means that you're not clicking inside the side navigation, so it must be outside the side navigation. Now you know that you can close the menu.
document.addEventListener('click', event => {
// If the clicked element is not a child of #sideNav..
if (event.target.closest('#sideNav') === null) {
// ..then close navigation..
// { your code here }
}
});
With jQuery:
$(document).mouseup(function (e){
let sideNav = $("#sideNav");
if (!sideNav.is(e.target) && sideNav.has(e.target).length === 0) {
sideNav.addClass("hide");
$("#menu").removeClass("close");
}
});
Pure js:
window.addEventListener('mouseup', function(e){
var sideNav = document.getElementById("sideNav");
var menu = document.getElementById("menu")
if (e.target.id != 'moreDrop') {
sideNav.classList.add('hide');
}
});

Clone working for an element but not for entire div

Explanation: I am trying to clone elements / div. I am trying to achieve it by right clicking on them opening up a context menu and clicking on "clone" option.
I have a very simple code, let me show you -
(function ($, window) {
$.fn.contextMenu = function (settings) {
return this.each(function () {
// Open context menu
$(this).on("contextmenu", function (e) {
// return native menu if pressing control
if (e.ctrlKey) return;
//open menu
var $menu = $(settings.menuSelector)
.data("invokedOn", $(e.target))
.show()
.css({
position: "absolute",
left: getMenuPosition(e.clientX, 'width', 'scrollLeft'),
top: getMenuPosition(e.clientY, 'height', 'scrollTop')
})
.off('click')
.on('click', 'a', function (e) {
$menu.hide();
var $invokedOn = $menu.data("invokedOn");
var $selectedMenu = $(e.target);
settings.menuSelected.call(this, $invokedOn, $selectedMenu);
});
return false;
});
//make sure menu closes on any click
$('body').click(function () {
$(settings.menuSelector).hide();
});
});
function getMenuPosition(mouse, direction, scrollDir) {
var win = $(window)[direction](),
scroll = $(window)[scrollDir](),
menu = $(settings.menuSelector)[direction](),
position = mouse + scroll;
// opening menu would pass the side of the page
if (mouse + menu > win && menu < mouse)
position -= menu;
return position;
}
};
})(jQuery, window);
$("#container").contextMenu({
menuSelector: "#contextMenu",
menuSelected: function (invokedOn, selectedMenu) {
var msg = "You selected the menu item '" + selectedMenu.text() +
"' on the value '" + invokedOn.text() + "'";
//var itsId = $(invokedOn).attr('id');
var selectedText = $(invokedOn).get(0).outerHTML;
var parentDiv = $(invokedOn).parent();
alert(selectedText);
if (selectedMenu.text() == "Clone"){
//alert("inside");
$(invokedOn).clone().insertAfter(invokedOn);
}
}
});
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css">
</head>
<body>
<div id="container">
<div id="content">content</div>
<div id="content2">
<p>This is p </p>
<h3> This is h3 </h3>
</div>
</div>
<ul id="contextMenu" class="dropdown-menu" role="menu" style="display:none" >
<li><a tabindex="-1" href="#">Clone</a></li>
<li><a tabindex="-1" href="#">Another action</a></li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="contextmenu.js"></script>
</body>
Run the code and Right click on "this is p" or "this is h3" and select clone, they will be cloned but i also want to clone entire div according to my selection. This requirement works for me on click but dont know how to do it by context menu, see this code here, the below code will work with left click, see this pic, i can clone entire div or single element depending on my area of click, same thing i want above with right click - https://www.dropbox.com/s/mqftyt96s75jc6b/Screenshot%202017-04-07%2013.38.30.png?dl=0
$('*').on('click', function(e){
e.stopPropagation()
var thisDiv_name = $(this).attr('id');
var thisDiv = $(this);
var parentDiv = $(this).parent();
// $(this).clone().appendTo(parentDiv);
$(this).attr('style','outline: #6c6b69 solid thin;');
$(this).clone().insertAfter(thisDiv);
//alert($(this).html());
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
</script>
</head>
<body>
<div id="main">
<div id="content">content</div>
<div id="content2">
<p>This is p </p>
<h3> This is h3 </h3>
</div>
<button id="button">show it</button>
</div>
</body>
</html>
To achieve this you could implement a new context menu item which clones the parent() element of one which triggered the event.
Also note that you can tidy up the logic by using a data attribute to specify the action to be performed instead of matching the text. Try this:
!function(a,b){a.fn.contextMenu=function(c){function d(d,e,f){var g=a(b)[e](),h=a(b)[f](),i=a(c.menuSelector)[e](),j=d+h;return d+i>g&&i<d&&(j-=i),j}return this.each(function(){a(this).on("contextmenu",function(b){if(!b.ctrlKey){var e=a(c.menuSelector).data("invokedOn",a(b.target)).show().css({position:"absolute",left:d(b.clientX,"width","scrollLeft"),top:d(b.clientY,"height","scrollTop")}).off("click").on("click","a",function(b){e.hide();var d=e.data("invokedOn"),f=a(b.target);c.menuSelected.call(this,d,f)});return!1}}),a("body").click(function(){a(c.menuSelector).hide()})})}}(jQuery,window);
$("#container").contextMenu({
menuSelector: "#contextMenu",
menuSelected: function($invokedOn, $selectedMenu) {
var action = $selectedMenu.data('action');
switch (action) {
case 'cloneEl':
$invokedOn.clone().insertAfter($invokedOn);
break;
case 'cloneParent':
var $parent = $invokedOn.parent();
$parent.clone().insertAfter($parent);
}
}
});
/* CSS is only to make the output more obvious */
p { background-color: #CC0; }
h3 { background-color: #0CC; }
#container > div {
border: 1px solid #C00;
margin: 5px;
}
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div id="container">
<div id="content">content</div>
<div id="content2">
<p>This is p </p>
<h3>This is h3</h3>
</div>
</div>
<ul id="contextMenu" class="dropdown-menu" role="menu" style="display:none">
<li><a tabindex="-1" href="#" data-action="cloneEl">Clone</a></li>
<li><a tabindex="-1" href="#" data-action="cloneParent">Clone parent</a></li>
<li><a tabindex="-1" href="#" data-action="another">Another action</a></li>
</ul>

How to switch image if DIV is not hidden

I have the following JQuery which displays a menu if a DIV is pressed:
var pull = $('#mmTrigger');
menu = $('.ulMM');
menuHeight = menu.height();
$(pull).on('click', function(e) {
e.preventDefault();
menu.slideToggle();
});
HTML:
<div class="dvMain">
<ul class="ulMM specClear">
<li class="liMM">Portfolio</li>
<li class="liMM">About</li>
<li class="liMM">Contact</li>
<li class="liMM">Forum</li>
</ul>
<div id="mmTrigger"><img src="nav-icon.png" class="imgMenu" /></div>
</div>
I modified the script to this:
$(pull).on('click', function(e) {
e.preventDefault();
menu.slideToggle();
if (menu.is(':hidden')) {
$(".imgMenu").attr("src", "nav-icon.png");
} else {
$(".imgMenu").attr("src", "iconx.png");
}
});
But after clicking the DIV, the X stays and doesn't go back to the nav-icon.png once the menu is closed.
How can I resolve it so that the X changes to the menu icon.
I added this statement: alert (menu.is(':hidden')); it always returns false.
You should change the icon after the slideToggle animation has stopped. You can do this in callback like this:
$(pull).on('click', function (e) {
e.preventDefault();
menu.slideToggle(function () {
// slideToggles callback
if (menu.is(':hidden')) {
$(".imgMenu").attr("src", "nav-icon.png");
} else {
$(".imgMenu").attr("src", "iconx.png");
}
});
});
try changing image on complete of slide toggle: see here:http://api.jquery.com/slidetoggle/
$(document).ready(function(){
var pull = $('#mmTrigger');
menu = $('.ulMM');
menuHeight = menu.height();
$(pull).on('click', function(e) {
e.preventDefault();
menu.slideToggle("slow", function() {
alert( ! menu.is(":visible") );
if (! menu.is(":visible")) {
$(".imgMenu").attr("src", "https://maps.google.com/mapfiles/kml/shapes/schools_maps.png");// icons added to show demo use your own icons.
} else {
$(".imgMenu").attr("src", "http://labs.google.com/ridefinder/images/mm_20_black.png");
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dvMain">
<ul class="ulMM specClear">
<li class="liMM">Portfolio</li>
<li class="liMM">About</li>
<li class="liMM">Contact</li>
<li class="liMM">Forum</li>
</ul>
<div id="mmTrigger"><img src="https://maps.google.com/mapfiles/kml/shapes/schools_maps.png" class="imgMenu" /></div>
</div>

Categories