I have some lis including a links as below
<li>
<span>SomeText</span>
<a href='someurl' class='entityDetailModal'>sometext</a>
</li>
I am using a third party library ('LightGallery') that adds click event on Li, and by Jquery I have add click event to the links to show a dialog.
The problem is when I click on link both click event will be fired,
my click event handler is
$('body').on("click", 'a.entityDetailModal', function (event) {
event.preventDefault();
event.stopPropagation();
loadDialog(this, event, '#mainContainer', true, true, false);
return false;
});
I tried event.stopPropagation() and event.preventDefault(); and return false; in link onclick event handler but they don't work.
Sample:http://jsfiddle.net/HuKab/30/
How can I overcome this?
Update
It seems the problem is the way I add click event handler,
using this way it seems that everything is ok
$('a.entityDetailModal').click(function (event) {
event.preventDefault();
event.stopPropagation();
loadDialog(this, event, '#mainContainer', true, true, false);
return false;
});
Update 2
Thanks #Huangism, this post stackoverflow.com/questions/16492254/pros-and-cons-of-using-e-stoppropagation-to-prevent-event-bubbling is explaining the reason.
Use stopPropagation(); in child element
$("li").click(function (e) {
alert("li");
});
$("a").click(function (e) {
e.preventDefault(); // stop the default action if u need
e.stopPropagation();
alert("a");
});
DEMO
It is not very clear to me what your problem really is. If you simply want to get rid of the click on the li tag you may use .unbind() from jQuery (see: http://api.jquery.com/unbind/). You should end up with only your click event.
Another thing that might help is to use something like:
$("a").on('click.myContext', function(event) {
//Your action goes here
}
This way you can have parallel events and turn them on with $("a").on('click.myContext') and off with $("a").off('click.myContext')
Edit: Use:
$("a").on('click.myContext',function (e) {
e.stopPropagation();
alert("a");
});
see working example: http://jsfiddle.net/bGBLz/4/
Related
I have made a side nav bar on toggled and by clicking on any point away from the navbar buttons navbar collapse and buttons not working on clicking on it
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
$(document).click(function (e) {
if ($('#wrapper').hasClass('toggled')) {
$("#body").click(function (e) {
e.preventDefault();
$("#wrapper").removeClass("toggled");
});
}
});
Don't bind a click event after a click event.
I don't see the use of the $(document).click(function(e){ })
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
$("#body").click(function (e) {
e.preventDefault();
if ($('#wrapper').hasClass('toggled'))
$("#wrapper").removeClass("toggled");
});
And maybe remove the # on the $('#body') if it needs to be on the <body> tag and the <body> tag has no id. Because the # is an id selector.
Actually you are overriding the click event handler on your $("#menu-toggle") element, you defined in:
$("#menu-toggle").click(function (e) {
By attaching a click event to the document in line:
$(document).click(function (e) {
Because document is the global element in the page and all other elements are inside of it, so by attaching a click event handler to the document you are omitting all other click handlers on the page.
Edit:
Another issue in your code is that you are attaching a click event handler inside another click event handler:
$(document).click(function (e) {
if ($('#wrapper').hasClass('toggled')) {
$("#body").click(function (e) {
e.preventDefault();
$("#wrapper").removeClass("toggled");
});
}
});
This will attach the second handler, to the body element, each time the document is clicked, which is a very wrong approach because you are always attaching a new click event handler on click of document which will lead to bad performance in your appplication.
I am a javascript noob, so apologies if this question is not for this forum. I am trying to understand jQuery method:
e.preventDefault()
In the code below, when moving items form one list to another it is needed for us to be able to move the items. I would like to know what exactly is happening there and what default action are we preventing from happening?
$('#move').click(
function(e) {
$('#list1 > option:selected').appendTo('#list2');
e.preventDefault();
});
$('#moveAll').click(
function(e) {
$('#list1 > option').appendTo('#list2');
e.preventDefault();
});
$('#removeAll').click(
function(e) {
$('#list2 > option').appendTo('#list1');
e.preventDefault();
});
Well basically when you click hyperlink it posts back to url or #
When we add e.preventDefault() function, jQuery will prevent default action of click event.
Therefore when you click #move, page will not refresh but action within function will be executed.
Hope this helps!
It will prevent further default action for current event.
E.g. clicking on link will follow href of element. e.preventDefault(); will prevent following link and you will not be redirected.
More information here
$(document).ready(function() {
$('#a1').click(function(e) {
e.preventDefault();
alert('Clicked, but not following link.');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Link with preventDefault
<br/>
Link without preventDefault
First of all e.preventDefault() should be first line when defining what all things will happen in function.
$('#move').click(
function(e) {
e.preventDefault();
$('#list1 > option:selected').appendTo('#list2');
});
$('#moveAll').click(
function(e) {
e.preventDefault();
$('#list1 > option').appendTo('#list2');
});
$('#removeAll').click(
function(e) {
e.preventDefault();
$('#list2 > option').appendTo('#list1');
});
Secondly preventDefault prevents the default function of element to which it is applied.
For ex:
<a href="#" class="clickBtn">
If you fire event on above <a> by default it will take to document to top and will show a # in url and then fire you function but if you use preventDefault then its default function of linking will be prevented.
I have a link that looks like this:
<a href="page.html" class="myLink">
Link text
<div class="toggle">x</div>
</a>
When they click on the x in toggle I want to prevent the link from navigating, but if they do click on the Link Text I want the link to navigate.
I tried this:
$('.toggle').click(function(event) { $(this).parents('a').preventDefault(); });
But it didn't seem to work.
To stop propagation from the clicked element to the outer a, you'd have to call stopPropagation. But here you can simply return false ( which both stops propagation and prevents default behavior) :
$('.toggle').click(function(event) {
// do interesting things
return false
});
It is the event not the element that you need to fire the preventDefault() method upon.
$('.toggle').click(function (event) {
event.preventDefault();
});
This will stop the event from triggering but not propagating up the document.
$('.toggle').click(function (event) {
event.stopPropagation();
});
Is it's counterpart.
I am having trouble with multiple clicks being registered in jQuery when only one element has been clicked. I have read some other threads on Stack Overflow to try and work it out but I reckon it is the code I have written. The HTML code is not valid, but that is caused by some HTML 5 and the use of YouTube embed code. Nothing that affects the click.
The jQuery, triggered on document.ready
function setupHorzNav(portalWidth) {
$('.next, .prev').each(function() {
$(this).click(function(e) {
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
});
function initiateScroll(target) {
var position = $(target).offset();
$('html, body').animate({
scrollLeft: position.left
}, 500);
}
}
Example HTML
<nav class="prev-next">
Prev
Next
</nav>
In Firefox one click can log a "Click!" 16 times! Chrome only sees one, but both browsers have shown problems with the above code.
Have I written the code wrongly or is there a bug?
-- Some extra info ------------------------------------------
setupHorzNav is called by another function in my code. I have tested this and have confirmed it is only called once on initial load.
if ( portalWidth >= 1248 ) {
wrapperWidth = newWidth * 4;
setupHorzNav(newWidth);
}
else
{
wrapperWidth = '100%';
}
There are mutiple instances of nav 'prev-next'. All target different anchors. All are within the same html page.
<nav class="prev-next">
Prev
</nav>
Try unbinding the click event like this
$(this).unbind('click').click(function (e) {
});
You don't need .each() for binding event handlers. Try this instead:
$('.next, .prev').click(function(e){
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
EDIT:
I think it is the way you are attaching the event handler from within the setupHorzNav function that is causing it. Change it to attach it only once from say, $(document).ready() or something.
I have managed to get the situation of multiple event handlers by attaching the event handlers from a function that gets called from event handler. The effect is that the number of click event handlers keeps increasing geometrically with each click.
This is the code: (and the jsfiddle demo)
function setupNav() {
$('.next, .prev').each(function () {
$(this).click(function (e) {
setupNav();
var target = $(this).attr('href');
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
});
}
setupNav();
See how calling the setupNav() function from the click event handler adds multiple eventhandlers (and the click log message) on successive clicks
Since it is not clear from your question whether you are calling the binding function multiple times, a quick and dirty fix would be:
$('.next, .prev').unbind('click').click(function() {
...
});
What you are doing here is unbinding any previously bound event handlers for click and binding afresh.
Are there no other click bindings elsewhere?
Are you loading the page with ajax?
You could also try this:
$('.next, .prev').click(function (e) {
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
I've got the following code:
<div onclick="alert('div event');" style="cursor:pointer">
some text
click
</div>
When somebody clicks on the link the javaschipt event is triggered. I want that the event is only triggers if somebody clicks on the text or on the empty space inside the div container; and not if somebody clicks on the link.
Is it possible to call a function when the event is triggered, which checks on which elements the user has clicked. something link
onclick="foo(caller);"
and
function foo(element){
if(element!='link'){
alert('yes');
}
}
Add a click handler to your link and stop event bubbleing to the parent div. Like this:
$('#link').click(function(e) {
e.stopPropagation();
});
$(function (){
$('#link').click(function (e){ e.stopPropagation(); /*do other thing*/});
})
OnClick event you can pass the current object type.
something like
onclick=foo(this)
The function foo looks like
function foo(obj) {
if(obj.tagName != 'A') {
alert('Yes')
}
}
Use the unbind http://api.jquery.com/unbind/