I've developed a few jQuery plugins before which follow the format of either $('#something').myPlugin() or $.myPlugin().
I know you can also write your own selectors.
What I was wondering if I could write a plugin that changes how the css() method works, that is, if I request a shorthand CSS attribute (such as padding) I could return something like this
return $(this).css('padding-top') + ' ' + $(this).css('padding-right') + ' ' + $(this).css('padding-bottom') + ' ' + $(this).css('padding-left');
Is this possible? How would I do it if so?
Thanks
It is possible, but its use in production should be avoided at all costs.
Changing the core functionality of a library that is so often used in tandem with multiple plugins is a bad, dangerous, and bad-and-dangerous idea.
It may be possible for you to cause the overwritten method to interface and behave in its original way and to only behave differently for a subset of parameters; however, in subsequent releases of the library, if this core method changes, you may, in short, be screwed and have to revisit the overwritten method.
It's best to use a different method name. Perhaps, for your uses, you can use style , xCss, cssExt, or something along those lines.
If you're looking for one method to combine the functionality of both your method and the core method, then it is best to take the opposite approach. Instead of overwriting the core method, wrap it with additional functionality, and of course, a new name.
jQuery.fn.xCss = (function() {
var compoundProperties = {
'padding': ['padding-top', 'padding-right' ...],
'border': ['border-width', 'border-style', ...],
'background': ['background-color', ...],
...
};
return function(property, value) {
// Use plugin functionality
if ( compoundProperties.hasOwnPropery(property) ) {
// Get value
if ( !value ) {
var propertySet = compoundProperties[property],
result = [];
for ( var i=0, l=propertySet.length; i<l; ++i ) {
result.push( this.css(propertySet[i]) );
}
return result.join(" ");
}
// Set value
...
return this;
}
// Use core functionality
return this.css.apply(this, arguments);
};
})();
* Code not tested or complete.
Essentially, you would need to replace the jQuery method. Extreme caution advised, as you could break many things that rely on this method. Best off to choose a different name.
Consider this concept:
jQuery.fn.css_orig = jQuery.fn.css
jQuery.fn.css = function(arg1, arg2) {
if(arg1 == 'what-I-want')
{
return my_thing;
}
else
{
return this.css_orig(arg1, arg2);
}
};
In the case of .css, I think you could (if you were very careful) retain 100% of the functionality of the .css method, while adding your functionality on top.
Cool idea, none the less!
Why not create a user defined function in your application namespace that does what you want (your custom business rules)?
By the example, I don't see many use of this function outside your current application...
My 2 cents
EDIT:
Hi Alex, does the already built-in function could help you?
Shorthand CSS properties (e.g. margin,
background, border) are not supported.
For example, if you want to retrieve
the rendered margin, use:
$(elem).css('marginTop') and
$(elem).css('marginRight'), and so on.
I guess you could do the same with the padding?
http://docs.jquery.com/CSS/css#name
You can override the default jQuery methods by creating plugins with the same name.
There's some more info about this over at Ask Ben.
jQuery is such a well thought out,
powerful Javascript library, that it
actually uses itself to build itself.
What I mean by that is that many of
the methods provided by the jQuery
library are actually built internally
as plugins to the jQuery architecture.
When you start to think about the
methods in this way, it is a small
leap to see that we can override a
given jQuery method by simply creating
a new plugin of the same name.
Related
I need to write a function where I can pass it a string and it will replace the word "prefix" in it with the contents of that string. So every time I call the function and pass it a new string i.e. alpha, beta, etc it will completely rebuild all the layers and events inside, using that key as the prefix. I suspect I need to use eval, but I'm not really sure how in this case.
layoutViews = (prefix) ->
prefix_layer1 = new Layer
width: 100
height: 100
prefix_layer1.on Events.Click ->
buttonActions()
layoutViews(alpha)
layoutViews(beta)
I'm using CoffeeScript, but any ideas in real JS are also welcome. I realize this specific question hints at my doing something else wrong in the project, but it's mostly for my own curiosity whether this is even possible.
So you want
function build(prefix) {
window[prefix + "_hi"] = function() {
alert("hi");
};
}
Use like this:
build("test");
test_hi();
Window is just the global (! Bad) element in browsers, so you might consider to assign to this instead of window depends on your usage.
I develop a JavaScript module to prevent basic dom-based XSS on a client-side. I use a couple of standard functions: indexOf(), substring(), toString(), etc.
During a testing I found that some external JavaScript libraries sometimes can incorrectly override functions. For example, the following overriding of indexOf() function does not return -1 if an element is not present in the array:
; /* Start:/js/jquery.select.js*/
(function($){
//add class of js to html tag
$('html').addClass('js');
//create cross-browser indexOf
Array.prototype.indexOf = function (obj, start) {
for (var i = (start || 0); i < this.length; i++) {
if (this[i] == obj) {
return i;
}
}
}
So this new indexOf() can break ifStatement. The trivial example:
function protect(s){
...
if(sNodes.indexOf(node) !== -1) { {
/*injection found*/
sanitize(s);
...
}
}
Now indexOf() returns undefined if node is not present. In my case this can lead to false positive and sanitization of correct input data.
The script must be executed before and after DOMContentLoaded.
One note: I can not control environment where my. script will be used for sanitizing. It somethins like WAF and shoul work with any JavaScript application
My suggestions are the following:
Implement own versions of main critical functions (e.g., indexOf)
Save references to these function before they will be overrided and the use them:
Array.prototype._indexOf = Array.prototype._indexOf;
...
function sanitize(s){
...
if(sNodes.indexOf(node) !== -1) { {
/*injection found*/
sanitize(s);
...
}
}
Are they correct?
What are the best practices to deal with this issue?
Are my suggestions correct?
Yes. For solution 2, you might want to use var indexOf = Array.prototype.indexOf and then indexOf.call(sNodes, node) (if you trust that Function.prototype.call hasn't been messed with…) to avoid creating methods on builtin prototypes. And of course you need to ensure that your library is loaded before the malicious one.
What are the best practices to deal with this issue?
Ignore the issue. Write your code as you'd always do.
If you find another library that does such shit, a) file a bug with them and b) replace it with a better one. If anyone insists on using such a library, charge them extra.
If your actual goal is to prevent such issues entirely, use Caja.
I don’t think I’ve grokked currying yet. I understand what it does, and how to do it. I just can’t think of a situation I would use it.
Where are you using currying in JavaScript (or where are the main libraries using it)? DOM manipulation or general application development examples welcome.
One of the answers mentions animation. Functions like slideUp, fadeIn take an element as an arguments and are normally a curried function returning the high order function with the default “animation function” built-in. Why is that better than just applying the higher-up function with some defaults?
Are there any drawbacks to using it?
As requested here are some good resources on JavaScript currying:
http://www.dustindiaz.com/javascript-curry/
Crockford, Douglas (2008) JavaScript: The Good Parts
http://www.svendtofte.com/code/curried_javascript/
(Takes a detour into ML so skip the whole section from “A crash course in ML” and start again at “How to write curried JavaScript”)
http://web.archive.org/web/20111217011630/http://blog.morrisjohns.com:80/javascript_closures_for_dummies
How do JavaScript closures work?
http://ejohn.org/blog/partial-functions-in-javascript (Mr. Resig on the money as per usual)
http://benalman.com/news/2010/09/partial-application-in-javascript/
I’ll add more as they crop up in the comments.
So, according to the answers, currying and partial application in general are convenience techniques.
If you are frequently “refining” a high-level function by calling it with same configuration, you can curry (or use Resig’s partial) the higher-level function to create simple, concise helper methods.
Here's an interesting AND practical use of currying in JavaScript that uses closures:
function converter(toUnit, factor, offset, input) {
offset = offset || 0;
return [((offset + input) * factor).toFixed(2), toUnit].join(" ");
}
var milesToKm = converter.curry('km', 1.60936, undefined);
var poundsToKg = converter.curry('kg', 0.45460, undefined);
var farenheitToCelsius = converter.curry('degrees C', 0.5556, -32);
milesToKm(10); // returns "16.09 km"
poundsToKg(2.5); // returns "1.14 kg"
farenheitToCelsius(98); // returns "36.67 degrees C"
This relies on a curry extension of Function, although as you can see it only uses apply (nothing too fancy):
Function.prototype.curry = function() {
if (arguments.length < 1) {
return this; //nothing to curry with - return function
}
var __method = this;
var args = toArray(arguments);
return function() {
return __method.apply(this, args.concat([].slice.apply(null, arguments)));
}
}
#Hank Gay
In response to EmbiggensTheMind's comment:
I can't think of an instance where currying—by itself—is useful in JavaScript; it is a technique for converting function calls with multiple arguments into chains of function calls with a single argument for each call, but JavaScript supports multiple arguments in a single function call.
In JavaScript—and I assume most other actual languages (not lambda calculus)—it is commonly associated with partial application, though. John Resig explains it better, but the gist is that have some logic that will be applied to two or more arguments, and you only know the value(s) for some of those arguments.
You can use partial application/currying to fix those known values and return a function that only accepts the unknowns, to be invoked later when you actually have the values you wish to pass. This provides a nifty way to avoid repeating yourself when you would have been calling the same JavaScript built-ins over and over with all the same values but one. To steal John's example:
String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );
Agreeing with Hank Gay - It's extremely useful in certain true functional programming languages - because it's a necessary part. For example, in Haskell you simply cannot take multiple parameters to a function - you cannot do that in pure functional programming. You take one param at a time and build up your function. In JavaScript it's simply unnecessary, despite contrived examples like "converter". Here's that same converter code, without the need for currying:
var converter = function(ratio, symbol, input) {
return (input*ratio).toFixed(2) + " " + symbol;
}
var kilosToPoundsRatio = 2.2;
var litersToUKPintsRatio = 1.75;
var litersToUSPintsRatio = 1.98;
var milesToKilometersRatio = 1.62;
converter(kilosToPoundsRatio, "lbs", 4); //8.80 lbs
converter(litersToUKPintsRatio, "imperial pints", 2.4); //4.20 imperial pints
converter(litersToUSPintsRatio, "US pints", 2.4); //4.75 US pints
converter(milesToKilometersRatio, "km", 34); //55.08 km
I badly wish Douglas Crockford, in "JavaScript: The Good Parts", had given some mention of the history and actual use of currying rather than his offhanded remarks. For the longest time after reading that, I was boggled, until I was studying Functional programming and realized that's where it came from.
After some more thinking, I posit there is one valid use case for currying in JavaScript: if you are trying to write using pure functional programming techniques using JavaScript. Seems like a rare use case though.
I found functions that resemble python's functools.partial more useful in JavaScript:
function partial(fn) {
return partialWithScope.apply(this,
Array.prototype.concat.apply([fn, this],
Array.prototype.slice.call(arguments, 1)));
}
function partialWithScope(fn, scope) {
var args = Array.prototype.slice.call(arguments, 2);
return function() {
return fn.apply(scope, Array.prototype.concat.apply(args, arguments));
};
}
Why would you want to use it? A common situation where you want to use this is when you want to bind this in a function to a value:
var callback = partialWithScope(Object.function, obj);
Now when callback is called, this points to obj. This is useful in event situations or to save some space because it usually makes code shorter.
Currying is similar to partial with the difference that the function the currying returns just accepts one argument (as far as I understand that).
Consider filter function. And you want to write a callback for it.
let x = [1,2,3,4,5,6,7,11,12,14,15];
let results = x.filter(callback);
Assume want to output only even numbers, so:
let callback = x => x % 2 === 0;
Now imagine we want to implement our callback such that
depending on scenario it outputs even numbers which are above some threshold number (such
number should be configurable).
We can't easily make such threshold number a parameter to callback function, because filter invokes callback and by default passes it array elements and index.
How would you implement this?
This is a good use case for currying:
let x = [1,2,3,4,5,6,7,11,12,14,15];
let callback = (threshold) => (x) => (x % 2==0 && x > threshold);
let results1 = x.filter(callback(5)); // Even numbers higher than 5
let results2 = x.filter(callback(10)); // Even numbers higher than 10
console.log(results1,results2);
I know its old thread but I will have to show how this is being used in javascript libraries:
I will use lodash.js library to describe these concepts concretely.
Example:
var fn = function(a,b,c){
return a+b+c+(this.greet || ‘');
}
Partial Application:
var partialFnA = _.partial(fn, 1,3);
Currying:
var curriedFn = _.curry(fn);
Binding:
var boundFn = _.bind(fn,object,1,3 );//object= {greet: ’!'}
usage:
curriedFn(1)(3)(5); // gives 9
or
curriedFn(1,3)(5); // gives 9
or
curriedFn(1)(_,3)(2); //gives 9
partialFnA(5); //gives 9
boundFn(5); //gives 9!
difference:
after currying we get a new function with no parameters pre bound.
after partial application we get a function which is bound with some parameters prebound.
in binding we can bind a context which will be used to replace ‘this’, if not bound default of any function will be window scope.
Advise: There is no need to reinvent the wheel. Partial application/binding/currying are very much related. You can see the difference above. Use this meaning anywhere and people will recognise what you are doing without issues in understanding plus you will have to use less code.
It's no magic or anything... just a pleasant shorthand for anonymous functions.
partial(alert, "FOO!") is equivalent to function(){alert("FOO!");}
partial(Math.max, 0) corresponds to function(x){return Math.max(0, x);}
The calls to partial (MochiKit terminology. I think some other libraries give functions a .curry method which does the same thing) look slightly nicer and less noisy than the anonymous functions.
As for libraries using it, there's always Functional.
When is it useful in JS? Probably the same times it is useful in other modern languages, but the only time I can see myself using it is in conjunction with partial application.
I would say that, most probably, all the animation library in JS are using currying. Rather than having to pass for each call a set of impacted elements and a function, describing how the element should behave, to a higher order function that will ensure all the timing stuff, its generally easier for the customer to release, as public API some function like "slideUp", "fadeIn" that takes only elements as arguments, and that are just some curried function returning the high order function with the default "animation function" built-in.
Here's an example.
I'm instrumenting a bunch of fields with JQuery so I can see what users are up to. The code looks like this:
$('#foo').focus(trackActivity);
$('#foo').blur(trackActivity);
$('#bar').focus(trackActivity);
$('#bar').blur(trackActivity);
(For non-JQuery users, I'm saying that any time a couple of fields get or lose focus, I want the trackActivity() function to be called. I could also use an anonymous function, but I'd have to duplicate it 4 times, so I pulled it out and named it.)
Now it turns out that one of those fields needs to be handled differently. I'd like to be able to pass a parameter in on one of those calls to be passed along to our tracking infrastructure. With currying, I can.
JavaScript functions is called lamda in other functional language. It can be used to compose a new api (more powerful or complext function) to based on another developer's simple input. Curry is just one of the techniques. You can use it to create a simplified api to call a complex api. If you are the develper who use the simplified api (for example you use jQuery to do simple manipulation), you don't need to use curry. But if you want to create the simplified api, curry is your friend. You have to write a javascript framework (like jQuery, mootools) or library, then you can appreciate its power. I wrote a enhanced curry function, at http://blog.semanticsworks.com/2011/03/enhanced-curry-method.html . You don't need to the curry method to do currying, it just help to do currying, but you can always do it manually by writing a function A(){} to return another function B(){}. To make it more interesting, use function B() to return another function C().
I agree that at times you would like to get the ball rolling by creating a pseudo-function that will always have the value of the first argument filled in. Fortunately, I came across a brand new JavaScript library called jPaq (http://jpaq.org/) which provides this functionality. The best thing about the library is the fact that you can download your own build which contains only the code that you will need.
Just wanted to add some resources for Functional.js:
Lecture/conference explaining some applications
http://www.youtube.com/watch?v=HAcN3JyQoyY
Updated Functional.js library:
https://github.com/loop-recur/FunctionalJS
Some nice helpers (sorry new here, no reputation :p):
/loop-recur/PreludeJS
I've been using this library a lot recently to reduce the repetition in an js IRC clients helper library. It's great stuff - really helps clean up and simplify code.
In addition, if performance becomes an issue (but this lib is pretty light), it's easy to just rewrite using a native function.
You can use native bind for quick, one line solution
function clampAngle(min, max, angle) {
var result, delta;
delta = max - min;
result = (angle - min) % delta;
if (result < 0) {
result += delta;
}
return min + result;
};
var clamp0To360 = clampAngle.bind(null, 0, 360);
console.log(clamp0To360(405)) // 45
Another stab at it, from working with promises.
(Disclaimer: JS noob, coming from the Python world. Even there, currying is not used all that much, but it can come in handy on occasion. So I cribbed the currying function - see links)
First, I am starting with an ajax call. I have some specific processing to do on success, but on failure, I just want to give the user the feedback that calling something resulted in some error. In my actual code, I display the error feedback in a bootstrap panel, but am just using logging here.
I've modified my live url to make this fail.
function ajax_batch(e){
var url = $(e.target).data("url");
//induce error
url = "x" + url;
var promise_details = $.ajax(
url,
{
headers: { Accept : "application/json" },
// accepts : "application/json",
beforeSend: function (request) {
if (!this.crossDomain) {
request.setRequestHeader("X-CSRFToken", csrf_token);
}
},
dataType : "json",
type : "POST"}
);
promise_details.then(notify_batch_success, fail_status_specific_to_batch);
}
Now, here in order to tell the user that a batch failed, I need to write that info in the error handler, because all it is getting is a response from the server.
I still only have the info available at coding time - in my case I have a number of possible batches, but I don't know which one has failed w.o. parsing the server response about the failed url.
function fail_status_specific_to_batch(d){
console.log("bad batch run, dude");
console.log("response.status:" + d.status);
}
Let's do it. Console output is:
console:
bad batch run, dude
utility.js (line 109)
response.status:404
Now, let's change things a bit and use a reusable generic failure handler, but also one that is curried at runtime with both the known-at-code-time calling context and the run-time info available from event.
... rest is as before...
var target = $(e.target).text();
var context = {"user_msg": "bad batch run, dude. you were calling :" + target};
var contexted_fail_notification = curry(generic_fail, context);
promise_details.then(notify_batch_success, contexted_fail_notification);
}
function generic_fail(context, d){
console.log(context);
console.log("response.status:" + d.status);
}
function curry(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
console:
Object { user_msg="bad batch run, dude. you were calling :Run ACL now"}
utility.js (line 117)
response.status:404
utility.js (line 118)
More generally, given how widespread callback usage is in JS, currying seems like a quite useful tool to have.
https://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/
http://www.drdobbs.com/open-source/currying-and-partial-functions-in-javasc/231001821?pgno=2
I asked a similar question at https://softwareengineering.stackexchange.com/questions/384529/a-real-life-example-of-using-curry-function
But only after I use ramda do I finally appreciate the usefulness of curry. So I will argue that if we need to chain functions together to process some input data one step a time, e.g. the promise chain example in the article Favoring Curry, using curry by "function first,data last", the code does look clean!
Here you have a practical example of were currying is being used at the moment.
https://www.joshwcomeau.com/react/demystifying-styled-components/
Basically he is creating a poor man styled components and uses currying to "preload" the name of the tag when creating a new style for it.
Background
I'm trying to refactor some long, ugly Javascript (shamefully, it's my own). I started the project when I started learning Javascript; it was a great learning experience, but there is some total garbage in my code and I employ some rather bad practices, chief among them being heavy pollution of the global namespace / object (in my case, the window object). In my effort to mitigate said pollution, I think it would be helpful to measure it.
Approach
My gut instinct was to simply count the number of objects attached to the window object prior to loading any code, again after loading third-party libraries and lastly after my code has been executed. Then, as I refactor, I would try to reduce the increase that corresponds to loading my code). To do this, I'm using:
console.log(Object.keys(window).length)
at various places in my code. This seems to work alright and I see the number grow, in particular after my own code is loaded. But...
Problem
Just from looking at the contents of the window object in the Chrome Developer console, I can see that its not counting everything attached to the object. I suspect it's not including some more fundamental properties or object types, whether they belong to the browser, a library or my own code. Either way though, can anyone think of a better and more accurate way to measure global namespace pollution that would help in refactoring?
Thanks in advance!
So after some of the comments left by Felix Kling and Lèse majesté, I have found a solution that works well. Prior to loading any libraries or my own code, I create the dashboard global object (my only intentional one) and store a list of objects attached to window via:
var dashboard = {
cache: {
load: Object.getOwnPropertyNames(window)
}
};
Then, after I load all of the libraries but prior to loading any of my own code, I modify the dashboard object, adding the pollution method (within a new debug namespace):
dashboard.debug = {
pollution: (function() {
var pollution,
base = cache.load, // window at load
filter = function(a,b) { // difference of two arrays
return a.filter(function(i) {
return !(b.indexOf(i) > -1);
});
},
library = filter(Object.getOwnPropertyNames(window), base),
custom = function() {
return filter(Object.getOwnPropertyNames(window),
base.concat(library));
};
delete cache.load;
pollution = function() {
console.log('Global namespace polluted with:\n ' +
custom().length + ' custom objects \n ' +
library.length + ' library objects');
return {custom: custom().sort(), library: library.sort()};
};
return pollution;
}())
};
At any point, I can call this method from the console and see
Global namespace polluted with:
53 custom objects
44 library objects
as well as two arrays listing the keys associated with those objects. The base and library snapshots are static, while the current custom measurement (via custom) is dynamic such that if I were to load any custom javascript via AJAX, then I could remeasure and see any new custom "pollution".
The general pattern you've selected works OK from experience. However, there are two things you might need to consider (as additions or alternatives):
Use JsLint.com or JSHint.com with your existing code and look at the errors produced. It should help you spot most if not all of the global variable usage quickly and easily (you'll see errors of 'undefined' variables for example). This is a great simple approach. So, the measurement in this case will be just looking at the total number of issues.
We've found that Chrome can make doing detection of leaking resources on the window object tricky (as things are added during the course of running the page). We've needed to check for example to see if certain properties returned are native by using RegExs: /\s*function \w*\(\) {\s*\[native code\]\s*}\s*/ to spot native code. In some code "leak detection" code we've written, we also try to (in a try catch) obtain the value of a property to verify it's set to a value (and not just undefined). But, that shouldn't be necessary in your case.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am starting a project with jQuery.
What pitfalls/errors/misconceptions/abuses/misuses did you have in your jQuery project?
Being unaware of the performance hit and overusing selectors instead of assigning them to local variables. For example:-
$('#button').click(function() {
$('#label').method();
$('#label').method2();
$('#label').css('background-color', 'red');
});
Rather than:-
$('#button').click(function() {
var $label = $('#label');
$label.method();
$label.method2();
$label.css('background-color', 'red');
});
Or even better with chaining:-
$('#button').click(function() {
$("#label").method().method2().css("background-color", "red");
});
I found this the enlightening moment when I realized how the call stacks work.
Edit: incorporated suggestions in comments.
Understand how to use context. Normally, a jQuery selector will search the whole doc:
// This will search whole doc for elements with class myClass
$('.myClass');
But you can speed things up by searching within a context:
var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);
Don't use bare class selectors, like this:
$('.button').click(function() { /* do something */ });
This will end up looking at every single element to see if it has a class of "button".
Instead, you can help it out, like:
$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });
I learned this last year from Rebecca Murphy's blog
Update - This answer was given over 2 years ago and is not correct for the current version of jQuery.
One of the comments includes a test to prove this.
There is also an updated version of the test that includes the version of jQuery at the time of this answer.
Try to split out anonymous functions so you can reuse them.
//Avoid
$('#div').click( function(){
//do something
});
//Do do
function divClickFn (){
//do something
}
$('#div').click( divClickFn );
Avoid abusing document ready.
Keep the document ready for initialize code only.
Always extract functions outside of the doc ready so they can be reused.
I have seen hundreds of lines of code inside the doc ready statement. Ugly, unreadable and impossible to maintain.
While using $.ajax function for Ajax requests to server, you should avoid using the complete event to process response data. It will fire whether the request was successful or not.
Rather than complete, use success.
See Ajax Events in the docs.
"Chaining" Animation-events with Callbacks.
Suppose you wanted to animate a paragraph vanishing upon clicking it. You also wanted to remove the element from the DOM afterwards. You may think you can simply chain the methods:
$("p").click(function(e) {
$(this).fadeOut("slow").remove();
});
In this example, .remove() will be called before .fadeOut() has completed, destroying your gradual-fading effect, and simply making the element vanish instantly. Instead, when you want to fire a command only upon finishing the previous, use the callback's:
$("p").click(function(e){
$(this).fadeOut("slow", function(){
$(this).remove();
});
});
The second parameter of .fadeOut() is an anonymous function that will run once the .fadeOut() animation has completed. This makes for a gradual fading, and a subsequent removal of the element.
If you bind() the same event multiple times it will fire multiple times . I usually always go unbind('click').bind('click') just to be safe
Don't abuse plug-ins.
Most of the times you'll only need the library and maybe the user interface. If you keep it simple your code will be maintainable in the long run. Not all plug-ins are supported and maintained, actually most are not. If you can mimic the functionality using core elements I strongly recommend it.
Plug-ins are easy to insert in your code, save you some time, but when you'll need an extra something, it is a bad idea to modify them, as you lose the possible updates. The time you save at the start you'll loose later on changing deprecated plug-ins.
Choose the plug-ins you use wisely.
Apart from library and user interface, I constantly use $.cookie , $.form, $.validate and thickbox. For the rest I mostly develop my own plug-ins.
Pitfall: Using loops instead of selectors.
If you find yourself reaching for the jQuery '.each' method to iterate over DOM elements, ask yourself if can use a selector to get the elements instead.
More information on jQuery selectors:
http://docs.jquery.com/Selectors
Pitfall: NOT using a tool like Firebug
Firebug was practically made for this kind of debugging. If you're going to be mucking about in the DOM with Javascript, you need a good tool like Firebug to give you visibility.
More information on Firebug:
http://getfirebug.com/
Other great ideas are in this episode of the Polymorphic Podcast:
(jQuery Secrets with Dave Ward)
http://polymorphicpodcast.com/shows/jquery/
Misunderstanding of using this identifier in the right context. For instance:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
$(".listOfElements").each( function()
{
$(this).someMethod( ); // here 'this' is not referring first_element anymore.
})
});
And here one of the samples how you can solve it:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
var $that = this;
$(".listOfElements").each( function()
{
$that.someMethod( ); // here 'that' is referring to first_element still.
})
});
Avoid searching through the entire DOM several times. This is something that really can delay your script.
Bad:
$(".aclass").this();
$(".aclass").that();
...
Good:
$(".aclass").this().that();
Bad:
$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();
Good:
$("#form")
.find(".text").this().end()
.find(".int").that().end()
.find(".choice").method();
Always cache $(this) to a meaningful variable
especially in a .each()
Like this
$(selector).each(function () {
var eachOf_X_loop = $(this);
})
Similar to what Repo Man said, but not quite.
When developing ASP.NET winforms, I often do
$('<%= Label1.ClientID %>');
forgetting the # sign. The correct form is
$('#<%= Label1.ClientID %>');
Events
$("selector").html($("another-selector").html());
doesn't clone any of the events - you have to rebind them all.
As per JP's comment - clone() does rebind the events if you pass true.
Avoid multiple creation of the same jQuery objects
//Avoid
function someFunc(){
$(this).fadeIn();
$(this).fadeIn();
}
//Cache the obj
function someFunc(){
var $this = $(this).fadeIn();
$this.fadeIn();
}
I say this for JavaScript as well, but jQuery, JavaScript should NEVER replace CSS.
Also, make sure the site is usable for someone with JavaScript turned off (not as relevant today as back in the day, but always nice to have a fully usable site).
Making too many DOM manipulations. While the .html(), .append(), .prepend(), etc. methods are great, due to the way browsers render and re-render pages, using them too often will cause slowdowns. It's often better to create the html as a string, and to include it into the DOM once, rather than changing the DOM multiple times.
Instead of:
var $parent = $('#parent');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$parent.append($div);
}
Try this:
var $parent = $('#parent');
var iterations = 10;
var html = '';
for (var i = 0; i < iterations; i++){
html += '<div class="foo-' + i + '"></div>';
}
$parent.append(html);
Or even this ($wrapper is a newly created element that hasn't been injected to the DOM yet. Appending nodes to this wrapper div does not cause slowdowns, and at the end we append $wrapper to $parent, using only one DOM manipulation):
var $parent = $('#parent');
var $wrapper = $('<div class="wrapper" />');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$wrapper.append($div);
}
$parent.append($wrapper);
Using ClientID to get the "real" id of the control in ASP.NET projects.
jQuery('#<%=myLabel.ClientID%>');
Also, if you are using jQuery inside SharePoint you must call jQuery.noConflict().
Passing IDs instead of jQuery objects to functions:
myFunc = function(id) { // wrong!
var selector = $("#" + id);
selector.doStuff();
}
myFunc("someId");
Passing a wrapped set is far more flexible:
myFunc = function(elements) {
elements.doStuff();
}
myFunc($("#someId")); // or myFunc($(".someClass")); etc.
Excessive use of chaining.
See this:
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
Explanation
Use strings accumulator-style
Using + operator a new string is created in memory and the concatenated value is assigned to it. Only after this the result is assigned to a variable.
To avoid the intermediate variable for concatenation result, you can directly assign the result using += operator.
Slow:
a += 'x' + 'y';
Faster:
a += 'x';
a += 'y';
Primitive operations can be faster than function calls
Consider using alternative primitive operation over function calls in performance critical loops and functions.
Slow:
var min = Math.min(a, b);
arr.push(val);
Faster:
var min = a < b ? a : b;
arr[arr.length] = val;
Read More at JavaScript Performance Best Practices
If you want users to see html entities in their browser, use 'html' instead of 'text' to inject a Unicode string, like:
$('p').html("Your Unicode string")
my two cents)
Usually, working with jquery means you don't have to worry about DOM elements actual all the time. You can write something like this - $('div.mine').addClass('someClass').bind('click', function(){alert('lalala')}) - and this code will execute without throwing any errors.
In some cases this is useful, in some cases - not at all, but it is a fact that jquery tends to be, well, empty-matches-friendly. Yet, replaceWith will throw an error if one tries to use it with an element which doesn't belong to the document. I find it rather counter-intuitive.
Another pitfall is, in my opinion, the order of nodes returned by prevAll() method - $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll(). Not a big deal, actually, but we should keep in mind this fact.
If you plan to Ajax in lots of data, like say, 1500 rows of a table with 20 columns, then don't even think of using jQuery to insert that data into your HTML. Use plain JavaScript. jQuery will be too slow on slower machines.
Also, half the time jQuery will do things that will cause it to be slower, like trying to parse script tags in the incoming HTML, and deal with browser quirks. If you want fast insertion speed, stick with plain JavaScript.
Using jQuery in a small project that can be completed with just a couple of lines of ordinary JavaScript.
Not understanding event binding. JavaScript and jQuery work differently.
By popular demand, an example:
In jQuery:
$("#someLink").click(function(){//do something});
Without jQuery:
<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
//do something
}
</script>
Basically the hooks required for JavaScript are no longer necessary. I.e. use inline markup (onClick, etc) because you can simply use the ID's and classes that a developer would normally leverage for CSS purposes.