Attach Click Event to HTML after Menu Click - javascript

I've got a dropdown menu on a site I'm working on that has different classes added to it when it is activated. It's built into a WordPress theme so I'm having to build a workaround on it for iPad landscape mode. The site navigation displays the same as desktop when on landscape so I need to create some touch events to mimic the behavior.
The first thing I'm having to do is to deactivate the link on the first click and then reactivate it if it's clicked again. This works fine.
if ('ontouchstart' in document.documentElement) {
$('#masthead nav ul > li:has(.sub-menu) a').click(function(e){
e.preventDefault();
$('li.clicked_link').on('click', function(){
var this_link = $(this).find('> a').attr('href');
document.location.href=this_link;
});
$(this).parent().addClass('clicked_link');
});
}
The problem is that when you click on the li.sub-menu it adds a class of sub-hover onto it which activates a dropdown menu. It's a CSS/jQuery dropdown menu so it's based on the presence of that sub-hover class. It works fine when I first click but I then want to remove that class when you click outside of it. It deactivates it if I click another link in the dropdown but I'd like to bind a click event to the html or body elements so if you click anywhere outside of it, it will remove the sub-hover class, thus removing the dropdown.
I tried to do this:
if ('ontouchstart' in document.documentElement) {
$('#masthead nav ul > li:has(.sub-menu) a').click(function(e){
e.preventDefault();
$('li.clicked_link').on('click', function(){
var this_link = $(this).find('> a').attr('href');
document.location.href=this_link;
});
$(this).parent().addClass('clicked_link');
$('html').on('click',function(){
$('#masthead nav ul > li:has(.sub-menu)').removeClass('sub-hover').removeClass('clicked_link');
});
});
}
It doesn't work though because it seems to fire the first click function and then immediately fire the html click function. I tried to use bind as well but the same thing happened. I also tried it outside of the initial click function but, as you can guess, it fires the two click events simultaneously which doesn't work.
How do I get it to bind but not fire the click event only after the initial click event takes place?

This is not a direct fix for the problem, but something that might help you fix the problem (Too long for a comment).
You are binding click handlers inside another click handler without unbinding the previous ones, So everytime you click a matching <li> new click handlers are being added to <html> and other matching elements. I strongly believe you're not doing it on purpose and isn't aware of it.
Leaving that, You're trying to bind a click for .clicked_link using
$('li.clicked_link').on('click', function(){
This code looks for matching elements currently present in DOM, and probably finds no matching elements since you're actually adding the class clicked_link after it.
You actually need to delegate this handler to check for matching elements in future.
The events are bubbled up till the root element, in other words: you if you click an anchor, starting from the anchor, all the parents till html will receive a click event, which you can prevent using e.stopPropagation();.
Ideally you're code should look something like this:
if ('ontouchstart' in document.documentElement) {
$('#masthead nav ul > li:has(.sub-menu) a').click(function(e){
e.preventDefault();
$(this).parent().addClass('clicked_link');
});
$(document).on('click','li.clicked_link', function(){
var this_link = $(this).find('> a').attr('href');
document.location.href=this_link;
});
$('html').on('click',function(){
$('#masthead nav ul > li:has(.sub-menu)').removeClass('sub-hover').removeClass('clicked_link');
});
}
(Can't go any further with the currently available info. Minimal code such as respective html structure or a demo would be helpful)

Related

How to bind an event within dynamically loaded content on a click event?

I have a div inside my html with the id pageContent. When users click various buttons, it will load the appropriate content. When a user clicks the javaQuestions button it loads, javaQuestions.html into the div just fine. However, inside, the javaQuestions.html, I have a collapsible list, and I can't figure out a way to "bind" the li collapse/uncollapse without having the user to click TWICE. Right now what I have is:
$("#pageContent").on('click', 'li', function (){
$('.collapsible').collapsible();
});
So I guess what happens is, first the user clicks on the button, and it loads content. Then, the user clicks on any li, and it enables the "collapsible()" function, but does not uncollapse/collapse the content. Only when the user clicks a second time does it works fine. I tried adding the line $('.collapsible').collapsible(); into the event that loads the javaQuestions.html content, but it doesn't do anything. Kind of at a roadblock, any ideas?
EDIT: Here is the code that loads the content:
$("#pageContent").on('click', '#javaQuestions', function (e) {
fadeIn("#pageContent", "../java-questions/javaQuestions.html", 50);
fadeIn("#commentsContent", "../comments/comment-section.html", 500);
});
I also really want to know how this will function once I figure it out. But as you can see, the above function loads the javaquestions.html, and I can't seem to find a way to ALSO bind 'li' to be collapsible in one swoop.
Have you tried using jQuery bind method? You can bind your handler to, say, body and then you don't have to care about loading and attaching a handler after it.
Update: may be this will help:
$(document).ready(function() {
$("body").on('click', '#pageContent li', function (){
$('.collapsible').collapsible();
});
});
Use this DOCUMENT because it is dynamically loaded
$(document).on("click","li #pageContent",function(){
$('.collapsible').collapsible();
});

jQuery $(this) selector is not working within a function

I'm trying to make a function that will be fired with the 'onclick' event of a procedurally added div.hb-menu-subMenuToggle element. The function works when using the initial selector as anything but '$(this)'
// FUNCTION: hbMenuSubToggle()
// Toggles CSS classes for animation of .hb-menu-sub-open. Fires when clicking the div element with .hb-menu-subMenuToggle class
function hbMenuSubToggle(){
// TESTING: This works as far as opening the submenus; however, it does not open only the submenu that is a direct sibling of the hb-menu-subMenuToggle element.
$('a.withSubmenu').siblings('ul').toggleClass('hb-menu-sub-open');
// DESIRED EFFECT: Does not work
$(this).siblings('ul').toggleClass('hb-menu-sub-open');
};
Here's a link to the
Codepen Project
Any help would be greatly appreciated!
The correct way to do this would be to use jQuery event handlers rather than using onClick and a function inline in your HTML.
For example if you place this within your $(document).ready() it will attach a click event handler to all A elements in your top menu. When it is clicked you will be able to get $(this) (which is the A element) and then traverse to its parent (the UL element) and then find the child UL elements (the sub menu) to toggle the class.
$('#main-nav>ul>li').on('click', '>a', function(){
$(this).parent().find('ul').toggleClass('hb-menu-sub-open');
});
Similarly your function to show the main menu could also be written as follows
$(document).on('click', '.hb-menu-btn', function(){
$('.hb-menu-btn, .hb-menu, .hb-menu-page').toggleClass('hb-menu-open');
});
See it working on CodePen here: http://codepen.io/anon/pen/rOKQOJ
function hbMenuSubToggle(divyouneed){
// TESTING: This works as far as opening the submenus; however, it does not open only the submenu that is a direct sibling of the hb-menu-subMenuToggle element.
$('a.withSubmenu').siblings('ul').toggleClass('hb-menu-sub-open');
// DESIRED EFFECT: Does not work
divyouneed.siblings('ul').toggleClass('hb-menu-sub-open');
};
and use it
hbMenuSubToggle($(this))
for $(this) you have to had selected one element before. In a function you dont have it like that.. So it will only work if you select it directly and not with $(this)
function hbMenuSubToggle() {
$('.blablabla').blablabla();
}
And read this to find out more about jQuerys basics

preventDefault but activate links

In my navigation menu, I have a dropdown that I want to use. The actual dropping down is fine, and I've prevented the automatic bubbling by using preventDefault(); but now all the links within the dropdown no longer work.
How do I make it so that the dropdown works, doesn't bubble and all the links within the dropdown work?
Edit: I've also used event.stopPropagation() to no effect either. What's going on here?!
This is my code:
// Toggle dropdowns
$('.menu-item-has-children').click(function(e){
e.preventDefault();
$(this).find('.sub-menu').toggleClass('open');
});
To stop bubbling, use event.stopPropagation().
Only use event.preventDefault() to prevent the default action of the event from happening.
Ah, now I see your problem. The issue is that when clicking a menu item to open a submenu, since the item is an anchor pointing to #, the document will scroll to top.
To avoid that, I suggest getting rid of href="#".
Alternatively, you can use preventDefault only if the clicked element was that element, not a descendant:
$('.menu-item-has-children').on('click', function(e){
if(this == e.target) e.stopPropagation();
// ...
});
Demo
You can check which element was clicked by using e.target, and if the clicked element was a sub menu link, don't preventDefault

Disable Bootstrap nav item click event

I'm using Bootstrap 3 nav as something like "collapsible div" only which holds multiple level menu. but I have an issue with the nav items or its hyperlinks click event and want to disable it so my menu works the way I want.
For sure I've assigned my custom events to the nav items which open the second level but for some reason that doesn't work fine on mobiles.
I even tried javascript:void() for the hyperlinks but I think the click event of bootstrap is assigned to the <li>
Use the following to prevent the default link behavior.
$( "a" ).click(function(e) { // target any selector
e.preventDefault();
});

trigger parent click event when child is clicked

I'n new to javaScript and jQuery. How is this possible to call the click event of parent element when you click its child?
I have this structure in my code:
<ul id="pc5">
<li>book
</li>
</ul>
I want something like this:
$("a").click(ul.click);
Any help would be appreciated.
EDIT: in my ul click function I need ul id attribute. something like this:
ul.click(function(e){alert(e.target.id);
so when link is clicked, event.target isn't ul element.
If your child element is located inside your parent element you could also just add this CSS property.
.child {
pointer-events: none
}
This way the click directly triggers the parent's click event listener.
This feature's support is quite good.
You dont need to trigger element click events when child elements are clicked, the click event bubbles up the dom tree if you dont stop propagation.
Here you can see it working: jsfiddle just click on the blue span, the click event will bubble up to the ul :)
Updated question
If you want the id of the ul, simply to:
$('ul li a').click(function() {
var id = $(this).closest('ul').attr('id');
});
Which would be even easier like so:
$('ul').click(function() {
var id = $(this).attr('id');
alert(id);
});
Working fiddle
This should work if you click on an since it bubbles up
You should read about event propagation in jQuery. In few words: when user clicks on a then event will be propagated up in DOM tree.
I had html like this:
<a href="?chk=1">
<input id="CHK_1" name="CHK[1]" type="checkbox">
<span>CHK 1</span>
</a>
where checkbox was supposed to be checked/unchecked only from server side.
For reason i don't know, 'click' was not bubbling from checkbox to link,
so i used js code like this:
$(document).on('click', '[id^="CHK_"]', function (e){
window.open($(this).parent().attr('href'), '_self');
e.preventDefault();
});

Categories