Jquery .change() to view currently assigned method - javascript

Is there any way I can view the current method assigned to a selects change event.
I have tried.
$('#select').change()
but that just returns me the change event. I don't really need to do this but would be very handy for debugging. Save me hunting through the code to find the method, this way I can simply search the text in the method and find the method quickly.

$('#select').data('events').change;
This will contain an array of objects, one per event handler.
If you're sure there's only one change event handler, you can access the function directly:
var theFunction = $('#select').data('events').change[0].handler;
See it here in action: http://jsfiddle.net/7UD3e/

A slight alteration to Joseph's answer will make the actual code for the function be output:
var clickEvents = $('#select').data("events").change;
$.each(clickEvents, function(key, handlerObj) {
console.log(handlerObj.handler) // prints actual function code, does not run function
})
Source: How to debug JavaScript/jQuery event bindings with Firebug (or similar tool)
Here is a demo: http://jsfiddle.net/7UD3e/2/

Related

using $(this) to get data attribute doesnt return the actual result

Im new to javascript/jquery, I've been searching all over the web but haven't got a satisfying answer. (I will delete it if someone can point out a similar question)
In the hmtl I have
Submit
In the console, I tried this
$('.btn-place-order').data("confirm-modal")
--> it returned "myModal"
But when I tried
$(".btn-place-order").on("click", function(e){ $(this).data("confirm-modal"); });
--> it return the whole object [a.btn-place-order]
Why ?
This behavior is exactly correct. If you take a look at the jQuery documentation you will see:
jQuery on:
.on( events [, selector ] [, data ], handler(eventObject) )
Returns: jQuery
jQuery data:
.data( key )
Returns: Object
This means that when you call var myObject = $('.btn-place-order').data("confirm-modal"); will contain the value of the data- attribute.
However, when you call $(".btn-place-order").on("click", function(e){ $(this).data("confirm-modal"); }); you get a jQuery object returned. This jQuery object is the same one that $(".btn-place-order") already returns, which is very important to make jQuery's concept of chaining work.
Chaining allows you to execute several methods in order, without getting the original jQuery object over and over. For example $(".btn-place-order").on('click',...).on('hover',...); would allow you to attach two handlers (a click and a hover) to the same element.
It also wouldn't make sense for on to return anything else, since it just attaches a handler to an element. It really doesn't give you any value just because you attach an event handler.
Now, if you want to take any action when the event is fired, you will need to take that action inside of the handler's callback function. E.g.
$(".btn-place-order").on("click", function(e){ alert($(this).data("confirm-modal");) });
will alert the user of the data-confirm-modal attribute value of the element that was clicked on. However, without the alert() part (i.e. the way your original code was written), the value is just read, but nothing is ever done with it.

jQuery attr method can set click handler and inner text

Reading jQueryUI dialog code, I've found out, jQuery .attr() method has some undocumented behavior:
<button id="btn1">1</button>
<button id="btn2">2</button>
$(function() {
var props = {
text: 'Click it!',
click: function () {
console.log('Clicked btn:', this);
}
};
$('#btn1').attr(props, true); // Changes #btn1 inner text to 'Click it!'
// and adds click handler
$('#btn2').attr(props); // Leaves #btn2 inner text as it is and fires
// click function on document ready
});
Can you explain me how it works? Why should I set true as the second argument after
map of attribute-value pairs?
Can I use this feature in my projects safely?
I'm guessing slightly here because I'm unfamiliar with the jQuery source. jQuery.attr calls jQuery.access, and the comment above the jQuery.access function reads:
// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
Upon further investigation, the text() function also calls jQuery.access:
attr: function( name, value ) {
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
.........
text: function( value ) {
return jQuery.access( this, function( value ) {
......
},
You're using attr to set text and event handlers, which is not what attr is for. However they all seem to be using the same function to get the job done, so the use of undocumented parameters is just incidentally giving you the expected behavior.
I would consider it unreliable to rely on undocumented behavior to accomplish what you're trying to do here, as any future upgrade of jQuery could break your code.
Looking at the jQuery 1.8.2 code, the true parameter eventually arrives in the variable pass at a line that says:
exec = pass === undefined && jQuery.isFunction( value );
which if set, tells jQuery to check the check the value belonging to the key, and if it's a function, call it immediately. Hence click: function(...) will call that function, not register that function.
This appears to be how the .method(function() { ... } versions of various jQuery functions work, i.e. those where instead of passing a specific value for a property, you pass a function which is itself passed the original value, and whose return value is assigned to the relevant property.
Can I use this feature in my projects safely?
I wouldn't, not until it's documented.
This is an interesting one. I can't pretend to tell you /why/ it works, this way, and I think there even might be reason to submit this as a bug report to jQuery, because the behavior that they document is not coming out as I'd expect.
On this page, the following quote appears toward the bottom:
http://api.jquery.com/attr/
"Note: If nothing is returned in the setter function (ie. function(index, attr){}), or if undefined is returned, the current value is not changed. This is useful for selectively setting values only when certain criteria are met."
This led me to do some playing around on jsFiddle: http://jsfiddle.net/mori57/GvLcE/
Note that, contrary to their documentation, Cases 8 and 9 return either null or nothing. Looking at what Alnitak mentioned, it seems to makes sense, as their test /actually/ is only validating that it /is a function/ not what that function returns (.isFunction should only ever return true/false, which is different from saying that the value returned is true/false).
In the end, however, I'd agree with both Alnitak and bcoughlan that this is not functionality you should rely on, though I'd add that, in addition to it being unstable because it may be changed in future releases of jQuery, it is also bad practice to rely on hacks that are reliant on undocumented features because future developers of the code you write today (and that includes you, in 2-4 months!) could very easily forget that is there, or why it's set that way. Far better to be explicit, and use functionality as documented, so that you're clear to yourself and others what your code is intended to do.

In Javascript/jQuery what does (e) mean?

I am new to JavaScript/jQuery and I've been learning how to make functions. A lot of functions have cropped up with (e) in brackets. Let me show you what I mean:
$(this).click(function(e) {
// does something
});
It always appears that the function doesn't even use the value of (e), so why is it there so often?
e is the short var reference for event object which will be passed to event handlers.
The event object essentially has lot of interesting methods and properties that can be used in the event handlers.
In the example you have posted is a click handler which is a MouseEvent
$(<element selector>).click(function(e) {
// does something
alert(e.type); //will return you click
}
DEMO - Mouse Events DEMO uses e.which and e.type
Some useful references:
http://api.jquery.com/category/events/
http://www.quirksmode.org/js/events_properties.html
http://www.javascriptkit.com/jsref/event.shtml
http://www.quirksmode.org/dom/events/index.html
http://www.w3.org/TR/DOM-Level-3-Events/#event-types-list
DISCLAIMER: This is a very late response to this particular post but as I've been reading through various responses to this question, it struck me that most of the answers use terminology that can only be understood by experienced coders. This answer is an attempt to address the original question with a novice audience in mind.
Intro
The little '(e)' thing is actually part of broader scope of something in Javascript called an event handling function. Every event handling function receives an event object. For the purpose of this discussion, think of an object as a "thing" that holds a bunch of properties (variables) and methods (functions), much like objects in other languages. The handle, the 'e' inside the little (e) thing, is like a variable that allows you to interact with the object (and I use the term variable VERY loosely).
Consider the following jQuery examples:
$("#someLink").on("click", function(e){ // My preferred method
e.preventDefault();
});
$("#someLink").click(function(e){ // Some use this method too
e.preventDefault();
});
Explanation
"#someLink" is your element selector (which HTML tag will trigger this).
"click" is an event (when the selected element is clicked).
"function(e)" is the event handling function (on event, object is created).
"e" is the object handler (object is made accessible).
"preventDefault()" is a method (function) provided by the object.
What's happening?
When a user clicks on the element with the id "#someLink" (probably an anchor tag), call an anonymous function, "function(e)", and assign the resulting object to a handler, "e". Now take that handler and call one of its methods, "e.preventDefault()", which should prevent the browser from performing the default action for that element.
Note: The handle can pretty much be named anything you want (i.e. 'function(billybob)'). The 'e' stands for 'event', which seems to be pretty standard for this type of function.
Although 'e.preventDefault()' is probably the most common use of the event handler, the object itself contains many properties and methods that can be accessed via the event handler.
Some really good information on this topic can be found at jQuery's learning site, http://learn.jquery.com. Pay special attention to the Using jQuery Core and Events sections.
e doesn't have any special meaning. It's just a convention to use e as function parameter name when the parameter is event.
It can be
$(this).click(function(loremipsumdolorsitamet) {
// does something
}
as well.
In that example, e is just a parameter for that function, but it's the event object that gets passed in through it.
The e argument is short for the event object. For example, you might want to create code for anchors that cancels the default action. To do this you would write something like:
$('a').click(function(e) {
e.preventDefault();
}
This means when an <a> tag is clicked, prevent the default action of the click event.
While you may see it often, it's not something you have to use within the function even though you have specified it as an argument.
In jQuery e short for event, the current event object. It's usually passed as a parameter for the event function to be fired.
Demo: jQuery Events
In the demo I used e
$("img").on("click dblclick mouseover mouseout",function(e){
$("h1").html("Event: " + e.type);
});
I may as well have used event
$("img").on("click dblclick mouseover mouseout",function(event){
$("h1").html("Event: " + event.type);
});
Same thing!
Programmers are lazy we use a lot of shorthand, partly it decreases our work, partly is helps with readability. Understanding that will help you understand the mentality of writing code.
Today I just wrote a post about "Why do we use the letters like “e” in e.preventDefault()?" and I think my answer will make some sense...
At first,let us see the syntax of addEventListener
Normally it will be:
target.addEventListener(type, listener[, useCapture]);
And the definition of the parameters of addEventlistener are:
type :A string representing the event type to listen out for.
listener :The object which receives a notification (an object that implements the Event interface) when an event of the specified type
occurs. This must be an object implementing the EventListener
interface, or a JavaScript function.
(From MDN)
But I think there is one thing should be remarked:
When you use Javascript function as the listener, the object that implements the Event interface(object event) will be automatically assigned to the "first parameter" of the function.So,if you use function(e) ,the object will be assigned to "e" because "e" is the only parameter of the function(definitly the first one !),then you can use e.preventDefault to prevent something....
let us try the example as below:
<p>Please click on the checkbox control.</p>
<form>
<label for="id-checkbox">Checkbox</label>
<input type="checkbox" id="id-checkbox"/>
</div>
</form>
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
//var e=3;
var v=5;
var t=e+v;
console.log(t);
e.preventDefault();
}, false);
</script>
the result will be : [object MouseEvent]5 and you will prevent the click event.
but if you remove the comment sign like :
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
var e=3;
var v=5;
var t=e+v;
console.log(t);
e.preventDefault();
}, false);
</script>
you will get : 8 and an error:"Uncaught TypeError: e.preventDefault is not a function
at HTMLInputElement. (VM409:69)".
Certainly,the click event will not be prevented this time.Because the "e" was defined again in the function.
However,if you change the code to:
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
var e=3;
var v=5;
var t=e+v;
console.log(t);
event.preventDefault();
}, false);
</script>
every thing will work propertly again...you will get 8 and the click event be prevented...
Therefore, "e" is just a parameter of your function and you need an "e" in you function() to receive the "event object" then perform e.preventDefault(). This is also the reason why you can change the "e" to any words that is not reserved by js.
It's a reference to the current event object
this will be my first stackoverflow help but I am confident that my answer will help anyone reading this.
Basically, e is just an object containing information about the EVENT which has just occured.
if it is 'click', then the object will contain about the click,
if it is 'submit', then the object will contain about the submit,
and they are typically found in addEventListener.
clickMe.addEventListener('click', e => {
console.log(e)
}
meaning, whenever I 'click' the button, it will console.log the INFOMRATION about the event that happened which is I did is to 'click' it, this will print information about the click event.
e is very useful because you can access and use the event to your very own project such as printing the location of x value... like
clickMe.addEventListener('click', e => {
console.log(e.clientX)
}
then it will print the location where you 'click' that event.. mine it returns 32
if you prefer video, please watch this
https://www.youtube.com/watch?v=_BVkOvpyRI0
video is not mine
upvoting me will truly help me since I am a student and looking for opportunity to help here. Love lots!
$(this).click(function(e) {
// does something
});
In reference to the above code
$(this) is the element which as some variable.
click is the event that needs to be performed.
the parameter e is automatically passed from js to your function which holds the value of $(this) value and can be used further in your code to do some operation.

jQuery ".triggerHandler()" vs. ".trigger()" when multiple elements are selected

The jQuery ".triggerHandler()" mechanism, unlike ".trigger()", only operates on the first element referenced by the jQuery object for which it's called. In other words,
$('.all-over-the-page').triggerHandler("readjust");
will only call the "readjust" handler for the first element with class "all-over-the-page", even if there are many elements on the page with that class. The ".trigger()" method, on the other hand, would affect all of them.
I realize that I can use ".each()" to get around this (or simply write my own substitute that does that for me), but is there some rationale for why the two are different in this respect? It kind-of makes no sense to me. (I understand of course that it almost certainly can't be changed now.)
edit to clarify:
It's probably easier to understand why I'm scratching my head over this if I provide a context in the style of code I've actually got. When I put together code for various "widget" features on a page, that often involves event handlers. A good example is a form of some sort that's got some fields whose relevance is controlled by a checkbox, or radio button, or selector. A common instance of that is the "Shipping Address" checkbox that shows up on a zillion e-commerce sites: if the checkbox is checked, the shipping address is disabled and the billing address is used.
Now consider that some other code may, for its own reasons that are totally independent of the checkbox-control widget, actually do things to the form that may include updating checkbox settings programmatically. In that case, that other widget code may want to use "triggerHandler()" to tell any widgets, "hey I've updated some stuff, so you might want to re-check the current status and adjust if necessary."
Thus, if ".triggerHandler()" would operate on all selected elements, I could use:
$theForm.find('input, select, textarea').triggerHandler('change');
and all those handlers could run and do whatever they need. As I said, it's easy enough to write:
$theForm.find('input, select, textarea').each(function() {
$(this).triggerHandler('change');
});
"...is there some rationale for why the two are different in this respect?"
I think the idea is that triggerHandler() is meant to be a way of invoking the function you as a handler as though it was any other function.
As such, they made triggerHandler() so that the function is only invoked once, it returns the actual return value of the function, and it doesn't affect the DOM with bubbling or default behaviors.
Of course the function may break if they changed the this value to something other than a DOM element, so they just use the first element matched.
If you're wanting to simply use your function, then I'd probably just keep a reference to it and invoke it directly, or as the argument to .each().
$('.element').each( handler_func );
...as long as you don't need the event object.
EDIT: Or if you want the values returned from the invocation, use .map() instead:
var return_values = $('.element').map( handler_func );
EDIT: With respect to the example provided in the updated question, a good solution may be to take advantage of the extraParameters capability of the trigger()[docs] method so that you can tell the handler to preventDefault() and stopPropagation().
$('.elememts').bind( 'click', function( e, was_code_triggered ) {
if( was_code_triggered ) {
e.preventDefault();
e.stopPropagation();
}
// your code
});
// ...
$('.elememts').trigger( 'click', true ); // pass "true" to let handler know
// it wasn't a DOM event
From the .trigger() docs:
"Note the difference between the extra parameters we're passing here and the eventData parameter to the .bind() method. Both are mechanisms for passing information to an event handler, but the extraParameters argument to .trigger() allows information to be determined at the time the event is triggered, while the eventData argument to .bind() requires the information to be already computed at the time the handler is bound."

Using Jquery, call function on selection just once

Say i have a selection of textboxes like this;
var arrayoftextboxes = $('.textbox1, .textbox2, .textbox3');
Is there a way I can call a function on each one in a simpler way than this?
It only needs to be called once.
arrayoftextboxes.each(function(i){foo(arrayoftextboxes[i]);});
I tried
arrayoftextboxes.load(function(){foo(this)});
and
arrayoftextboxes.bind(function(){foo(this)});
but the functions dont seem to be called.
You can do this:
$('.textbox1, .textbox2, .textbox3').each(function() { foo(this); });
The .each() call creates a closure, inside it this refers to the DOM element you're currently on, but it may be better to write what you have as a jQuery plugin. Or, if you just use this inside foo (instead of the DOM element as a parameter) you can shorten it down to:
$('.textbox1, .textbox2, .textbox3').each(foo);
Here's a demonstration of that method
Also, make sure you're running this on document.ready like this:
$(function() {
$('.textbox1, .textbox2, .textbox3').each(foo);
});
Otherwise the DOM elements may not be there to find, making that selector return an empty array (so nothing to run on).

Categories

Resources