-
-
Save louisremi/1319121 to your computer and use it in GitHub Desktop.
// class manipulation library | |
function( elem, verb, classname, attr, result ) { | |
// systematically remove class name from className attribute | |
result = elem[ | |
attr = 'className' | |
].replace( | |
eval('/ *\\b' + classname + '\\b/g') | |
// in production environment, replace with the following safer line (+9B) | |
//RegExp('(^| ) *'+ classname +' *( |$)','g') | |
, '' ); | |
return 'has' == verb ? result != elem[attr]: | |
// all other verbs modify className attribute | |
elem[attr] = { | |
add: 1, | |
toggle: result == elem[attr] | |
}[ verb ] ? | |
// verb is 'add' or ( verb is 'toggle' and class name wasn't already present in className attribute) | |
result + ' ' + classname: | |
// verb is anything else ('remove', 'getRidOf') or ( verb is 'toggle' and class name was already present in className attribute) | |
result; | |
} |
function(e,v,n,c,r){r=e[c='className'].replace(eval('/ *\\b'+n+'\\b/g'),'');return'has'==v?r!=e[c]:e[c]={add:1,toggle:r==e[c]}[v]?r+' '+n:r} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 @louis_remi <http://louisremi.com> | |
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": "c", | |
"description": "An expressive className manipulation lib: c( elem, 'has/add/remove/toggle', class_name )", | |
"contributors": [ | |
"louisremi", | |
"atk", | |
"tsaniel", | |
"maettig" | |
], | |
"keywords": [ | |
"class", | |
"className", | |
"DOM" | |
] | |
} |
<!DOCTYPE html> | |
<title>Foo</title> | |
<div id="elem" class="banana"></div> | |
<pre><code><div id="elem" class="banana"></div></code></pre> | |
<div>elem has banana?: <b id=t1>undefined</b></div> | |
<div>elem has chocolate?: <b id=t2>undefined</b></div> | |
<div>elem add cacao: <b id=t3>undefined</b></div> | |
<div>elem remove banana: <b id=t4>undefined</b></div> | |
<div>elem has banana?: <b id=t5>undefined</b></div> | |
<div>elem toggle iceCream?: <b id=t6>undefined</b></div> | |
<div>elem toggle cacao?: <b id=t7>undefined</b></div> | |
<script> | |
var c = function(e,v,n,c,r){r=e[c='className'].replace(eval('/ *\\b'+n+'\\b/g'),'');return'has'==v?r!=e[c]:e[c]={add:1,toggle:r==e[c]}[v]?r+' '+n:r}, | |
$ = function(id) { return document.getElementById(id) }, | |
elem = $("elem"); | |
$("t1").innerHTML = !!c( elem, "has", "banana" ); | |
$("t2").innerHTML = !!c( elem, "has", "chocolate" ); | |
$("t3").innerHTML = c( elem, "add", "cacao" ); | |
$("t4").innerHTML = c( elem, "remove", "banana" ); | |
$("t5").innerHTML = !!c( elem, "has", "banana" ); | |
$("t6").innerHTML = c( elem, "toggle", "iceCream" ); | |
$("t7").innerHTML = c( elem, "toggle", "cacao" ); | |
</script> |
@atk nope, c({className:"atest test"}, "remove", "test") would fail. And keeping "add" and "has" is actually shorter.
Save 8 bytes.
function(a,b,c,d){var e=" ",f=e+a[d="className"]+e,g=e+c+e;return"has"==b?~f.indexOf(g):b=="add"?a[d]+=e+c:a[d]=f.split(g).join(e)}
I kept your idea of flipping verb=="has" and factorizing elem[c]=, saving 2bytes.
I won't factorize ( s+ elem[c] +s ) and ( s+ cName +s ) because assigning them isn't necessary for add, and conditional assignment is longer.
137bytes!
I don't quite understand the meaning of 'conditional assignment is longer'.
if @tsaniel factorizes a[d]= then his code is 130bytes
If someone saves another 2bytes then we can add .slice(1,-1) and I'd accept to factorize ( s+ elem[c] +s ) and ( s+ cName +s ). Otherwise it's not worth it ;^)
What about
function(a,b,c,d){var e=" ",f=e+a[d="className"]+e,g=e+c;return"has"==b?~f.search(g):a[d]=b=="add"?a[d]+g:f.split(g+e).join(e).slice(1,-1)}
Update: 139 bytes.
My mistake, replace(r,'') not replace(n,'') - now it works:
function(e,v,n,c,r){c='className';v=v[0];r=eval('/\\b'+n+'\\b/g');return'h'==v?r.test(e[c]):(e[c]=v=='a'?e[c]+' '+n:e[c].replace(r,''))}
But here's one even shorter (126bytes):
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'has'==v?r!=e[c]:(e[c]=r+('add'==v?' '+n:''))}
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'has'==v?r!=e[c]:(e[c]=r+('add'==v?' '+n:''))}
Wow, I like that one very much! It filters duplicate values when using add, perfect.
You guys are impressive.
Now using v=v[0], can we add the verb "toggle"?
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'h'==(v=v[0])?r!=e[c]:e[c]=r+('a'==v||'t'==v&&r==e[c]?' '+n:'')}
142 with toggle...
that's 144, not 142.
We can save four more bytes by replacing
'a'==v||'t'==v&&r==e[c]
with
v in{a:1,t:r==e[c]}
Voila:
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'h'==(v=v[0])?r!=e[c]:e[c]=r+({a:1,t:r==e[c]}[v]?' '+n:'')}
Update: damn, toggle not yet working...
Better try (works now, 139 bytes only):
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'h'==(v=v[0])?r!=e[c]:e[c]=r+({a:1,t:r==e[c]}[v]?' '+n:'')}
I came up with
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'h'==(v=v[0])?r!=e[c]:e[c]='a'==v||'t'==v&&r==e[c]?r+' '+n:r}
which was still 1 byte too long. Let's see if merging the two can save some bytes...
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'h'==(v=v[0])?r!=e[c]:e[c]={a:1,t:r==e[c]}[v]?r+' '+n:r}
136 bytes :^)
No wait, we can have IE compat back:
function(e,v,n,c,r){r=e[c='className'].replace(eval('/\\b'+n+'\\b/g'),'');return'has'==v?r!=e[c]:e[c]={add:1,toggle:r==e[c]}[v]?r+' '+n:r}
That's 138 bytes. I love this game!
Not bad at all ;-)
Update: would you mind renaming this gist?
Done, thanks a lot! http://twitter.com/#!/Louis_Remi/status/129639917499334656
No, thank you. It was really fun to help you golfing this one down :-)
Like the idea and the coverage (add,has,remove, including toggle) of this modifing class function :)
If you still like to enhance it, there is this odd thing with a space - as you "add/toggle" a new class to an element. It's not really a problem, but perhaps this could somehow be considered too (^_^)
Thanks Autarc. There are only two characters left so it's a tricky problem ;^)
Besides @tsaniel's abusing regular expressions to find prime numbers this is one of my favorite 140byt.es snippets. It's incredible how much functionality is compressed in this toolkit.
I have a suggestion what to do with the remaining 2 bytes: Change eval('/\\b'+n+'\\b/g'),'')
into eval('/ *\\b'+n+'\\b/g'),'')
. This will at least remove some of the spaces. Toggling the same class on and off will not add more and more spaces.
Thanks maettig, I should have applied your suggestion earlier. The output is now much cleaner.
Does not work in ie yet (due to v[0]), but saves some bytes:
function(e,v,n,c,r){c='className';v=v[0];r=eval('/\\b'+n+'\\b/g');return'h'==v?r.test(e[c]):(e[c]=v=='a'?e[c]+' '+n:e[c].replace(n,''))}