jQuery "*on click function*" - javascript

I am struggling with this code:
After choosing the html element and then applying the on click function what is the purpose of tr.
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});

The purpose of the TR is to specify what you will be clicking within the #dataTable tbody selector. Try changing it to something else and see how it behaves differently.

There's a subtle difference between:
$( "#dataTable tbody tr" ).on( "click", callback); // 1
and
$( "#dataTable tbody" ).on( "click", "tr", callback); // 2
The first selects every tr and calls addEventListener on each individually.
The second adds only one, special event listener to the tbody element. Whenever something inside is clicked, this listener checks if it is a tr and then delegates the event to your specified callback.
This gives 2 practical differences:
One listener is added, instead of potentially very many (which can improve performance in some cases),
if you add more trs dynamically in the future, they will also react to click as you'd expect.

Events bubble. That's the primary thing you need to understand. If the user clicks on an a inside a p inside a td inside a tr inside a table (and so on), the click event will bubble up each of these elements and trigger all click event listeners in turn.
$("#dataTable tbody").on("click", "tr", function() {
This chooses the #dataTable tbody element to attach the event listener to, but it will filter and only react to events triggered by a nested tr. You could also do this instead:
$("#dataTable tbody tr").on("click", function() {
But this would bind many individual event listeners to each and every tr. This may be a lot more inefficient or have other undesirable effects; for example if you keep adding or removing tr elements, you may end up with some trs which have event listeners bound to them and others without.

Related

Table row and cell click

How do I create click event for table row(tr) specific and table data(td).
For example, something similar like this
$("table tr").on("click", function(){
// do something with tr without td click handler
});
$("table tr td").on("click", function(){
// do something with td without tr click handler
});
Thanks in advance
To bind click event to td element so that it doesn't fire parent tr click, you need to prevent event from bubbling up DOM tree. You should call stopPropagation method of the event object:
$("table tr td").on("click", function(e) {
e.stopPropagation();
// do something with td without tr click handler
});
do something with tr without td click handler
This is also possible if you bind click event in capturing phase (read about event order). For this you will need to use HTMLElement's addEventListener method, jQuery $.fn.on method bind event in bubbling stage of the event propagation. However note, that this has little practical sense if you think about it. Most likely that you want to prevent bubbling of the event in td->tr direction on some specific table cells clicks.

.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.

Event handler query at time that event is registered?

I know certain queries take a bit longer than others (e.g., compound queries are slower than simple queries, ids are faster than classes, etc.). In my case, that's of practical significance. Wonder how it applies to queries in event handlers.
Does the query have any impact on the speed at which the event handler will fire? Or is the query already resolved to some sort of pointer to that object in the DOM?
For example, would these handlers be absolutely equivalent? :
$("body > section > #id div.class element").click(func);
$("#element").click(func);
In the case you give, the speed of the selector would only affect the initial setup of the page -- the speed to find the element on which to place the event handler. Once the event handler is attached, the selector shouldn't affect the speed of the actual event handler firing.
The case in which selector speed could matter to an event handler would be where you use the on() function to define event handlers for elements that might not yet exist -- "delegated" events. For example:
$( "#dataTable tbody" ).on( "click", "tr", func);
versus
$( "#dataTable tbody" ).on( "click", ".my-table-row", func);
The performance of the first event handler will be better (though it's absolutely worth pointing out that the difference is typically small). The reason this case is different from your example is that the actual click handler is being placed on the tbody, and the selector is then used at fire time to determine whether a given event is a match.

jquery delete dynamically created input field

So im creating project in which you can create unlimited number of input fields that belong to the same array and eventualy are being posted to php handler via ajax. i managed to get that far, its working all fine but the problem im having is that i would want to let user to delete input he/she doesnt want (i.e. created by mistake), it seems to be core part of script, yet i dont know how to approach the issue.
This project you can see in here:
http://jsfiddle.net/7LCzN/
and this is the code:
$(function(){
$("#add").on('click', function () {
$('body').append('<input type="text" class="ac" name="array[]" />');
});
});
$(function(){
$("#post").on('click', function () {
var myArray = new Array();
$('.ac').each(function(index, elem) {
myArray.push($(elem).val());
});
$('#result').text(myArray);
});
});
So for instance ive created 4 fields with these value:
5463, 8675, 2340, 1203
and i just realized i dont want the one with value 2340 i would want to delete it so im left with 3 fields:
5463, 8675, 1203
anyone that helps, ill be glad and greatful, thank you fellows:)
.remove() is a jQuery function that you can use to remove elements from the DOM.
Here's a tiny example:
$(".inputToRemove").remove();
Here's a fork of your jsFiddle for a working example.
From the docs:
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() );
});

Using .on() and e.stopPropagation() on dynamic elements

I have been experimenting with capturing click events outside of elements using stopPropagation().
$(".container").children().on('click',function(e){
e.stopPropagation();
});
$(".container").on("click",function(){
alert("outside the box?");
})​
Here is a jsFiddle set up to demonstrate it functioning. An alert should fire when you click anywhere outside of the white box.
Now, I am trying to have the same principle applied to dynamically created elements. As far as I understand, the on() method of event assignment in jQuery should allow this to function without changing the script.
Here is a second jsFiddle where you must first click a link to create the elements. Once you have done this, the theory is that the same script will work, but it does not. What am I missing about this method?
When the item is added dynamically, you should attach the handler to the closest parent that will surely be there - in your case this is body. You can use on() this way to achieve a functionality that delegate() used to offer:
$(selector-for-parent).on(events, selector-for-dynamic-children, handler);
So your code rewritten would simply be this:
$("body").on('click', '.container', function(e){
var $target = $(e.target);
if ($target.hasClass('container')) {
alert("outside the box!");
}
});
I used e.target to find which element actually triggered the event. In this case, I identify the item by checking whether it has the container class.
jsFiddle Demo
In short word you need to put on() on existing parent element to make it works:
$('body').on('click', 'a', function(e){
e.preventDefault();
$('<div class="container"><div class="box"></div></div>').appendTo('body');
$(this).remove();
});
$('body').on('click', '.container > *', function(e){
e.stopPropagation();
});
$('body').on('click', '.container', function(){
alert("outside the box?");
})​
Code: http://jsfiddle.net/GsLtN/5/
For more detail check '.on()' on official site at section 'Direct and delegated events'
The demo.
When you bind a event handler to a element use .on, the target you bind to must exist in the domcument.
$('body').on('click', '.container > *', function(e){
e.stopPropagation();
});
$('body').on("click",'.container',function(){
alert("outside the box?");
})​
You need to bind the .on() to a parent.
What you're trying to do is - bind the handler to a parent that listens for an event, then checks whether the event was triggered by an element that matches that selector.
$("body").on("click", '.container',function(){
alert("outside the box?");
})​
Updated fiddle here
According to the documentation for jQuery.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().
You will have to bind the event to a parent container. Perhaps something like THIS.

Categories

Resources