Utility methods
> Object.getOwnPropertyNames(jQuery).toString();
"prototype,fn,extend,expando,isReady,error,noop,isFunction,isArray,isWindow,isNumeric,isEmptyObject,isPlainObject,type,globalEval,camelCase,nodeName,each,trim,makeArray,inArray,merge,grep,map,guid,proxy,now,support,find,expr,unique,text,isXMLDoc,contains,filter,dir,sibling,Callbacks,Deferred,when,readyWait,holdReady,ready,acceptData,cache,noData,hasData,data,removeData,_data,_removeData,queue,dequeue,_queueHooks,access,event,removeEvent,Event,clone,buildFragment,cleanData,swap,cssHooks,cssNumber,cssProps,style,css,Tween,easing,fx,Animation,speed,timers,valHooks,attr,removeAttr,attrHooks,propFix,prop,propHooks,parseJSON,parseXML,active,lastModified,etag,ajaxSettings,ajaxSetup,ajaxPrefilter,ajaxTransport,ajax,getJSON,getScript,get,post,_evalUrl,param,parseHTML,offset,noConflict,length,name"
Query selection methods
> Object.getOwnPropertyNames(jQuery.prototype).toString();
"jquery,constructor,selector,length,toArray,get,pushStack,each,map,slice,first,last,eq,end,push,sort,splice,extend,find,filter,not,is,init,has,closest,index,add,addBack,parent,parents,parentsUntil,next,prev,nextAll,prevAll,nextUntil,prevUntil,siblings,children,contents,ready,data,removeData,queue,dequeue,clearQueue,promise,on,one,off,trigger,triggerHandler,text,append,prepend,before,after,remove,empty,clone,html,replaceWith,detach,domManip,appendTo,prependTo,insertBefore,insertAfter,replaceAll,css,show,hide,toggle,fadeTo,animate,stop,finish,slideDown,slideUp,slideToggle,fadeIn,fadeOut,fadeToggle,delay,val,attr,removeAttr,prop,removeProp,addClass,removeClass,toggleClass,hasClass,blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error,contextmenu,hover,bind,unbind,delegate,undelegate,wrapAll,wrapInner,wrap,unwrap,serialize,serializeArray,ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend,offset,position,offsetParent,scrollLeft,scrollTop,innerHeight,height,outerHeight,innerWidth,width,outerWidth,size,andSelf"
From the documentation, I learnt that,
Methods called on jQuery selections are in the $.fn namespace, and automatically receive and return the selection as this.
Methods in the $ namespace are generally utility-type methods, and do not work with selections; they are not automatically passed any arguments, and their return value will vary.
From the above statement, I infer that,
1) Methods applied on query selections[ex- jQuery('ul li')] come from jQuery.prototype.
2) Methods coming from jQuery are utility methods.
Is my understanding correct?
Note: beginner
Your understanding is correct.
jQuery.fn is a reference to jQuery.prototype. When you define a function using jQuery.fn.myFunction = function() { }, you can access it using jQuery("div").myFunction(). Within this function, you can access the selected elements using this, so you can for example run this.html("newcontent"), which would in this example equal jQuery("div").html("newcontent").
When you define a function using jQuery.myFunction = function() { }, the function will not receive any selected elements, so it is only useful if you pass it some parameters.
I am creating a few DOM elements dynamically like,
var anchorElement = jQuery('<a />',{text:property.text});
var liElement = jQuery('<li />',{"class":"navlink_"+i,id:"navlink_"+i});
anchorElement.on('click',property.fnctn);
liElement.append(anchorElement);
parentID.append(liElement);
Where property is a JSON object.
property.text is the text that I want to put into anchor element. (Works fine)
I want to attach a click event handler to that anchor element.
The function that needs to be bound to that element is specified in JSON and we can access it like
property.fnctn
The following line should bind the event handler to the anchor element.
anchorElement.on('click',property.fnctn);
This was not working so I tried converting it into string like,
anchorElement.on('click',property.fnctn.toString());
No Success...
When I click on this link, the error is logged in the console
The object has no method 'apply'.
What is the reason...???
I am able to get it working with a slight work around like
anchorElement.attr('onclick',property.fnctn+"()");
Above statement works, but I want to know why .on() API is not working.
Thanks :)
AÐitya.
Update:
Youve said that property.actfn is a string, "paySomeoneClick". It's best not to use strings for event handlers, use functions instead. If you want the function paySomeoneClick, defined in the string, to be called, and if that function is global, you can do this:
anchorElement.on('click',function(event) {
return window[property.fnctn](event);
});
That works because global functions are properties of the global object, which is available via window on browsers, and because of the bracketed notation described below.
If the function is on an object you have a reference to, then:
anchorElement.on('click',function(event) {
return theObject[property.fnctn](event);
});
That works because in JavaScript, you can access properties of objects in two ways: Dotted notation with a literal property name (foo.bar accesses the bar propety on foo) and bracketed notation with a string property name (foo["bar"]). They're equivalent, except of course in the bracketed notation, the string can be the result of an expression, including coming from a property value like property.fnctn.
But I would recommend stepping back and refactoring a bit so you're not passing function names around in strings. Sometimes it's the right answer, but in my experience, not often. :-)
Original answer:
(This assumed that property.fnctn was a function, not a string. But may be of some use to someone...)
The code
anchorElement.on('click',property.fnctn);
will attach the function to the event, but during the call to the function, this will refer to the DOM element, not to your property object.
To get around that, use jQuery's $.proxy:
anchorElement.on('click',$.proxy(property.fnctn, property));
...or ES5's Function#bind:
anchorElement.on('click',property.fnctn.bind(property));
...or a closure:
anchorElement.on('click',function(event) {
return property.fnctn(event);
});
More reading (on my blog):
Mythical methods
You must remember this
Closures are not complicated
I'm trying to understand the format of the Javascript functions that jQuery, among other people, use.
For instance jQuery(arg).hide() or $("#obj").hide
I'd like to write similar format functions but I don't understand how.
I know how to write
function myFunc(args) {
}
but I don't understand the second part ie the .hide()
is that a function within a function?
thanks for any help
It's called method chaining. The way to achieve this is for your first function to return an object, so the second function can be called as a method on that object.
The standard way to do this style of programming is to always return the same type of object, so for example, jQuery always returns a jQuery object representing a collection of HTML nodes. If one of the calls modifies the collection then the next call will be on that collection. That's how you can do something like $('#myid').parent().hide();. $('#myid') returns a jQuery object representing the #myid element and .parent() returns a jQuery object representing the parent element of #myid. .hide() returns the same object, so you could then call another method on the same object if you wanted.
This is called method chaining. I highly recommend picking up Crockford's "JavaScript: The Good Parts". This is a very quick read but wonderfully explains OOP in JavaScript and identifies good versus bad language features. Highly recommend it.
As Skilldrick pointed out, this is called method chaining.
The most straightforward example for this is an object that returns itself when you call any of its methods:
var world = {
'hello': function() {
alert('Hello');
return this;
},
'goodbye': function() {
alert('Goodbye');
return this;
}
};
world.hello().goodbye();
This is identical to world.hello(); world.goodbye();.
jQuery does a little more than that. Calling the jQuery or $ function on a valid selector string will return a jQuery object representing the matched elements (it's not actually an array, though you could think of it as one). Most of its methods will return the object itself after modifying the object (e.g. $("a").css({...}) will apply changes to the styling of the matched elements and then return the set of matched elements again).
But some jQuery methods allow modifying the set you're working with (e.g. $("a").parent() will return a jQuery object representing the parents of the matched elements). That is, they don't return the same object, but an object that behaves identically.
You have to be careful if you decide to use this style, though, as the flow will break if you need a method that has a return value of its own (e.g. if you want calculations or getter methods). This can be avoided by passing a callback function to the method, but the resulting coding style may be terribly convoluted.