function( | |
constructor, //The group to make chainable - | |
// e.g. Window.Element, Window.Node, Window.DOMTokenList etc... | |
prototype, //Placeholder | |
method //Placeholder | |
) { | |
prototype = constructor.prototype; //Shorthand to work with the prototype of the constructor | |
for (method in prototype) // For every method on this object | |
if (prototype[method].call) // ...if it's a function | |
prototype[method] = (function(method) { // Make every function | |
return function() { // into another function | |
return method.apply(this, arguments) // which does its job then either returns itself if that was the default behaviour | |
|| // or | |
this; // returns itself here | |
} | |
})(prototype[method]) // pass in the method we want to be working with | |
} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "chainableDomManipulation", | |
"description": "Extremely minimal chainable DOM manipulation based on Chainvas", | |
"keywords": [ | |
"html", | |
"DOM", | |
"chaining" | |
] | |
} |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>Chain anything</title> | |
<div>Expected value: <b><a href="http://140byt.es/" title="tiny awsm" data-monkeys="∞">140byt.es</a></b></div> | |
<div>Actual value: <b id="ret"></b></div> | |
<script> | |
// This is paired with the propertize gist to cover chainability and setting properties | |
//This is a very, very minimal version of the functionality of Chainvas (http://lea.verou.me/chainvas/) to make anything chainable | |
var chainer = function(a,b,c){b=a.prototype;for(c in b)if(b[c].call)b[c]=(function(d){return function(){return d.apply(this,arguments)||this}})(b[c])} | |
// see https://gist.github.com/gists/1466253 | |
var propertize = function(a,b,c){a.prototype.prop=function(){b=arguments;if(1 in b)this[b[0]]=b[1];else{b=b[0];for(c in b)this[c]=b[c]}return this}} | |
chainer(window.Element); | |
propertize(window.Element); | |
document.getElementById('ret').appendChild( | |
document.createElement('a') | |
.prop({ | |
'href': 'http://140byt.es/', | |
'title': 'tiny awsm' | |
}) | |
.prop('innerHTML', '140byt.es') | |
.setAttribute('data-monkeys', '∞') | |
.addEventListener('click', function(){ alert('Urk! Alert!')}, false) | |
); | |
</script> |
This comment has been minimized.
This comment has been minimized.
I took out the extra check
as we only get to the check when we are iterating through the object so we know it already exists. It's now at 140bytes exactly. |
This comment has been minimized.
This comment has been minimized.
You can eliminate a bunch of curly brackets. |
This comment has been minimized.
This comment has been minimized.
You're right. I've just taken out four of them. Thanks |
This comment has been minimized.
This comment has been minimized.
Nice idea and great job! A little code minimizing hint: extra scope for closure may also be created using
|
This comment has been minimized.
This comment has been minimized.
Dang, that's a clever shuffle. I'd never have considered using a with there. I've updated the code and (I think) annotated it right. |
This comment has been minimized.
This comment has been minimized.
Hawt stuff! |
This comment has been minimized.
This comment has been minimized.
Ah, well spotted, thanks. Thanks to @subzey's clever shuffling, there's enough space to put in a strict My initial hope of combining chain and prop together looks to be a bit unobtainable. Still, they both function fine on their own. |
This comment has been minimized.
This comment has been minimized.
I suppose, |
This comment has been minimized.
This comment has been minimized.
Done. I must get round to putting together some performance tests at some point. *edit: http://jsperf.com/trialchainifytest Not sure I've got the setup quite right but, anyway, it's not too bad for performance. |
This comment has been minimized.
This comment has been minimized.
Love it... using the call property to detect a function is brilliantly simply yet rarely seen. Does it work cross browser? |
This comment has been minimized.
This comment has been minimized.
That’s duck typing, and not usually considered a good practice (although in this case it saves characters). Don't do it when # of bytes is not such a huge issue. |
This comment has been minimized.
This comment has been minimized.
True, a simple {call:true} would make it unstuck. |
This comment has been minimized.
This comment has been minimized.
Uh-oh, if any prototype property will be
|
This comment has been minimized.
This comment has been minimized.
I started messing around testing whether something is a function by using Besides, I don't think it works in IE7. |
This comment has been minimized.
This comment has been minimized.
But this works in IE7+
Well, saves 1 byte. |
This comment has been minimized.
This comment has been minimized.
Since with() is deprecated and unreliable, I remade your function to not use with(). chainify = function(a,b){for(b in a)(function(c){a[b]=function(){c.apply(this,arguments);return this}})(a[b])} chainify(window.Element.prototype) Feel free to use it :) |
This comment has been minimized.
This comment has been minimized.
Note: These updates include calling the function on window.Element or window.Element.prototype Seperate functions -------------------- Original prop - 174 bytes Updated prop - 141 bytes Original chanify - 166 bytes Updated chanify - 129 bytes Combined functions -------------------- Original prop and chanify - 336 bytes Updated prop and chanify - 228 bytes |
This comment has been minimized.
This comment has been minimized.
@tjbenton awesome! use codeblocks... @thingsinjars, need update of the gist because it is 2015 now :) Based on above function(a,b,c){a.prototype.prop=function(){b=arguments,1 in b?this[b[0]]=b[1]:b=b[0];for(c in b)this[c]=b[c];return this}} chainify - 111 bytes function(a,b){for(b in a=a.prototype)(function(c){a[b]=function(){return c.apply(this,arguments),this}})(a[b])} Combined propertize + chainify - 200 bytes - test pass!function(a,b,c){a.prop=function(){b=arguments,1 in b?this[b[0]]=b[1]:b=b[0];for(c in b)this[c]=b[c];return this};for(b in a=a)(function(c){a[b]=function(){return c.apply(this,arguments),this}})(a[b])} test pass |
This comment has been minimized.
This is currently at 146 bytes so there's a little room for improvement.
The test file references the chainable property setter (https://gist.github.com/1466253) as I was working on them both at the same time although I could probably separate them into smaller test cases.
It started off as a minimal implementation of Lea Verou's Chainvas