Click event not triggered of dynamically added div - javascript

I have added a div dynamically into HTML,
When i have tried to trigger the click event of same element
what i have tried till yet is below ::
$(function(){
$("#id").bind("click",function(){
alert("hi");
})
});
i have also tried to use "on" instead of "bind" but it doesn't work.
but when i have write simple , it works fine
<div onclick="javascript:testFunction();"></div>

Delegate event using on(), you can give the static parent of element that is supposed to be added after execution of binding code.
$(function(){
$(document).on("click", "#id",function(){
alert("hi");
});
});
Delegated events
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers, reference.

Related

Need to get info from any element, which was clicked, but not from parent elements

Need to get info from any element, which was clicked.
Example:
<div>text1<section>text2</section></div>
and JS
$(function(){
$('body *').click(function(){
alert($(this).get(0).tagName.toLowerCase());
});
});
If I click text2, parent element throw alert too. I need only first alert from section. How I can block next alerts from all parent elements of section.
Use event.stopPropagation() to prevent the event from firing on the containing elements.
$(function(){
$('body *').click(function(e){
e.stopPropagation();
alert($(this).get(0).tagName.toLowerCase());
});
});
Just wanted to expand on Kooilnc answer - Using on with event delegation is another option.
Event delegation would be nice if you have an event listener bound before or after on a node that needs to listen to a click handler that has bubbled up. If you stopPropagation, this obviously would be an issue.
Here's a fiddle with a demo:
http://jsfiddle.net/ahgtLjbn/
Let's say a buddy of yours has bound an event listener to a node higher up in the DOM tree. He expects any events that bubble up to it, to be handled by his script.
Using event delegation, the event still bubbles up (so your buddies code will still fire), but it will only alert once (since we called e.stopPropagation).
Calling on without event delegation, or binding the event directly using click (which, under the hood, is just calling on) will prevent the event from bubbling, so your buddies code will never run.

jQuery remove function not working

I have a Div with a link remove when I click on the remove this Div removed.
JS FIDDLE
<div class="bar">
<p style="float:left"> Hello world</p>
remove
</div>
Here the div with Class .bar will remove when I click on the link remove which is working fine.
But I also created a link below the div(.bar) which is :
+ Add New
On clicking +Add New will create a new .bar div.
$('.add').click(function() {
$(".holder").prepend('<div class="bar"><p style="float:left"> Hello world</p> remove </div>');
});
But the Problem is when this new .bar div is created clicking on the remove not working. This new .bar div not remove.
why is that ? is there any other way to do this ? Any help will be much appreciated.
You need to use Event Delegation. You have to use .on() using delegated-events approach.
i.e.
$(document).on('event','selector',callback_function)
Example
$('.holder').on('click', '.delete', function() {
$(this).parent('.bar').remove();
});
In place of document you should use closest static container.
DEMO
The delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.
You should use event delegation:
$('.holder').on('click', '.delete', function() {
$(this).parent('.bar').remove();
});
Here .holder is the closest static parent element.
DEMO: http://jsfiddle.net/jnLfh/5/
You need event delegation for dynamically added elements which are not present in DOM at the time of execution of event binding code. You can delegate event to static parent of dynamic element, in the given example you can delegate it to .holder or document
Live Demo
$(".holder").on('click', '.delete', function() {
$(this).parent('.bar').remove();
});
Delegated events
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers, jQuery Doc
Change to this:
$(document).on('click', '.delete', function(e) {
e.preventDefault(); // stops the jump
also a note, if you want to delegate the event then you should always try to delegate to the closest static parent (Which was available at the time of doc ready), so here in your case is <div class='holder'> then you can change to this:
$('.holder').on('click', '.delete', function(e) {
e.preventDefault(); // stops the jump
but here one more thing for note if you are delegating to the closest static parent then you have to put this click event in your "document ready block".
The selector will not recognize the new div added by the script. For this you need to add event delegation. Here's an example
using "on"
$('.delete').on('click', function(){
$(this).parent('.bar').remove();
});
using "live" (might be depreciated now. Please check)
$('.delete').live('click', function(){
$(this).parent('.bar').remove();
});

adding more clickable elements to a page then .on() doesnt work

so i have some code in a page that is like this
<div id="main">
<div class='module' id ='test1'>1</div>
<div class='module' id ='test2'>2</div>
<div class='module' id ='test3'>3</div>
<div class='module' id ='test4'>4</div>
</div>
and a bit of js that has an event that is on the document.load
$('.module').on("click", function(){
if ($(this).hasClass('flipped')) {
$(this).toggleClass('flipped');
} else {
$('.module').removeClass('flipped');
$(this).toggleClass('flipped');
}
});
this works fine until an element is added dynamically so lets say i add
<div class='module' id ='test5'>5</div>
this is not going to be clickable because .on is not bound to this..
I have read posts here explaining that .on wont work... but i cannot find a solution..
can anyone help?
Delegate the events to the parent #main.
$('#main').on("click", ".module", function(){
if ($(this).hasClass('flipped')) {
$(this).toggleClass('flipped');
} else {
$('.module').removeClass('flipped');
$(this).toggleClass('flipped');
}
});
Your JavaScript code executes only when the page loads. So after your page is loaded, your code is executed and you telling it to attach the onclick event handler to the elements having the class module. During initial page load there are only 4 such elements. So the event handler will be attached only to these elements (speaking very abstractly).
Now when a new element is added dynamically, events wouldnt fire because there are no handlers tied to them.
In this case you should take advantage of Event Delegation. You need to tie your event handler to the enclosing element (#main or some use body).
So your code would be like:
$('#main').on("click", ".module", function(){
if ($(this).hasClass('flipped')) {
$(this).toggleClass('flipped');
} else {
$('.module').removeClass('flipped');
$(this).toggleClass('flipped');
}
});
So the Event would be tied only to the static #main but when the event occurs, it knows where to find the targeted element because you have specified the target as .module.
Have a look at this:
http://api.jquery.com/on/
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, this example attaches a handler to 1,000 elements:
$( "#dataTable tbody tr" ).on( "click", function() {
alert( $( this ).text() );
});
A delegated-events approach attaches an event handler to only one element, the tbody, and the event only needs to bubble up one level (from the clicked tr to tbody):
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});
Note: Delegated events do not work for SVG.
Try this...
$('body').on("click", ".module" , function(){

The added class doesn't trigger its jQuery function

It's an audio player: the idea is that the play button turns into a pause button (and viceversa) when clicked.
Thing is that the .pause event doesn't trigger the following function:
$('.pause').click(function(){
player.pause();
$(this).addClass('play');
$(this).removeClass('pause');
});
The css shows that the pause class is set, but the function doesn't work. Is there a way to make it work? (would be great to know why it didn't work)
jsFiddle
Use a delegated event binding to bind a handler that will be selector-aware without requiring rebinding on events.
For the purposes of your demo, the selector would be along the lines of:
$('.player_controls').on('click', '.pause', function () {...});
Delegate event bindings attach the listener to a parent element that checks to see if the event fired was fired on an element that matches the provided selector.
jQuery docs
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
You can use event delegation for this. The issue is that binding directly (without delegation) binds to whichever elements exist at the time click is called.
$(".player_controls").on("click", ".pause", function(){
/* ... */
});
Instead of using $('.pause').click(function(){...}) you would need to start using the $.on method to start listening for objects which are still not in the DOM.
e.g
$(".pause").parent().on("click",".pause", function(event){
player.pause();
$(this).addClass('play');
$(this).removeClass('pause');
});

jQuery on() event only working with $(document)

I'm using jQuery's .on() event handler and it's only working when I use $(document).
This works:
$(function() {
$(document).on("click", ".search .remove", function(e) {
console.log("clicked");
});
});
This does not work:
$(function() {
$(".search .remove").on("click", function(e) {
console.log("clicked");
});
});
Nothing happens on that second one...no errors or anything. It just doesn't fire.
You are using two different syntaxes of .on which have two very different outcomes.
Your first is:
$(context).on("event","targetselector",handler)
This binds the event to context, and any events of type event that gets to the context that has an e.target that can be selected with targetselector will trigger the handler with e.target as the context. this is commonly known as event delegation.
Your second syntax is
$(targetselector).on("event",handler)
In this case, the event is bound directly to the elements currently on the page that match targetselector, not future elements. This is essentially the same as the old .bind.
Your second example doesn't work because your elements are created dynamically. When using .on() with dynamically inserted elements, you have to bind it via an element that isn't inserted dynamically, i.e. one that exists on the page at load time.
You can continue to use document as an ancestor element but in terms of performance you might want to find an element closer in the DOM to ".search .remove".
From the jQuery docs on .on():
Event handlers are bound only to the currently selected elements; they
must exist on the page at the time your code makes the call to .on().
To ensure the elements are present and can be selected, perform event
binding inside a document ready handler for elements that are in the
HTML markup on the page. If new HTML is being injected into the page,
select the elements and attach event handlers after the new HTML is
placed into the page. Or, use delegated events to attach an event
handler, as described next.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers. This
element could be the container element of a view in a
Model-View-Controller design, for example, or document if the event
handler wants to monitor all bubbling events in the document. The
document element is available in the head of the document before
loading any other HTML, so it is safe to attach events there without
waiting for the document to be ready.
Your first method is the on() equivalent for the deprecated method live(). Probably your elements get inserted dynamically after the page loading has finished.
You could rewrite your code like following and it should work:
$(function() {
$(".search").on("click", ".remove", function(e) {
console.log("clicked");
});
});

Categories