How do I stop a event propagation? - javascript

I understand I need to use the stopPropigation, but how do I get a reference to the event from an onClick function. And Also how do I find out how an event was attached to the element. So I have a simple button like this:
<button class="btn btn-default" onclick="addRoleToReportClicked()">
the function looks like this:
function addRoleToReportClicked() {
$('#addRoleDiv').show();
}
So Simple. And was working fine. Unitl I just did an update of code from work. Now it does show the div, but then proceeds to do other stuff, namely re-load the whole page.
I am using firefox and I see that the button now has a "bubbling" and "DOM0" event handlers. I would love to know how that got there, but more importantly 2 questions:
How do I stop this in the addRoleToReportClicked() function? (I assume that I can stopPropogation, but how do I get a handle to the event?
Is there any easy way to find what code is adding these event listeners? I tried the debug, but that did not show me anything. I don't want to go through 20+ js files and thousands of lines of code to find it. But I do want to hunt down the developer and shoot him.
UPDATE
I tried this:
$("#addRoleDivButton").unbind("click").on("click", function(e){
e.cancelBubble = true;
e.stopPropagation();
e.bubbles = false;
$('#addRoleDiv').show();
});
None of it worked. Taking the idea of a form submition, I noticed that all the other buttons on the page were working fine, but this one was inside a from. So I changed the tag from a "button" to an "a" and it works fine. Someone attached a submit() to every button inside a form tag. How do I stop a submit?

There are a bunch of ways you can stop bubbling, the most popular two ways are -
stop the propagation -
function addRoleToReportClicked(e) {
e.stopPropagation();
$('#addRoleDiv').show();
}
or, unbind the other handlers -
<button class="btn btn-default btn-1">
$(".btn-1").unbind("click").on("click", function(){
$('#addRoleDiv').show();
});

Since you haven't accepted any of the above answers, I'll add this here.
function addRoleToReportClicked(event) {
$('#addRoleDiv').show();
return false;
}
By adding the return false;, it should stop any other functions running. If this or any of the other solutions don't work then there must be something else refreshing the page.
Try and debug it yourself using the chrome or firefox debuggers.

1) the event is passed as argument to the callback function
function addRoleToReportClicked(event) {
event.stopPropagation();
$('#addRoleDiv').show();
}
stopPropagation() will prevent the event from trigger callbacks on parent elements.
You may want to use stopImmediatePropagation() in some cases: I leave to you to look for the difference
jquery: stopPropagation vs stopImmediatePropagation
Note that you may also/instead want to prevent the browser to execute its default actions: (for example a click on a link would also open the link, a click on a submit button would send the form).
In that case you have event.preventDefafult()
EDIT:
Note that if addRoleToReportClicked is invoked because you have
<button class="btn btn-default" onclick="addRoleToReportClicked()">
Then the event object is not passed to the function
You may remove the onclick attribute.
Then if you need to catch the click on the button use Jquery's on('click')
2) Google Chrome (Dev Tools) tells you what event listeners are attached to an element (just right-click and inspect the element).
AFAIK it doesn't tell you where on the code the event listener were set up.
But if you perform a global search on your sources for the name of the event listener you should find it.

Related

jQuery click firing multiple times

Update:
Seems like the problem has nothing to do with my code. I've been running the webpage over browser-sync and that's where the problem appears. When I open the static webpage in Chrome directly, everything seems to be working fine. Thank you to everyone for your help!
I'm working on my personal website and want to make a way to filter through my list of projects using buttons.
<div class="filters">
<button class="btn btn-filter">Android</button>
<button class="btn btn-filter">iOS</button>
<button class="btn btn-filter">Web Dev</button>
<button class="btn btn-filter">Data Science</button>
</div>
I'm trying to attach event listeners to the buttons by doing this, but it seems like the event listeners are being attached multiple times:
$(".btn-filter").each(function() {
console.log(this); // #1
$(this).click(function(e) {
e.preventDefault();
e.stopPropagation();
console.log(this); // #2
})
debugger;
})
I have also tried using the class selector. It doesn't work, I switched to .each() and $(this) to be sure the elements were being assigned event handlers only once.
$('.btn-filter').click(...)
Logs show that each button is selected once to be assigned a click listener, but when I actually click the buttons, only some fire once, and some fire 3 times. I use some because it doesn't always behave the same way each time the page is run.
I have tried the solutions described in
this post(off(), unbind(), stopPropagation()), but none have worked.
Using Google Chrome's debugger tools, it seems like at the breakpoint, this refers to the HTML element twice for every iteration of each, despite some clicks firing once and some three times.
I suppose I could just assign IDs and wire each button individually, but I want to know what I'm doing wrong here. Could anyone explain?
You are running a for each loop on the class, so it will create a new event handler for each element with the class. If you want just one event handler you need to write it like this:
$(".btn-filter").click(function() {
console.log($(this).text());
});
Buttons that show or hide specific content are best described with a data value or id
Edit: after learning you had this before I will add that nothing you supplied is causing the error you are receiving.
The problem with your code is is here
$(".btn-filter")**.each**(function() {
You should simplify it by simply doing something like this
$(".btn-filter").click(function(e) {
e.preventDefault();
e.stopPropagation();
console.log(e);
debugger;
})
Since you are already selecting via the class name $(".btn-filter") the function should be added to all the elements.
Call click event using class and get clicked value using .html()
$(document).ready(function () {
$(".btn-filter").click(function() {
alert($(this).html());
})
});
JSFiddler

Triggering button click in jQuery not working

Using dot.js I'm adding a button to a specific web page that, when clicked, should add some text to a text field and then trigger another button to also be clicked. I simulate this by adding a click handler to my button which has this code:
var button = $('.some-class').find('button')[0];
console.log(button); // element I expect
button.click();
However, this doesn't work and I'm not sure why. If instead of .click() I perform .remove(), the button is removed from the page. If I use the console to execute the same code, the button does get clicked. This tells me I do have the right element, but there is something wrong with the click() event specifically.
Can someone explain why this isn't working in either Safari or Chrome? I've tried a lot of different things, but I'm new to jQuery so I'm probably missing some detail in how that works.
We went to the bottom of this in the chat. What probably caused the problem was another event-handler attached to (possibly) body, that undid the click.
So the solution was to stop the event from propagating:
event.stopPropagation();
While assigning the click event handler to the button you should use jquery on
This should ensure that whenever a new button with added with same selector (as in when event was assigned), event handled will be assigned to that button
Some examples here
The problem is the click() function is from jquery and you're attempting to fire the click function from the DOM object.
Try
$(button).click();
Here's a plunk.
http://plnkr.co/edit/2pcgVt
You can use the following statement.
var button = $('.some-class').find('button')[0].trigger('click');
try jquery's trigger() function:
$(button).trigger('click');
see jsfiddle: https://jsfiddle.net/665hjqwk/

preventdefault not preventing when its inside button

I could not make preventdefault to prevent action. I apologize if the answer is too easy but I simply cant find the error. why is it not preventing from entering the link? jsfiddle given below.
http://jsfiddle.net/zwY5p/34/
$('#theForm').click(function(e) {
event.preventDefault();
alert('FORM!');
});
e != event
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
The parameter passed to the handler function is what you need to execute preventDefault on. In your code, you are passing e but calling preventDefault on event.
preventDefault prevents the default browser action. It does not cancel the inline JavaScript, since that runs first. If you have to override that, just remove it (no event listener necessary):
$('#theForm').removeAttr('onclick').
your event parameter name e and the variable you are using event are different,
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
Other than the errors pointed out on other answers there's another small issue, specifically in your markup declaration:
<!-- Use either the closing tag or the slash (/) in the opening tag -->
<button id="theForm" onclick="location.href='http://www.example.com'" />
go to google
</button>
On the topic, you have two different handlers attached to the button element, they are both handling the click event but they are still different and separate things. jQuery won't know about the handler defined in the markup:
var btn = document.getElementById('theForm');
jQuery._data( btn, "events" );
will return an array with a single element which is the handler added via jQuery.
Now you have to re-evaluate the need of two different handlers for the same element and event and apply conditions. Do you really need to do it this way?
You're using 2 'click' events.
You end up using preventDefault once, and it's used after the 1st click event has ran.
If you make your button an href, then your preventDefault will be working.
It will also make more sense, as the JS will be separated from the HTML markup.
Also, of course you must use the same parameter name. (function(event), with event.preventDefault for example).
If you are passing "e" as an event to the function then you should prevent the default action only for that "e" that you have passed and not for "event".
$('#theForm').click(function(e) {
e.preventDefault();
alert('FORM!');
});
jQuery preventDefault() method: http://api.jquery.com/event.preventDefault/

How do I debug why handler for "click" JavaScript event doesn't get called?

I've installed a handler for the click JavaScript event of a <button> element using the jQuery API, but the handler doesn't get called when the button is in fact clicked. How can I debug why the event handler isn't invoked? I'm developing in Visual Studio 2010 and debugging with the help of Google Chrome Developer Tools.
I'm new to JavaScript and don't know the debugging methods :)
EDIT
This is the HTML declaration of the button in question:
<button id="start-lint">Submit</button>
The relevant JavaScript:
$('button').button();
var btn = $("button#start-lint");
log.debug("Button: %s", btn);
btn.click(function () {
log.debug("Button clicked");
});
Let me know if more information is needed.
EDIT 2
Somehow I got it working, not sure what was wrong in the first place, but at least now I know how to tell if an element was found or not!
You can only debug if the code is actually fired, which it seems to not be.
You could try to see if its even finding the selector using length.
alert($("#myselector").length);
or
console.log($("#myselector").length);
For debugging javascript i recommend you to use FIREBUG for Firefox (http://getfirebug.com/) - you can set breakpoints, write to console etc, and it gives all possible displays of variables, objects etc.
Tutorial can be found here: http://www.youtube.com/watch?v=2xxfvuZFHsM
(You said you where new to jQuery/Javascript, so hope it helped :D)
Inline JavaScript is executed as the page loads, so if the button is defined after the JavaScript the code won't find it and so can't attach the handler. You need to put that JavaScript in the document ready (or onload) function, which means it will be executed after the button (and everything else on the page) has loaded, and/or put it after the button in the source.
I'm guessing that the $('button').button(); throws an exception, and the rest of your code isn't executed. Comment out that line and see if it works.
Original reply:
Paste your code, or the relevant parts of it.
Add a debugger; statement to your handler function to see if you are entering it.
If not, then there is a problem with how you're registering the handler.
If you are entering it, maybe there is a problem with the handler itself.
your button may look like this
<input type="button" value="Click" />
for this you bind a click handler like
$(document).ready(function(){
$("input[type='button']").click(function(e){
alert("somebody clicked a button");
});
});
http://jsfiddle.net/6gCRF/5/
but the drawback of this approach is it will get called for every button click, to prevent that you might want to add an id to your button and select that specific button e.g.
<input type="button" value="Click" id="specific" />
attach a click handler to it like
$(document).ready(function(){
$("#specific").click(function(){
alert("specific button clicked");
});
});
http://jsfiddle.net/6gCRF/4/
EDIT
in your case select the button by id
$(document).ready(function(){
$("#start-lint").clcik(function(){
console.log("clicked");
});
});
you can also use the pseudo :button selector
$(document).ready(function(){
$(":button").click(function(e){
console.log("clicked");
});
});
have a look at jquery selectors

jQuery / JavaScript Bubbling and stopPropagation doesn't work

I'm making an edit button which pops up a modal box with a form to edit it. jQuery then sends this form to my server and I get a JSON response back. However, due to my bubbling issue, if I click on, for example, all of the edit buttons and then click on the last one and change a field, it does it across all of them.
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
and then the submit event:
function modal_submit(the_id){
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
}
finally all of this is inside of a getScript:
$.getScript('js/edit.js',function(){
create_edit_btn();
});
I've only used this 1 other time, and it worked, but I also had to do this.event.stopPropagation, but if I do "this" now it says this.event is undefined, but like I said, this exact code worked before for another script I did.
Does anyone have any ideas? :\
EDIT:
the html is:
<li>
<input id="item1" type="checkbox" value="webhosting|15" title="Web Hosting">
<p>Hosting for your web site</p>
</li>
An event can have multiple event listeners. Each time you use $(element).submit(whateverFunction) you are adding another whateverFunction to the submit event. If you only want only the last listener to be the action that is taken upon envoking the event, try doing this:
function modal_submit(the_id){
$('#modal form').unbind(); // this will remove all other event listeners from this element
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
I think you event.stoppropagation does its job already. It stopped all the bubbling on the click event of the button (ie, if you try checking the document body, it won't have mouse click event anymore). The reason why codes within submit of the form is still executed, is because this is called by the button's default action.
Together with event.stoppropagation(), I suggest you include this:
event.preventDefault();
So that the default action will not used and only the codes within your handler is executed.
Is this in the function that creates edit buttons?
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
If it this, then it will add this handler multiple times to the same elements, causing a flurry of alerts. Use live, which will place the handler on every matched element, even if is is added later in execution.

Categories

Resources