This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 10 years ago.
My problem is rather hard to word. So I have created a jsfiddle.net of my issue.
I have a list of divs. Inside each div there is some text and an "X". The "X" is to delete the parent div. The three divs and "X" works fine. But if I were to add a button that appends a new div to the list, then those "X"'s don't work. Any idea what this problem is? I know this is probably some basic JS DOM thing. But I'm self thought and just don't understand JS very well to resolve this issue.
Please and thank you for your time.
http://jsfiddle.net/JLxKJ/
$("#trigger").click(function() {
$("#participants_wrapper").append("<div class='participant'><a href='javascript:void(0)' class='delete_participant'>X</a>Appended</div>");
return false;
});
$(".delete_participant").click(function(){
$(this).closest('div').remove();
});
<div id="participants_wrapper">
<div class="participant">Xalready here</div>
<div class="participant">Xalready here</div>
<div class="participant">Xalready here</div>
</div>
add this participant
You need to delegate the event to closest existing parent in the dom:
$("#participants_wrapper").on("click", ".delete_participant", function(){
$(this).closest('div').remove();
});
This is because jQuery can't put the click event on the element, as it doesn't exist on page load, so this puts the event on the parent, but affects the children
because you are not binding the events again to the new element.
You can use on() to get around that.
$("#participants_wrapper").on("click", ".delete_participant",
function(){
$(this).closest('div').remove();
}
);
For dynamically added elements, use jQuery's .on() function. Change your delete code to:
$("#participants_wrapper").on('click', '.delete_participant', function () {
$(this).closest('div').remove();
});
jsFiddle example
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 1 year ago.
I want to hide a div using JQuery on click event of another div. The problem is that the div that I want to hide is actually created only when I click on the existing div.
Let me explain with code example:
HTML:
<div class="first">I already exist and I create the second div when I am clicked</div>
<div class="second">I do not exist yet, I am created when first div is clicked</div>
The above is happening by another piece of code that another developer wrote.
I want to write another piece of code that will hide the second div when its created right after first div is clicked.
I do not have the permission to change the original dev's original code.
My JQuery that is not working:
$(".first").on("click",function() {
$(".second").hide();
});
You should use this, cause you have to make this delegate.
explanation: https://api.jquery.com/on/
$("body").on("click", ".first",function() {
$(".second").hide();
});
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
Let us say we are adding several elements to the dom. What is the best way to make sure these elements also have a click handler added to them? For example, if I have a click handler on all elements with the class "canvas-section", and I keep adding "canvas-section" elements, what is the best way to make sure in Jquery that these new "canvas-section" elements also have that click handler added.
Before I used to use the "live" jquery function or "on" but those don't seem to work for elements that are dynamically added or added after the original click listener is added.
You can bind the click handler to a parent object, including document, like this:
$(document).on('click', '.div-to-click', function() {
console.log('hi!');
});
See: https://api.jquery.com/on/
I made the following code to clarify the question:
Html:
<body>
<div class="static">This is a static div</div>
<button class="add-dynamic-button">Click me to add a new button</button>
</body>
Js:
$(function(){
$('.add-dynamic-button').on("click",function(){
$('body').append("<button class='dynamic-button'>Click me to add a dynamic div'</button>");
});
$('.dynamic-button').on('click',function(){
$('body').append("<div class='dynamic-div'>This is a dynamic div</div>");
});
});
And here is jsfiddle to test: http://jsfiddle.net/6ZN5J/
When I have the $('.dynamic-button').on('click') handler inside the first click handler, a .dynamic-div is added fine.
But when I place it outside the first click handler scope (as in the example above), nothing happens. I initially thought that $.on works on any DOM element that is not yet created, but now it turns out that it works on new elements of the same class or type if they are already in the DOM or when $.on is placed inside the function that creates those elements.
Can you clarify why this happens and whether there are any methods to allow for using event handlers on dynamically created elements outside the handler they were created with?
Thanks
$() is a selector. It finds the element(s) that were in the document or the parent element from which you're peforming the whole query at the time you did it.
If you want further buttons bound to click event you'll need to manually bind them:
$('body').append("<button class='dynamic-button'>Click me to add a dynamic div'</button>")
.on("click", ....);
so i implemented a bit of jQuery that basically toggles content via a slider that was activated by an <a> tag. now thinking about it id rather have the DIV thats holding the link be the link its self.
the jQuery that i am using is sitting in my head looks like this:
<script type="text/javascript">
function slideonlyone(thechosenone) {
$('.systems_detail').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).slideDown(200);
}
else {
$(this).slideUp(600);
}
});
}
</script>
i was using this as a index type box so there are several products when you click on the <a> tag that used to be an image* it would render a bit of content beneath it describing the products details:
<div class="system_box">
<h2>BEE Scorecard database</h2>
<p>________________</p>
</div>
the products details are wrapped in this div.
<div class="systems_detail" id="sms_box">
</div>
so when you click on what used to be a image* it would run the slideonlyone('div_id_name') function. the function above then first closes all the other divs with the class name 'system details' and then opens/slides the div with the id that was passed into the slideonlyone function. that way you can toggle products details and not have them all showing at once.
note i only kept the <a> tag to show you what was in there i will be getting rid of it.
note: i had an idea of just wrapping the whole div in an <a> tag but is that good practice?
So now what i am wondering is since you need JavaScript to run onclick on a div tag how do you write it so that it still runs my slideonlyone function?
Using obtrusive JavaScript (i.e. inline code) as in your example, you can attach the click event handler to the div element with the onclick attribute like so:
<div id="some-id" class="some-class" onclick="slideonlyone('sms_box');">
...
</div>
However, the best practice is unobtrusive JavaScript which you can easily achieve by using jQuery's on() method or its shorthand click(). For example:
$(document).ready( function() {
$('.some-class').on('click', slideonlyone('sms_box'));
// OR //
$('.some-class').click(slideonlyone('sms_box'));
});
Inside your handler function (e.g. slideonlyone() in this case) you can reference the element that triggered the event (e.g. the div in this case) with the $(this) object. For example, if you need its ID, you can access it with $(this).attr('id').
EDIT
After reading your comment to #fmsf below, I see you also need to dynamically reference the target element to be toggled. As #fmsf suggests, you can add this information to the div with a data-attribute like so:
<div id="some-id" class="some-class" data-target="sms_box">
...
</div>
To access the element's data-attribute you can use the attr() method as in #fmsf's example, but the best practice is to use jQuery's data() method like so:
function slideonlyone() {
var trigger_id = $(this).attr('id'); // This would be 'some-id' in our example
var target_id = $(this).data('target'); // This would be 'sms_box'
...
}
Note how data-target is accessed with data('target'), without the data- prefix. Using data-attributes you can attach all sorts of information to an element and jQuery would automatically add them to the element's data object.
Why do you need to attach it to the HTML? Just bind the function with hover
$("div.system_box").hover(function(){ mousin },
function() { mouseout });
If you do insist to have JS references inside the html, which is usualy a bad idea you can use:
onmouseover="yourJavaScriptCode()"
after topic edit:
<div class="system_box" data-target="sms_box">
...
$("div.system_box").click(function(){ slideonlyone($(this).attr("data-target")); });
You can bind the mouseenter and mouseleave events and jQuery will emulate those where they are not native.
$("div.system_box").on('mouseenter', function(){
//enter
})
.on('mouseleave', function(){
//leave
});
fiddle
note: do not use hover as that is deprecated
There's several things you can improve upon here. To start, there's no reason to use an <a> (anchor) tag since you don't have a link.
Every element can be bound to click and hover events... divs, spans, labels, inputs, etc.
I can't really identify what it is you're trying to do, though. You're mixing the goal with your own implementation and, from what I've seen so far, you're not really sure how to do it. Could you better illustrate what it is you're trying to accomplish?
== EDIT ==
The requirements are still very vague. I've implemented a very quick version of what I'm imagining you're saying ... or something close that illustrates how you might be able to do it. Left me know if I'm on the right track.
http://jsfiddle.net/THEtheChad/j9Ump/
I have the following simple code, where I double click a div (with class container) and it's simply clones itself inside another div (with id containment-wrapper):
html
<span class="container">div one</span>
<div id="containment-wrapper">
</div>
Jquery
$(".container").dblclick(function() {
$(this).clone().appendTo('#containment-wrapper');
});
When I double click the original div, it clones itself and puts a div inside the containment-wrapper but when I double click a cloned div, it doesn't do anything even though it has class=container, why is this happening? I tried many different ways to clone it but nothing worked.
It's because the event handler isn't cloned. Use delegate instead:
$(".container").delegate("","dblclick",function() {
$(this).clone().appendTo('#containment-wrapper');
});
Because dblclick is not bounded to the new div. What you want to achieve can be easily done with live
$(".container").live('dblclick', function() {
$(this).clone().appendTo('#containment-wrapper');
});
Since you're dynamically adding div tags they aren't automatically bound to the .dblclick function you've specified. Using a live event handler is one way to solve this.