This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 8 years ago.
So I have a bunch of game pieces that I want to be clickable. If I add a click function to a button I get the desired result, but when I add it to the game piece class, it fails to work.
Here is an example that works fine on jsfiddle, but not when I use it in my script:
http://jsfiddle.net/sLt7C/
Here is what I want to do on my page:
$('.gamePiece').click(function(){
$('.gamePiece').addClass("toggled");
});
This doesn't work, but if I switch the identifier to a button on the page it does work:
$('#btn_AddClass').click(function(){
$('.gamePiece').addClass("toggled");
});
What could be causing this to fail?
Not sure if this has any impact on what could be causing it to fail, but the "game pieces" are span elements that are generated after clicking a "New Game" button.
Here is a fiddle showing more code http://jsfiddle.net/sLt7C/4/
For further clarification:
This doesnt work
$('.gamePeice').click(function(){
$(this).addClass("toggled");
});
This works
$('#btn_addClass').click(function(){
$('.gamePeice').addClass("toggled");
});
If the game pieces are added after the page load (i.e. by clicking a button) you need to use event delegation by using jquery .on()
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
$(myContainer).on('click', '.gamePiece', function(){
$(this).addClass("toggled");
});
I think you want this:
$(document).ready(function() {
$(document).on('click', '.gamePeice', function(){
$(this).addClass("toggled");
});
});
instead of
$('.gamePeice').click(function(){
$(this).addClass("toggled");
});
$('#btn_addClass').click(function(){
$('.gamePeice').addClass("toggled");
});
just prove http://jsfiddle.net/aras7/sLt7C/7/
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I create a span using PHP like this.
if ($subnetkey == 1 ) { echo ("<span class='subnetkey'>S/N of: $subnetnum</span> ");}
It works, and shows the correct data on screen. Additionally if I look at it using 'Inspect Element' its properly formatted.
<span class="subnetkey">S/N of: 780</span>
I have this script at the top of the page. I've also tried it at the bottom.
<script>
$(document).ready(function(){
$(".subnetkey").click(function() {
alert("subnet click mode");
});
});
</script>
When I click the span, nothing happens. I get no errors, and of course I don't see the alert fire.
It seems like this is a timing issue between building the page dynamically and using the page. But in case thats not it, what can I do to make the function fire?
JQuery Event Methods like click(), dblclick(), mouseenter() etc. work only for elements already created when DOM is rendered. For dynamically created elements you use on() method with the below syntax (see previous post):
$(staticAncestors).on(eventName, dynamicChild, function() {});
Since it is a dynamically created element your code won't work. Try:
$(document).on('click', '.subnetkey', function() {
alert("subnet click mode");
});
jQuery is only aware of the elements in the page at the time it runs, so new elements added to the DOM are unrecognized by jQuery. To combat the problem use event delegation, bubbling events from newly added items up to a point in the DOM which was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go all the way up the DOM tree. Ideally you should delegate to the nearest parent existing at the time of page load.
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.
This question already has answers here:
jQuery onclick all images in body
(3 answers)
Closed 5 years ago.
Is it possible to write a JQUERY event that if any image is clicked on, a message box gets displayed. Or does every image have to have its own event to activate. I know how to specific images but is it possible to have one JQUERY for all images?
Use generic html tag in jquery selector, like:
$("img").click(function() {
//DoForAllImgs();
});
Yes.you can trigger by tag name like
$('img').on('click',function(){
alert($(this).attr('src'));
//alert('any one image clicked');
});
You can use event delegation thus event will be added to one element and delegated to decendent image children
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all descendants matching a
selector, whether those descendants exist now or are added in the
future.
$(document).on('click','img',function(){
//Your handler
});
Instead of document you may use any container inside which you want to delegate click event on image.
This technique will fire click event on dynamically add image also.
You can place a listener on the whole document and specify a selector, in this case 'img':
$(document).on('click', 'img', function (e) {
console.log('click');
});
This will make any current or future img that is inserted into the DOM clickable.
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 6 years ago.
This might be a dumb mistake but I have this code:
$('#delete-btn').on('click', function(){
return confirm('Are you sure you want to delete this?');
});
the alert does not occur but with this code it does:
$(document).on('click', '#delete-btn', function(){
return confirm('Are you sure you want to delete this?');
});
from what I understand they are the same thing, but the second tries to process the event every click on the page looking for the specified id. I tried putting it in a document ready block but that didn't help.
I don't understand why one works and the other does not.
Your first code will also work if the element you reference is part of the document at that time, so make sure to put the script near the end of the document, or else wrap it in the ready handler:
$(function () {
$('#delete-btn').on('click', function(){
return confirm('Are you sure you want to delete this?');
});
});
The second script ($(document).on('click' ...)) works, because the document is there from the start, so the handler is bound to it. At the time of the click, the event bubbles up to the document and the handler kicks in.
Dynamically created content
If your button is not in the document when the page loads, but is generated dynamically, the above code might still look for the button to soon. You mentioned django generates the button. It probably also captures an event when the document is ready, then queries the database, waits for its reply (in most cases this is asynchronous), and only then adds the button. If your code has already run by that time, it missed the button, and did not attach an event handler to it.
In that case, it is indeed a more solid solution to use the event delegation to the document level ($(document).on('click' ...)).
This question already has answers here:
jQuery click event not working after adding class
(7 answers)
Closed 7 years ago.
I have this button rendered after some text in an unordered list:
The button's HTML is like this:
<a
data-action="remove"
data-class-name="ECEC 301 Advanced Programming for Engineers Lab"
class="btn btn-danger remove-item btn-xs btn-font-12-px btn-raised margin-add-to-cart mdi-content-remove-circle-outline">
</a>
And this is the unordered list element it is within:
I am trying to write some jQuery that calls an action when the button is clicked, but no matter what I write, I just cannot register the click action, for example:
$('.btn.btn-danger.remove-item').on('click', function(){
console.log("you should see this");
});
$("[data-action]").click(function() {
console.log("yeah");
});
$('a[data-action="remove"]').click(function() {
console.log("yeah");
});
EDIT: The button is created dynamically AFTER page-load using jQuery (I call my JSON API to create the unordered list of classes)
Since button is generated dynamically you need to use event delegation
$(document).on('click','.btn.btn-danger.remove-item', function(){
console.log("you should see this");
});
Event delegation refers to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.
Taken from : http://learn.jquery.com/events/event-delegation/
The issue is that the element doesn't exist when the click handler is being added.
Basically, you are saying "hey jquery, find this element and do XYZ when it is clicked". jQuery looks for it, doesn't find anything (since the element has not been created yet), and since it is chill it doesn't say anything to you about it (it would be super annoying if it errored out all of the time).
The way around this is by using event delegation. What that means is that you attach the event to an element that will be there, and then jQuery filters every event sent to that parent element and checks to see if the event that triggered it happened to an element that matches the selector.
It may sound complicated, but it is straight forward. All you need to do is update
$(".btn.btn-danger.remove-item").on("click...
to this
$(document).on("click", ".btn.btn-danger.remove-item"...