Attaching events to elements added dynamically with jQuery - javascript

Here's my code:
$("#strong-against .pick .data .actions .btn-success").on("click", function () {
//Magic here.
});
I read that I should use .on() as that would dynamically attach events to items added even after the document finishes loading.
Yet, the event is not being fired after I load these items dynamically. How can I make it so that any items I add after the document load are listened to?

Try,
$(document).on("click", "#strong-against .pick .data .actions .btn-success", function () {
//Magic here.
});
Follow the 2 steps to bind event handler for dynamic elements,
Find the closest parent elements to which the element will be added dynamically.
Bind the handler to parent element with the dynamic elements selector as the 2nd argument.
So if #strong-against exist on page load then you can,
$("#strong-against").on("click", ".pick .data .actions .btn-success", function () {
//Magic here.
});

Related

how to stop the event of the class without refreshing

i have used the event for the whole row and perform some function by ajax in the page task.php and change the style removed the class and displayed the message without refreshing the page . Eventhough i have removed the class view_task its still getting worked and doing the function how to prevent it. and also changed the class with toggle class(jquery function
$('#task tbody tr.view_task').dblclick(function(e){
var task_id = this.id.split('-');
var id = this.id;
$.post('task.php',{'task':task_id[1],'action':'update_count','type':task_id[2],'index':task_id[3]},function(data){
$('#'+id).css('background-color','white');
$('#'+id).removeClass( "view_task" );
$("#message2").html('<span id="msg">Task Viewed <img src="images/remove.png" /></span>');
});
e.preventDefault();
});
When you install an event handler like this:
$('#task tbody tr.view_task').dblclick(function(e){
it is installed initially and will remain on the object no matter what class changes you make to the object.
If you want the event handlers to be dynamic and change as the class changes, then you need to use the delegated form of .on() like this:
$('#task tbody').on("dblclick", "tr.view_task", function(e){...});
This will actually attach the event handler to #task tbody and then each time a dblclick event bubbles up to that element, it will check to see if it originated on an element that has "tr.view_task". This will allow it to only respond if the appropriate class is still on the clicked on object.
See these references for other info on delegated event handling:
JQuery Event Handlers - What's the "Best" method
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
jQuery selector doesn't update after dynamically adding new elements
Should all jquery events be bound to $(document)?
Try this:
$('#task tbody tr.view_task').unbind();
or if you only want to remove click event
$('#task tbody tr.view_task').unbind("click");
You need to unbind or off the event of .view_task class
Example:
$('#task tbody tr.view_task').off('dblclick');
OR
$('#task tbody tr.view_task').unbind('dblclick');
$('#task tbody tr.view_task').dblclick(function(e){});
Above statement finds element the bind the event with them, if you remove selector it will have no impact.
You can use either .off() to remove event handler.
$('#task tbody tr.view_task').dblclick(function(e){
var self = this;
$.post('task.php',{'task':task_id[1],'action':'update_count','type':task_id[2],'index':task_id[3]},function(data){
$(self).off('dblclick')
});
});
OR, You can use Event Delegation using .on() delegated-events approach.
$('#task tbody').on('dblclick', 'tr.view_task', function(e){
//Your code
})
Try
$("#task tbody tr.view_task").dblclick(function(e) {
if ($(this).hasClass("view_task")) {
// do stuff
$(this).removeClass("view_task")
};
e.preventDefault();
});
$("body").addClass("view_task")
.on("dblclick", function(e) {
if ($(this).hasClass("view_task")) {
// do stuff
console.log(this.className);
$(this).removeClass("view_task");
};
e.preventDefault();
});
body {
width:400px;
height:400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
dblclick

.off(), .undelegate(), .unbind() event only from copied element

I'm using
$(document).on('click', '.mySelector', function () {
//do something
});
To delegate events to buttons.
Next I'm using .clone(true) to copy div which containing few buttons with delegated in to it events.
My question is how do I remove events form selected new created buttons?
I'm tried:
$(document).unbind('click', $(myNewDiv).find('.mySelector'));
Somehow it's removing events from all $('.mySelector') in whole document not only from this inside 'myNewDiv' object.
I have seen documentation of jQuery .off() and .undelegate() and they accept only string like selector (my div can't have any unique ID).
Is any option to remove events from selected elements inside jQuery object when they are delegated to document?
You can add a class to your clones:
var $clone = $original.clone(true).addClass("clone");
And reject that class in your delegated handler:
$(document).on("click", ".mySelector:not(.clone)", function() {
// Do something...
});
$(document).on('click', '.mySelector', function(){
//do something
});
the code above means, "attach a click handler to the document, so whenever any element that corresponds to the '.mySelector' selector is clicked, fire the handler".
whenever you clone an element, you clone its class as well, therefore it will suit the '.mySelector' too.
the handler that you have delegated is attached to the document and not to the elmenets themselves. in order for the new elements to not fire the handler, you must make them not fit the selector. so either change their class to '.mySelector2' after cloning, or whatever.

JQuery Clone - Triggering the same event on both elements

If I clone an element with events .clone(true) and append it within the same page. Can I trigger the same 'live' click event on both.
For example, if I build my own select menu using 'ul' and 'li' elements and add a 'live' click' event on it's class e.g. '.selectOption'. Can I make the original element change when the cloned one does?
I don't really have a code example, but I have run into trouble with this before. The original stays the same if you select one of the options. I have tried triggering a click on the original, but that does not work either.
I don't understand why the event will not make both change. It is pointing to both because they have the same class and structure.
Instead of using .delegate() or .live(), you should try using .on() instead. Let's say you are cloning the element with the class name item, then you can use the following code to bind an event, say, a click event:
$(document).on('click', '.item', function() {
// Do magic here that changes things in both the original item and its cloned counterpart
});
How .on() works is that it listens for events to bubble up the DOM tree until it reaches your selected element of interest, and in this case, document. The caveat is that the element you are listening on event bubbling has to be present in the DOM when jQuery is executed, and document is the safest way to do it. Of course you can also use .on() on other static elements that are present in the DOM, such as <body>.
The OP has furnished with additional information. It seems that OP wants the changes done to one element to propagate to its cloned counterpart, and not simply binding the same handlers to the cloned elements.
$(document).ready(function () {
var $selectMenu = $('.selectMenu');
$selectMenu.on('click', 'li', function () {
$(this).css('background','red');
});
$selectMenu.clone(true).appendTo('body');
});
In this case, I would advocate the use of indexes (with .index()) for DOM transversal in the context of the element's parent.
$(document).ready(function () {
var $selectMenu = $('.selectMenu');
$selectMenu.on('click', 'li', function () {
$(".selectMenu").find('li:eq('+$(this).index()+')').css('background','red');
});
$selectMenu.clone(true).appendTo('body');
});
See fiddle here: http://jsfiddle.net/teddyrised/4Jxv2/2/
Also, some possible improvements:
Add/remove classes instead of directly manipulating inline CSS of the element
Use .on() so that you can bind events that are not originally bound to the element before cloning.
See revised function below:
$(document).ready(function () {
// Clone first, worry about binding events later
$('.selectMenu').clone(true).appendTo('body');
// Bind events
$(document).on('click', '.selectMenu li', function() {
$('.selectMenu')
.find('li:eq('+$(this).index()+')')
.addClass('highlighted');
});
});
where the class .highlighted can be used to declare the background color :) See fiddle here: http://jsfiddle.net/teddyrised/4Jxv2/3/

How to add onclick to Div with a specific class name?

I have a few generated div's on my page listing events on a calender, they all have the same class "fc-event-inner". I would like to add a onclick to these div's but am struggling to get this right.
This is what iv tried, no onclick is added and no errors on page.
$(document).ready(function () {
$('.fc-event-inner').each(
function (element) {
Event.observe("click", element, EventClick);
}
);
function EventClick() {
alert("You clicked an event")
}
});
This is an example of a generated event div:
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br>by Santa</span>
</div>
Use the delegate version of on
$(document).on("click", ".fc-event-inner", function(){
/// do your stuff here
});
This catches the click at the document level then applies the class filter to see if the item clicked is relevant.
Example JSFiddle: http://jsfiddle.net/BkRJ2/
In answer to comment:
You can access the clicked element via this inside the event function. e.g.
$(document).on("click", ".fc-event-inner", function(){
var id = this.id; // Get the DOM element id (if it has one)
var $this = $(this); // Convert DOM element into a jQuery object to do cool stuff
$this.css({'background-color': 'red'}); // e.g. Turn clicked element red
});
*Note: You should never have to run an Each in order to catch events on multiple items that have a common class.
You do not need each() to bind event to elements with specific class, just selector is enough. Use jQuery on() with event delegation it will bind event to those which are generted after the binding code.
$(document).on("click", ".fc-event-inner", function(){
alert("click");
});
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.
<div class="fc-event-inner">
<span class="fc-event-title">Requested<br />by Santa</span>
</div>
Your JS:
<script>
$(document).ready(function () {
$('.fc-event-inner').on("click", EventClick);
function EventClick() {
alert("You clicked an event")
}
});
</script>
http://jsfiddle.net/UBhk9/
Some explanation:
Because you are using a class(it may be used multiple times, in contrast to an id) it will work for all the elements with this class name. The .on method will attach the event handler(in this example "click") to the selector(the class .fc-event-inner). If you want to remove events bounds you've to use the .off() method and if you only want to attach the event once you can use the .one() method.

return false on dynamically created element

I'm trying to prevent an event on dynamically created elements.
I tried several ways but none worked.
On deafult, a click on the div containing the class opens a menu, and I want to disable that.
This is my code (please note I'm using jQuery 1.6.4 so I'm not able to use the "on" method).
$(function() {
$( document ).delegate( "span.highlight_mkt", "click", function() {
return false;
});
});
I have tried this using the "live" method as well but without any success.
Any help would be much appreciated.
maybe this link helps you -> preventDefault
$(document).delegate("span.highlight_mkt", "click", function (e) {
e.preventDefault();
/* your code here */
});
EDIT
you tried this too?
$('span.highlight_mkt').live("click", function (e) {
e.preventDefault();
/* your code here */
});
This one should stops the event propagation:
$(function() {
$( document ).delegate( "span.highlight_mkt", "click", function(e) {
e.preventDefault();
e.stopPropagation();
return false;
});
});
What I understand from your question is you have span with highlight_mkt class in your html form with click event attached using selector or document. And you are loading using Ajax or dynamically creating other span with same class name.
So in order to prevent events on your dynamically created elements you can use .die() function with container name where you are attaching dynamically created elements as following:
$('container_selector span.highligh_mkt').die('click');
In this method click event will be fired only your elements which is not attached dynamically.
If I understand you incorrectly please clarify your question.
What you did is you are attached event handler to document element or global container using .live() jquery function. So it is not good thing to do. I will explain later.
$('body').live('click','span.hihligh_mkt', function(e){
//Your code here. Which is doing some cool staff i believe :)
});
However if you want to prevent only for dynamically created elements do following:
$('body').live('click', 'span.some_class', function(e){
// This part is needed in order to check weather it is attached dynamically
// or it is predefined html objects
if($(e.target).closest('#some_container').length==0)
{
//Your code here. Which is doing some cool staff i believe :)
}
});
So in above you will just check, does event fairing element is dynamically attached to container element or it is part original html. Of course this kind of method can be avoided if you will use event which will be attached individually to the the elements like following when DOM ready.
$('span.hihligh_mkt').live('click', funtion(e){});
In this case only elements which was exists in DOM ready will get handlers. Other dynamically attached elements will not have event handlers. Unless you are not doing deep cloning of span elements.
Another thing is here when you attaching event handler to body or other root elements it gives you slow performance. You can read about it here.
Since all .live() events are attached at the document element, events
take the longest and slowest possible path before they are handled.
You can see some example here.

Categories

Resources