Reputation: 1778
Code:
scope.offCanvasShow = function ($event) {
$('.app-off-canvas-menu').toggleClass('show');
// Prevents default functionality of a element
// In this instance, this prevents the anchor from reloading the page on click.
$event.preventDefault();
$event.stopPropagation();
$(document).one('touchstart click', offCanvasHandler);
/**
* Checks to see if the event target isn't .off-canvas-menu or has off-canvas-menu as a parent then removes the
* show class.
* @param event - is the event of the function
*/
function offCanvasHandler(event) {
console.log('hello');
if (!$(event.target).closest('.app-off-canvas-menu').length) {
$('.app-off-canvas-menu').removeClass('show');
$(document).off('touchstart click', offCanvasHandler);
} else {
$(document).one('touchstart click', offCanvasHandler);
}
}
};
This is a simple off canvas drop down menu. I have this odd problem of bubbling. That I thought I fixed with the .one()
function.
If you click on the class app-off-canvas-menu a few times and then leave the menu open and click outside of the menu the menu closes which is what I want.
Here is the but, once I clicked outside of the menu it seems that the console log gets run multiple times depending on how many times I've clicked the app-off-canvas-menu hamburger.
Can anyone see anything clearly obvious with my code?
Its worth noting that I am using angular so it might be possible I have to go about this in a different fashion.
Upvotes: 2
Views: 405
Reputation: 5605
If you click on the class app-off-canvas-menu a few times and then leave the menu open and click outside of the menu the menu closes which is what I want.
Every time you click on the class you will bind another handler:
$(document).one('touchstart click', offCanvasHandler);
so when you click outside the element it will execute all those handlers.
From the jQuery website:
The
.one()
method is identical to.on()
, except that the handler is unbound after its first invocation.
So you don't bind it once, it only runs once. This might have caused the confusion.
Update with code:
var isBound = false;
scope.offCanvasShow = function ($event) {
$('.app-off-canvas-menu').toggleClass('show');
// Prevents default functionality of a element
// In this instance, this prevents the anchor from reloading the page on click.
$event.preventDefault();
$event.stopPropagation();
if(!isBound) {
$(document).one('touchstart click', offCanvasHandler);
isBound = true;
}
/**
* Checks to see if the event target isn't .off-canvas-menu or has off-canvas-menu as a parent then removes the
* show class.
* @param event - is the event of the function
*/
function offCanvasHandler(event) {
console.log('hello');
if (!$(event.target).closest('.app-off-canvas-menu').length) {
$('.app-off-canvas-menu').removeClass('show');
$(document).off('touchstart click', offCanvasHandler);
} else {
$(document).one('touchstart click', offCanvasHandler);
}
}
};
Upvotes: 2