jQuery - Utility Vs QuerySelection - methods - javascript

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.

Related

call jQuery lib function identified with variable

I build recurring html with jQuery functions.
I'd like to give my functions more flexibility with $.append(), $.before(), and $.after(), etc.
Currently, I do something like
$.fn.appendRecurringHTML = function(domInsertMethod, domInsertID, htmlToInsert) {
if(domInsertMethod == 'append'){
$(domInsertID).append(htmlToInsert);
}
else if(domInsertMethod == 'before'){
$(domInsertID).before( ...
}
but I'd prefer (pseudo)
$.fn.appendRecurringHTML = function(domInsertMethod, domInsertID, htmlToInsert) {
$(domInsertID).window[domInsertMethod](htmlToInsert);
}
but that doesn't work for me.
Is this possible? If so, how?
Just use
$(domInsertID)[domInsertMethod](htmlToInsert);
DEMO: http://jsfiddle.net/UZKLY/
This works because the result of $(domInsertID) (or any $()) is a jQuery object, so it has properties and methods you want to call. Normally, you use dot notation to access them, but bracket notation is just as valid to use. Bracket notation is the only way to dynamically get a property/method (and allows for invalid identifier characters).
But be careful, because technically any method name could be provided, and therefore called. So it's up to you if you want to allow it or not.
As it stands, it doesn't make sense to add to $.fn, because you're not actually using the selected elements from the selector. It makes more sense to me to use this setup:
$.appendRecurringHTML = function(domInsertMethod, domInsertID, htmlToInsert) {
$(domInsertID)[domInsertMethod](htmlToInsert);
};
And you would call it like:
$.appendRecurringHTML("after", "#id", "html");
But if you wanted to use the selected element(s) as the target(s), you could use:
$.fn.appendRecurringHTML = function(domInsertMethod, htmlToInsert) {
return this.each(function () {
$(this)[domInsertMethod](htmlToInsert);
});
};
And call it like:
$("selector").appendRecurringHTML("after", "html");
DEMO: http://jsfiddle.net/UZKLY/1/
It preserves chaining, and will be applied to all matched elements.
Try this:
$(domInsertID)[domInsertMethod](htmlToInsert);
This approach creates jQuery object with your domInsertID first. Than selects domInsertMethod from that object's prototype chain and executes the method using htmlToInsert.

Difference _() and () in javascript

I've been working in backbone.js and came across the following snippet of code.
_(view.buttonViews).each(function(button) {
button.render();
});
Where view.buttonViews is an array. If I take away the _() and have
view.buttonViews.each(function(button) {
button.render();
});
then I get an error that each is not a function. What does the _() add? Thanks!
I guess it is the Underscore.js library which provides the each method:
_.each(list, iterator, [context]) Alias: forEach
Iterates over a list of elements, yielding each in turn to an iterator function. The iterator is bound to the context object, if one is passed. Each invocation of iterator is called with three arguments: (element, index, list). If list is a JavaScript object, iterator's arguments will be (value, key, list). Delegates to the native forEach function if it exists.
This way, _([...]).each(...), is just another way of calling it.
BTW, it is also described in Backbone's documentation:
Backbone's only hard dependency is Underscore.js.
And FWIW, as #Jonathon already said, in general, _ is a valid variable name and in this case it contains a function. Adding parenthesis behind a function references calls that function and therefore, _() calls the function referred to by _. It is nothing special.
Besides that, parenthesis can occur as part of a function declaration or expression (function foo() {...}) or as grouping operator (var i = (20 + 1) * 2;).
Backbone is built on top of underscore, a utility library providing a lot of useful functionality that isn't native to JS but probably should be (eg things like traversing objects, array mapping, eliminating duplicate items in an array, that sort of thing).
It can be written using object-oriented or a functional style. So for instance your snippet of code could also be written thus:
_.each(view.buttonViews,function(button) {
button.render();
});
Backbone depends on Underscore which implements many utility functions. You can wrap an array with the _() function and use the Underscore API as demonstrated here.
Underscore implements these functions without touching the prototype, so each is not available to a regular array. However, it is callable from the object returned from the _ function, which wraps the original array.
Backbone provides functions from Underscore.js -> http://documentcloud.github.com/backbone/#Collection-Underscore-Methods

jQuery like custom functions

I have been wondering how I can create functions like jQuery. For example: $(ID).function()
Where ID is the id of an HTML element, $ is a function that return the document.getElementById reference of the element "ID" and function is a custom javascript function.
I'm creating a little library which implements some functions. And I want to use that sintax without using jQuery.
Now, my questions are: how I can implement that? What is the name of the tecnique that allow that?
Edit:
What I want to do is this:
HTMLElement.prototype.alertMe = function() {alert(this.value);}
Then, when I call document.getElementById('html_input_id').alertMe(), it must show an alertbox with the input value. But HTMLElement.prototype doesn't work in IE.
$ = function(id) {
return document.getElementById(id);
}
Okay, look, what you're asking has a lot of details and implications. The code for jQuery is open source, you can read it for the details; you'd do well to find a good Javascript book as well, the the O'Reilly Definitive Guide.
$ is just a character for names in JS, so as some of the other answers have shown, there's no reason you can't just write a function with that name:
var $ = function(args){...}
Since everyone and his brother uses that trick, you want to have a longer name as well, so you can mix things.
var EstebansLibrary = function(args){...}
var $ = EstebansLibrary; // make an alias
Since you end up doing different things with the entry point function, you need to know how JS uses arguments -- look up the arguments object.
You'll want to package this so that your internals don't pollute the namespace; you'll want some variant of the module pattern, which will make it something like
var EstebansLibrary = (function(){
// process the arguments object
// do stuff
return {
opname : implementation,...
}
})();
And you'll eventually want to be prepared for inheritance and that means putting those functions into the prototype object.
You can use prototype to assign a new function to the Element prototype.
Element.prototype.testFunction=function(str){alert(str)};
This would provide the function 'testFunction' to all HTML elements.
You can extend any base Object this way, i.e. Array, String etc.
This will work without any plugin at all - although that said I don't think it will work in IE. I believe libraries such as MooTools and jQquery create their own inheritance with DOM elements to ensure cross-browser compatibility, although don't quote me on that.

creating a plugin return this question

it says in the documentation to allways return the this object in all cases i've seen so far you return this.each() function. So are there anyother cases other than this.each that you would return
If you are trying to add a method similar to .prev() or another such function included in jQuery, using this.map() may be useful. To answer another question on this site, I created a jQuery plugin that does exactly that.
Likewise, one might want to return a string (or other data type) from a plugin (compare .attr(), .css(), and .data()), most often from the first wrapped element when only one argument is passed to the method.
For most plugins, the main reasons to return this.each(function() { ... }) are:
Your code is executed for every DOM element referred to within the jQuery object.
It returns that same jQuery object to allow method chaining. Obviously, that doesn't apply for methods intended to return a new jQuery object, such as mine.

Understanding javascript function calls in format of myFunc(arg).something()

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.

Categories

Resources