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
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 5 years ago.
This code below is very simple but for some reason it dosent work.
I want a simple function to toggle elements that will active different functions each one. When you click on the first element it changes his class for the second element, when you click on a second element it does other things.
The toggle works well (No JS errors) but I dont know why jQuery do not trigger a click on a class that was added with javascript. I tested too with "addClass" and "removeClass" and got the same result.
I already created a replacement for this (using a if with jquery function "hasclass" to switch behavior when you click on the element). I also understand that I may use other functions with count and all... That would not work for what I wanted but this is not the point...
I just wanted to know why it dosent work because its a common solution that I am sure that I will use again. The code is so simple that I am wondering if I dindt miss something obvious.
Here is fiddle: https://jsfiddle.net/mhbubh8p/17/
HTML:
<div class="toggle aaa">No click so far</div>
Jquery
$(document).ready(function () {
$('.aaa').click(function() {
$('.toggle').toggleClass('aaa zzz');
$('.toggle').html('Class was toggled');
});
$('.zzz').click(function() {
alert("This should work...it dosent... why?");
});
});
It's just a case of event delegation:
$(document).ready(function() {
$('.aaa').click(function() {
$('.toggle').toggleClass('aaa zzz');
$('.toggle').html('Class was toggled');
});
$(document).click('.zzz', function() {
alert("This should work");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle aaa">
No click so far
</div>
Since your element with the zzz class does not exist when you bind the click event to it, the listener never gets created. One fix is to bind to the document and check for your element inside of the listener.
Another fix would be to create the listener when the zzz element is created, like so:
$(document).ready(function() {
$('.aaa').click(function() {
$('.toggle').toggleClass('aaa zzz');
$('.zzz').off().click(function() {
alert("This should work");
});
$('.toggle').html('Class was toggled');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle aaa">
No click so far
</div>
One advantage to this approach is that the click listener will show up in your dev tools when inspecting the element (without having to have Ancestors checked). I find this makes debugging a bit easier, but it also requires you to remove all previous listeners with .off(), otherwise you can get duplicate bindings, which no one wants.
So, i have this code snippet that opens a modal:
<button id="trigger-overlay" class="order">Open Overlay</button>
Now, i wanted to include it in Wordpress menu, but i cant add button tag there, so i added:
Open Overlay
And i am using jquery to add a ID to that link, like this:
$('.order').attr('id','trigger-overlay');
ID is added, but link doesnt open anything, aka, it links to "#" instead of opening a modal...
How could i fix this to make it work?
Thanks!
This thing may causing due to events binging order. So, your code $('.order').attr('id','trigger-overlay'); is executing right after click's binding event (I think that event looks like this one: $('#trigger-overlay').click(function() { ... });.
If you have ability to change that binding, please use jquery.on method: http://api.jquery.com/on/
So that code will looks like: $(document).on('click', '#trigger-overlay', function() { ... });.
Also you can just move $('.order').attr('id','trigger-overlay'); above the script with that event binding.
Based on your
<button id="trigger-overlay" class="order>Open Overlay</button>
I'm not sure how you got a modal to trigger, since it is not connected to an event handler like:
<button onclick="turnOverlayOn()">Demo Button</button>
In this case, there would be a function that targets the overlay/modal and turns its CSS display property from none to block or inline-block (however you would like to display it):
var turnOverlayOn = function () {
$('targetOverlayId').css('display','block')
}
I suggest focusing on attaching an onClick event that triggers a function that does what you want to make the overlay appear.
The function used to turn the overlay off could be:
var turnOverlayOff = function () {
$('targetOverlayId').css('display','none')
}
You could attach this to a different anchor tag or button to turn the overlay off.
Note: the event should work the same for an anchor tag as it does for a button.
In my understanding you want to trigger the button click event. Using the a tag with class order.
try
jQuery(document).on('click','.order',function(){
jQuery('#trigger-overlay').click();
});
You can trigger the click event using jquery. Since I have no knowledge of your DOM structure jQuery(document).on('click','.order',function().. will work even if your elements are dynamic (added to the DOM after the script execution) because the click event is bind to the document.
NOTE:
When using wordpress always use jQuery instead of $ to avoid conflicts.
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.
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
I have a question. I have 8 buttons that have unique incrementing id's and a shared class.
<button class="btnChapter" id="btnChapter_1" value="1">1</button>
<button class="btnChapter" id="btnChapter_2" value="2">2</button>
<button class="btnChapter" id="btnChapter_3" value="3">3</button>
...
In order to prevent me from duplicating code, I bound a click event to the btnChapter class instead of binding an event individually to each button's ID.
$('.btnChapter').click(function(){ .. do stuff .. });
How do I trigger() the click() event only for #btnChapter_2? The following doesn't seem to work.
$('#btnChapter_2').click()
Your code is perfectly fine.
The only thing that you could possibly be doing wrong in my opinion is not executing this code after the ready event.
I'd also suggest the use of live.
Try this:
$(function() {
$('.btnChapter').live('click', function(){
//blah
});
//...
$('#btnChapter_2').click();
});
Your code seems to be fine. Can you check whether the click event is actually binded to the button controls.
One reason I can think of is the code is the javascript is executed before the dom is ready, so the $('.btnChapter') selector may not return any element.
Can you check what is the value returned by $('.btnChapter').length soon after the click event is binded.
Note: Can you manually click on the buttons and check whether the event is fired?
Here is a sample I did in JSFIDDLE, it works fine for me.