jQuery delegated event target conflicting with children - javascript

When I click on menu-link specifically on the span the class active doesn't get added or toggled, if I click not on the span then everything works as normal.
$(document).on("click touchstart", ".menu-link", function(event) {
$("body").toggleClass('nav-open');
utilities.toggleContent(event);
});
utilities = function() {
var toggleContent = function(event) {
//If clicked element is an anchor and has a hash target, use it to select the toggle DIV
if (event.target.hash) {
//If it's one of the menu links
if ($(event.target).hasClass('menu-link')) {
//Close any open menus which aren't the target menu
$(".menu-content.active").not($(event.target.hash)).removeClass('active');
}
//Toggle the target menu
$(event.target.hash).toggleClass('active');
event.preventDefault();
} else {
$(this).next().toggleClass('active');
$(this).toggleClass('active');
return false;
}
},
// ...
<a href="#mainMenu" class="menu-link">
<span class="iconbar"></span>
<span class="iconbar"></span>
<span class="iconbar"></span>
</a>

Related

How to close navbar when clicking outside of it

How can I edit my code so that the navbar closes when clicked outside of it but remain open if something inside of it is clicked?
$(document).ready(function() {
$('.nav-btn').on('click', function() {
$('.nav-btn').removeClass('active');
$(this).parent().find('.sub-menu').slideToggle();
$(this).toggleClass('active');
});
});
$(document).ready(function () {
$('.nav-btn').on('click', function (e) {
// Stop Document to be clicked when clicked in nav.
e.stopPropagation()
$('.nav-btn').removeClass('active');
var subMenu = $(this).parent().find('.sub-menu')
if (!$(".sub-menu").is(":visible")) {
$(this).parent().find('.sub-menu').slideToggle();
}
$(this).toggleClass('active');
});
// Toggle Sub Menu and remove active when Any vacant place is clicked
$(this).on('click', function (event) {
$('.nav-btn').removeClass('active');
$('.nav-btn').parent().find('.sub-menu').slideToggle();
});
// Prevent View close when Sub Items is clicked
$('.sub-menu').on('click', function (e) {
e.stopPropagation()
})
});
Hi, You just need to prevent the document click when clicked on the nav item and handle some additional things as done in the above code.
You can see Plunker example here also.
$(document).on('click', function (event) {
if ($(event.target).closest('.main-nav').length === 0) {
// Close button code
}
});
Another possible way is by wrapping all the content inside another div (except the header & navbar) and using the onclick tag:
<div onclick="hideNavbar()">
all your content goes here
</div>
function hideNavbar() {
$('.navbar-collapse').collapse('hide');
// getting the navbar div with jQuery
// and calling the function 'hide' of the Bootstrap class 'collapse'
}

How can I keep a menu open when navigating to another page?

I'm using a js code for additional menu options on click, but how can I keep the "click menu" permanently open, say after one of its option has been clicked, so the user won't have to start over again once taken to the new page.
HTML:
<div class="c3" id="topLeftNav">
<ul class="secnav" id="secnav">
<h6>Generelt</h6>
<li class="current">Ordklasser
<ul class="ternav">
<li>Substantiver</li>
<li>Verber</li>
<li>Adjektiver</li>
<li>Numeralier</li>
<li>Interjektioner</li>
</ul>
And my JS:
///ternav/secnav -- catch inner clicks (ternav) first and preventDefault.
$('.ternav li a').click(function () {
window.location = $(this).attr('href');
});
//secnav
$('li').click(function (event) {
if ($(this).has('ul').length) {
event.preventDefault();
if ($(this).find('ul').css("display") == "none") {
$(this).find('a').eq(0).addClass('current');
$(this).find('ul').slideDown();
}
else {
$(this).find('ul').slideUp();
$(this).find('a').eq(0).removeClass('current');
}
}
});

How to close a sidebar when clicking outside?

I have a right sidebar appearing when this function its called
var toggleSidebar = function() {
$('#sidebar .arrow-box').click(function() {
if (s === 0) {
s = 1;
$('#sidebar').css('left', '0');
$('#sidebar .arrow').removeClass('dir-two');
$('#sidebar .arrow').addClass('dir-one');
$('#content').css('padding-left', '0');
} else {
s = 0;
$('#sidebar').css('left', '-300px');
$('#sidebar .arrow').addClass('dir-two');
$('#sidebar .arrow').removeClass('dir-one');
$('#content').css('padding-left', '300px');
}
});
};
but as you see I can open and close that sidebar only when clicking on that specific element, what should I do in order to close it when I click outside?
And just in case: as per UX I am not able to use a dark background in the whole view when the sidebar comes up.
Test the target of the click. If it does not match the target you want to close, then close it. All the other elements are children of the body - so clicking anywhere outside of the panel will retrieve a click target.
$sidebar = $('#sidebar');
$( "body" ).click(function( event ) {
var a = event.target;
if(a === $sidebar){
//close the sidebar
//you may also want to test if it is actually open before calling the close function.
}
});
Take a look at this:
How do I detect a click outside an element?
$('html').click(function() {
// Hide the sidebar
});
$('#sidebar').click(function(event){
event.stopPropagation(); // prevents executing the above event
});
I would do it like this... (DEMO HERE)
sideBarOpen=false;
function openSidebar(){
sideBarOpen = true;
$('#sidebar').css('margin-left', '0');
$('#sidebar .arrow').removeClass('dir-two');
$('#sidebar .arrow').addClass('dir-one');
$('#content').css('padding-left', '0');
}
function closeSidebar(){
sideBarOpen=false;
$('#sidebar').css('margin-left', '-300px');
$('#sidebar .arrow').addClass('dir-two');
$('#sidebar .arrow').removeClass('dir-one');
$('#content').css('padding-left', '300px');
}
$( document ).click(function( event ) {
var target = $( event.target );
if(sideBarOpen){
closeSideBar();
} else {
if(target.is( '#sidebar' )){
openSideBar();
}
}
});
This will close it if the user clicks anywhere, but open it, if the user clicks the sidebar
UPDATE
If you want to also be able to click on the stuff inside the sidebar
Just give them a class, and add to the target.is check.
Example for links inside the bar
<a href='#' class='menuLinks'>Test Link</a>
Then your click handler
if(target.is( '#sidebar' ) || target.is('.menuLinks')){
openSideBar();
} else {
if(sideBarOpen){
closeSideBar();
}
Just detect clicks on an element that encompasses the page. And prevent clicks on the sidebar from bubbling up to that element.
$("body").click(function () {
toggleSidebar();
});
$("#sidebar").click(function (e) {
e.stopPropagation();
});

Adding and removing click/hover event handlers jQuery

Run into issues mixing click and hover events.
Clicking an inactive li a element toggles an active class and binds a hover event.
Hovering over now active element displays a previously hidden block (span.rate)
Clicking the hovered element is supposed to hide it, remove hover event and toggle the active class on the parent so it is no longer 'active'.
Clicking the hovered event does not remove the events and toggle active. There is some other logic in there regarding mutually exclusive options, this all works fine though.
jsfiddle of how it all sits together:
http://jsfiddle.net/65yY3/15/
Current js:
ps = {
psToggle: 0,
init: function () {
$(document).ready(function () {
$('.example li a)').on('click', function(e) {
e.preventDefault();
var that = $(this);
if (that.parent().hasClass('paired')) {
if (rm.psToggle === 0) {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.psToggle = 1;
} else {
if (that.hasClass('active')) {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.psToggle = 0;
} else {
$('.paired a').toggleClass('active');
that.find('.rate').fadeToggle(50);
//Call message function
}
}
rm.pControl();
} else {
that.toggleClass('active');
that.find('.rate').fadeToggle(50);
rm.pControl();
}
});
});
},
pControl: function () {
//Unbind events to all control items excluding 1st item.
$('.example li a').off('hover');
$('.example li a .rate').off('click');
$('.example .active').each(function(i) {
$(this).on('hover', function() {
$(this).find('.rate').fadeToggle(50);
});
});
$('.example li a.active .rate').on('click', function() {
//Remove hover/hide and toggle active state
$(this).off('hover');
$(this).hide();
$(this).parent().toggleClass('active');
rm.pControl(); //rebind new active classes
});
}
};
ps.init();
Check the below demos.
Both the click events were getting fired as ,.rate is the child of a.
$('.example li a.active .rate').on('click'... and
$('.example li a').on('click'...
So you can either remove the click on .rate. Demo1
Or add e.stopPropagation(); to the child to stop event bubbling from parent to child. Demo2
$('.example li a.active .rate').on('click', function(e) {
e.stopPropagation();
//Remove hover/hide and toggle active state
$(this).off('hover');
$(this).hide();
$(this).parent().toggleClass('active');
ps.pControl(); //rebind new active classes
});
enter link description hereCorrect
$('.example li a') instead of $('.example li a)')
update here is the link

jQuery: Clicking anywhere to remove class, without using $('body').on('click'

I want to remove all active classes when clicking anywhere on the screen, but if a clicked element has the .dropdown class, I would also want to toggle the .active class into that element.
// remove all .active classes when clicked anywhere
hide = true;
$('body').on("click", function () {
if (hide) $('.dropdown').removeClass('active');
hide = true;
});
// add and remove .active
$('body').on('click', '.dropdown', function () {
var self = $(this);
if (self.hasClass('active')) {
$('.dropdown').removeClass('active');
return false;
}
$('.dropdown').removeClass('active');
self.toggleClass('active');
hide = false;
});
I have this working with the above but I'm worried capturing a body click is overkill, and unnecessary. Is there a better solution?
jsiddle - I've set several li's to the .active class, if you click around you will see they get removed. Clicking an li will trigger toggleClass('active'), whilst still removing all .active classes.
you could try doing:
$('body').on("click", function (ev) {
if( $(ev.target).hasClass('.dropdown') ) {
//you clicked on .dropdown element, do something
}
else {
//you clicked somewhere other than dropdown element
}
});

Categories

Resources