JavaScript Clicked Outside of Element - javascript

I know with jQuery it is quite easy to see if a user has clicked outside of a particular element and then react to it, much like how clicking outside of an open drop down menu will close it.
I am trying to achieve something similar with JavaScript alone, no jQuery. Here is my current code:
window.onload = function() {
var nav = document.querySelectorAll('ul li.current_page_item');
var navList = nav[0].parentNode;
//Open the navigation menu list
nav[0].onclick = function() {
navList.className = 'open';
}
}
As of now, the code will apply a class of open to an unordered list if its child element li.current_page_item is clicked on.
I would like to trigger an event (to remove the open class) if the user clicks outside of the li.current_page_item list item.
Could someone show how I could listen for then react to an event that would do something like this with JavaScript alone?
Thank you for your time.

Add click on the document that will close the div, and remember to stopPropagation in the li handler or it will propagate to the document as well.
document.onclick = function(e) {
navList.className = 'close';
}
nav[0].onclick = function(e) {
navList.className = 'open';
e.stopPropagation(); // <----
}

Related

Why jQuery breaks on click event?

I am trying to create menu/navigation for mobile screen size. I have made variable that keeps track of is menu opened or not, and if it is then add class 'opened' to ul, but it only works 1st time, and then stops, but if I remove jQuery code that is adding class to ul, then it keeps working like it suppost to be, what might be the problem that causes click event to break?
Site.prototype.hamburgerHandler = function() {
var site = this;
$('#hamburger').click(function(event) {
event.stopPropagation();
if(!site.menuOpen) {
$('nav ul').attr('class', 'open');
site.menuOpen = true;
} else {
$('nav ul').attr('class', 'closed');
site.menuOpen = false;
}
});
}
Code is also available here:
https://github.com/Kevin-Murda/SiteFichte/blob/c4122cdb6fb61a57adebc1b7f6863d8530b37ebd/pub/js/main.js#L144
Use addClass() and removeClass(). If this is a toggle you should be removing the class when it is clicked the second time.
Updated
When you do var site = this; you get a reference to the element the handler is attached, as a locally scoped variable named site.
By dropping the line var site = this, the site.menuOpen will reference the globally defined site
As simpler solution would be to just toggle the open class, and no worries about setting any variable
Site.prototype.hamburgerHandler = function() {
$('#hamburger').click(function(event) {
event.stopPropagation();
$('nav ul').toggleClass('open');
});
}
menuOpen isn't defined, that's why it never traverses the loop.
In this case, problem was caused by after menu is opened it will overlap hamburger button and however you see this button you are instead clicking menu and not the button, it all happened because I used padding-top instead of margin-top to position menu, it's solved now, thanks to everybody who helped.

click events in JavaScript

I'm building a list of images dynamically. What I want to happen is when a user clicks the close text (inside my DIV element) the code will delete that particular image (list element). The code below does that the FIRST time the DIV is selected. After that it seems to ignore my div event listener and jump straight into the jquery on click function.
function removeItem(){
var test = document.querySelector('li > div').addEventListener('click', function(){
$(document).on('click', 'li', function () {
var photoId = (this.id);
$("#"+photoId).remove();
});
});
How can I make it so it will ALWAYS run when the DIV is selected instead of just the first time?
I'm new to learning about JavaScript so any help is appreciated!
When the user clicks on the DIV, you're not removing anything, you're just adding a new click listener on all LIs that removes that LI. Then the user needs to click again to trigger the second handler. It should simply be:
$(document).on('click', 'li > div', function() {
$(this).parent().remove();
});
BTW, there's no point in writing
var photoId = (this.id);
$("#"+photoId).remove();
It's simply $(this).remove(). Why go searching for an ID when you already have a reference to the element itself?

Exclude a radiobutton from .click() of div

I am trying to make and area on my page selectable, but inside there is a radiobutton which i dont want to be part of the selectable area. I have it setup at the moment to allow the user select the area but this also includes the radiobutton:
$(document).ready(function () {
jQuery(document).on('click', 'label[title^="id_"]', function(e) {
$(this).addClass('hide');
var current = "s_" + $(this).attr('title');
$("label[title='" + current + "']").removeClass('hide');
});
});
This basic idea of the code at the moment is hide the selected div and show another. What i want is to exclude the radiobuttons inside this div from the click event.
I tried this: but it prevents clicking of the radiobuttons
if ($(e.target).is('input[type="radio"]')) {
e.preventDefault();
return;
}
As said by Jon in comments(and also my personal answer)
Your code should be:
if ($(e.target).is('input[type="radio"]')) {
return;
}
Put that in opening of the function body of the click event handler.
The return call, will terminate the function so it wont progress further.

Drop down only one menu at a time

So far I have this drop-down menu. When I click on either "Menu", "Menu1" or "Menu2", the links under it will drop down.
The problem:
I need to display only one drop-down at a time, so that the user can switch between them.
I tried to apply css('overflow', 'hidden'); to the menu currently dropped down, but it won't work, since the overflow: visible !important; is applied to the .clicked class.
Please help, anything will be highly appreciated!
Try when you click on a element remove class clicked from all elements and add class clicked to the element that is clicked
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
$("#product-menu>ul>li").removeClass('clicked');
$(this).addClass('clicked');
$('.productSubmenu').width(menuWidth);
});
DEMO
UPDATE
If you want also on second click menu to be closed try checking if clicked item has already class clicked:
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
if ($(this).hasClass('clicked')) {
$(this).removeClass('clicked')
} else {
$("#product-menu>ul>li").removeClass('clicked');
$(this).addClass('clicked');
}
$('.productSubmenu').width(menuWidth);
});
DEMO2
You also might want to close the links
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
$("#product-menu>ul>li").removeClass('clicked');
$("#product-menu .productSubmenu2").hide(); // this one I added
$(this).addClass('clicked');
$('.productSubmenu').width(menuWidth);
});

Understanding JQuery. Collapsible menu

I have created a collapsible menu in JQuery with the help of some coding I've found around this site.
And everything work. But now it's time for me to understand how and why it works.
The JQuery:
jQuery(document).ready(function($) {
var submenu = $('.submenu').hide();
$('.open').click(function() {
$this = $(this);
$target = $this.parent().next();
if(!$this.hasClass('close')){
$('.open').removeClass('close');
submenu.slideUp();
$this.addClass('close');
$target.slideDown();
}else{
$target.slideUp();
$this.removeClass('close');
}
});
});
The HTML and CSS are in here: JSFIDDLE!
Can someone break the code down for me, and explain what it does.
I know that it hides my .submenu class when the page loads.
And when I click the class .open the .submenu. slides down
But then I am a bit lost to what it does with my .close class.
Thanks in advance!
No problems :)
Let's start with this:
jQuery(document).ready(function($){});
this wraps around all jQuery code. it defines an anonymous function and attaches it to the event $(document).ready meaning - this code runs only after the entire DOM is loaded. This is needed because if the following code will run before the elements were loaded it will have no effect on them,
var submenu = $('.submenu').hide();
This line picks all elements with class="submenu", hides them - and returns an array of all submenus to the submenu variable. The rest of the explanation will be commented on each line:
$('.open').click(function() { // the following code will run if you click an element with class="open"
$this = $(this); // $this will hold the element you clicked
$target = $this.parent().next(); // $target will hold the next element (relevant single submenu)
if(!$this.hasClass('close')){ // if the current element is open (marked by class="closed")
$('.open').removeClass('close'); // remove the "close" class from all main menu items
submenu.slideUp(); // close all submenus
$this.addClass('close'); // add "close" class only to the clicked main menu item
$target.slideDown(); // open the correct submenu (the element after the clicked main menu item)
}else{ // if current submenu is already open
$target.slideUp(); // close it
$this.removeClass('close'); // remove class "close" from the main menu item.
}
});
When user clicks on a menu group, you need to consider two cases:
The clicked menu group is closed (i.e. it doesn't have the close class)
!$this.hasClass('close')
If so, you first have to close all open menus, and set their class accordingly:
$('.open').removeClass('close');
submenu.slideUp();
Then you can expand the clicked menu group, and mark it as currently open:
$this.addClass('close');
$target.slideDown();
The clicked menu group is already open. The only thing that needs to be done in that case is closing the menu:
$target.slideUp();
$this.removeClass('close');

Categories