Jquery click function exclude children - javascript

Hey I'm having an issue figuring this one out.
JS
$('.jrm-menu-categories,#overlay-2').click(function() {
$('#overlay-2').toggle();
$('#overlay-3').hide();
});
HTML
<ul id="megaUber" class="megaMenu">
<li id="menu-item-1459" class="jrm-menu-categories">
<ul class="sub-menu sub-menu-1">
So basically what my JS does is create an overlay/modal effect when a sub menu is opened via click. I have the code repeated a few times with different classes and overlay ids hence the last line of code (needed so that only one overlay is shown at a time). Quickest and simplest way for a beginner like me, but that's not the subject.
When a sub-menu is open, and a user clicks anywhere in the sub-menu it toggles the overlay. I'm assuming this is because when I selected .jrm-menu-categories in the JS, it also selected the child elements, which happen to be .sub-menu
I'm thinking I need to use the .not() function, but can't figure it out.
can you guys help me with this? if possible write the code so I can try it out
Thanks!

You can try adding a second click handler to the children that will always return false. That way the click won't propagate up and dismiss:
$('.jrm-menu-categories').children('.sub-menu').click(function (e) {
e.stopPropagation(); // prevent click propagation, so parent click never fires.
})

You can test for the clicked item.
$('.jrm-menu-categories,#overlay-2').click(function(e) {
if (this == e.target){
$('#overlay-2').toggle();
$('#overlay-3').hide();
}
});

Related

How to use .not() Jquery Selector on triple selector class?

I have an issue with two buttons that share common html classes. Both buttons are part of a tutorial. As the tutorial goes through the steps the Skip button appears first. as the tutorial gets to the last step before moving on to anew tutorial page, the 3rd party JS package dynamically adds another class to the skip button and changes the inner html to Continue. My issue is below
One button is:
<a class="introjs-button introjs-skipbutton" role="button" tabindex="0">Skip</a>
The other button is
<a class="introjs-button introjs-skipbutton introjs-donebutton" role="button" tabindex="0">Continue</a>
These buttons are part of a tutorial guide with certain steps. They are not displayed at the same time. However, clicking the Skip button fires the same action as the Continue button, as displayed in the JS code below. I'd like the action to only Fire when the Skip button is clicked but it keeps firing on both and I cant figure out how to figure it out.
I'd like a certain action to fire but only fire when <a class="introjs-button introjs-skipbutton> is fired and NOT <a class="introjs-button introjs-skipbutton introjs-donebutton> is fired.
$("a.introjs-button.introjs-skipbutton").not(".introjs-donebutton").click(() => {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
})
I've tried various combinations and was hoping to get some insight on using the not() selector for triple stacked html classes.
You don't need to use :not(). You could just check it doesn't have the class.
$("a.introjs-button.introjs-skipbutton").click(() => {
if ( ! $(this).hasClass('introjs-donebutton') {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
}
})
The hasClass() documentation can be read here.
If you're adding and removing the introjs-donebutton class dynamically, you can do it with event delegation and a selector with :not().
$(document).on("click", "a.introjs-button.introjs-skipbutton:not(.introjs-donebutton)", () => {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
})

Detect Right Click From Class Selector?

I have the below HTML which is generated using jQuery from an AJAX call:
<ul id="ul-container">
<li class="li-item" data-deviceKey="1">Data1</li>
<li class="li-item" data-deviceKey="2">Data2</li>
</ul>
I then have this jQuery code:
$('.li-item').mousedown(function(e) {
if(e.which == 3) {
console.log('Right Click Detected on '+$(this).attr('data-deviceKey'));
}
});
I am trying to detect a right mouse click, and then do something when it occurs.
This does not work, and it's stressing me out. I've tried literally every combination under the sun in order to try and get this to work. There's way too many to list, but literally nothing will detect the right click event.
Weirdly, if i set the selector to the ul's ID, it will then detect it? But, the problem is, i need to obtain the data-deviceKey attribute from the selected li.
Has anyone got any idea where the issue is here?
Things I've tried
1: Pretty much every reply in this: How to distinguish between left and right mouse click with jQuery
2: Detecting the right click on the ul's ID then finding the "closest" li element, which just returned the first li element in the list.
3: In my actual code, my li has 3 classes attached, i've tried using all of these which has not worked
4: tried using $('#ul-container li') to no avail.
Is it even possible to detect a right click on a class? Where am i going wrong? Please help before i have no hair left!
This is just a guess, but if you're loading the HTML content via an AJAX call, then you need to register the click handler after the HTML is inserted into the DOM.
Try registering the mousedown in the AJAX request's .done callback:
$.ajax({
url: "test.html",
}).done(function() {
$('.li-item').mousedown(function(e) {
if (e.which == 3) {
console.log('Right Click Detected on ' + $(this).attr('data-deviceKey'));
}
});
});

Why can't jquery remove these classes?

I have created a series of elements that when you click on any one of them, they will expand, pushing the other elements out of the way. Initially if you clicked on it again the element would contract, but now I want to take the close functionality and put it in a button with in the element.
Initially when you click on the element, I use jQuery to add a number of classes to a variety of elements.
$(".left > .elem").click(function () {
$(this).addClass("expand");
$(this).parent().addClass("WithLarge");
$(this).children(".bar").addClass("visible");
$(this).children(".reduce_button").addClass("visible");
$(".right").addClass("shift_right");
});
When I click the close button I would like to remove those classes.
$(".reduce_button").click(function () {
$(this).parent().removeClass('expand');
$(this).parent().removeClass("WithLarge");
$(this).parent().children(".bar").removeClass("visible");
$(this).parent().children(".reduce_button").removeClass("visible");
}
The problem is, those classes aren't budging.
You can try it out on the JSFiddle
Click on the yellow box(".left > .elem"), it expands pushing the others out of the way, click on the red box(".reduce_button"), and nothing happens. I tried
console.log($(this).parent().hasClass('expand'));
$(this).parent().removeClass('expand');
console.log($(this).parent().hasClass('expand'));
to see if it has been removed. It returns false, even though the class is still there.
Why can't I remove these classes?
You ARE removing the class. But, the click on the .reduce_button is also triggering the .elem click event, which adds the class back again.
EDIT:
As commented below by j08691, you can add stopPropagation to keep the event of going on to the next listener, like:
$(".reduce_button").click(function (e) {
$(this).parent().removeClass('expand');
e.stopPropagation();
...
Here is your fiddle updated: http://jsfiddle.net/HybHK/9/

Error when trying to execute two onclick actions on the same div

I have a little problem here, and if someone could help me, I will truly appreciate.
I have a menu that opens when I click on a div, and once open, I want to close the menu clicking again on te same div. The problem is that I can open the menu but I can't close it.
Here is my code:
<script>
$(document).ready(function () {
$("#menuResp").click(function () {
$('#profile_menu').css('margin-left','0px');
$('#menuResp').css('margin-left','315px');
$('#menuResp').attr('id', 'menuResp2')
});
$("#menuResp2").click(function () {
$('#profile_menu').css('margin-left','-300px');
$('#menuResp2').css('margin-left','0px');
$('#menuResp2').attr('id', 'menuResp')
});
});
</script>
<div id="menuResp">
<ul id="menuRespCss">
<li class="icon-css">
<a>Menu</a>
</li>
</ul>
</div>
Anyone have an idea of why this doesn't work?
What your code is doing is setting callbacks at the moment, when the initial DOM is being built. Of course, there is no #menuResp2 yet. Insdead, set the callback on the document element (or body, or some other parent element), specifying the selector of your menu - this element will fire the event. This will work:
$(document).ready(function () {
$(document).on('click', "#menuResp", function () {
$('#profile_menu').css('margin-left','0px');
$('#menuResp').css('margin-left','315px');
$('#menuResp').attr('id', 'menuResp2')
}).on('click', "#menuResp2", function () {
$('#profile_menu').css('margin-left','-300px');
$('#menuResp2').css('margin-left','0px');
$('#menuResp2').attr('id', 'menuResp')
});
});
But. I would stroungly recommend not to change the ID attribute, but to work with classes instead.
you need to add the click handler like this
$(document).on('click', '#menuResp', function(){
$('#profile_menu').css('margin-left','0px');
$('#menuResp').css('margin-left','315px');
$('#menuResp').attr('id', 'menuResp2');
});
.click() only works for elements that are already created, using .on() will cover elements that will be created later.
you should really be identifying the element by class though , and using .addClass() and .removeClass() like the comment suggest
just use toggle. if the item is closed, it will open, if its open, it will close. all the answers above do not check to see if the item is open already or not.
$(document).on("click", function(e){
e.preventDefault();
$('#menuResp').toggle();
$("##menuResp2").toggle();
})
easier would be to give element a single class and just toggle once on class name, rather than changing the ID of the item, this second item would not have an avent binding added to it. But at the same time. You dont need the ID when you can just toggle with class. like so:
$(".clasname").toggle();
this will open any element that is closed with the class of clasname. this will also, at the same time, close all elements that have that class name, and are also open

onclick dropdown menu with a form, click outside to close

ive got a drop down menu with form elements. the menu element gets set to
display:none
when anything outside the element is clicked ... or at least so i thought.
Here's my little function
$(function(){
$('#loginAcc').click( function(event){
event.stopPropagation();
//show
$('#auth-menu').css('display', 'block');
});
$(document).click( function(){
//hide when click anywhere out the menu
$('#auth-menu').hide();
});
})
the problem i have is that it also closes when i click inside the element, which makes it very difficult, pretty much impossible to complete a form.
#loginAcc
is a horizontal list item that gets clicked, and
#auth-menu
is
if i were to hazard a guess, i would like to think that .toggle() is the culprit, but that's a sheer guess and i wouldn't even know where to start if i were to reimplement it (a little bird told me that it's getting taken out of the spec anyway).
what i would like to happen is that when you click on the #loginAcc list item, the #auth-menu gets set to display:block, and can only be closed if you reclick #loginAcc or anywhere else outside of #auth-menu.
any help would be amazing. thanks
Use a not() selector to exclude the menu:
$(document).not('#auth-menu').click( function(){
//hide when click anywhere out the menu
$('#auth-menu').hide();
});

Categories

Resources