So, I turned the code around a bit and managed to find a way to get more consistent timings:http://www.tfuture.org/julian/classname2.html
Each solution is ran separately at user's request. Conclusions are: - For a single node: + .removeClass().addClass() have equivalent timing for the old & new implementations using strings + It gets just a little bit better with a regexp (though I have no clue why) + .replaceClass() is much faster than .removeClass().addClass(), which was to be expected - For multiple nodes, keeping the computed regexp for all nodes pays off. The new implementation is always faster. I haven't tested in IE6 or Opera yet. And there undoubtedly are bugs. But it's quite promising nonetheless. 2009/3/27 Daniel Friesen <[email protected]> > > Transforming every simple class check into a regex? That sounds like a > horribly roundabout way to do something extremely simple. > What happened to good old classic string testing? (" " + this.className > + " ").indexOf(" foo "); > A tiny bit of trickery, and that could be turned into a good possibility. > > (" " + node.className.replace(/\s+/, " ") + " ").indexOf(" " + className > + " "); > > ~Daniel Friesen (Dantman, Nadir-Seen-Fire) > > Julian Aubourg wrote: > > And gmail borked the sample page link :/ > > http://www.tfuture.org/julian/classname.html > > > > 2009/3/27 Julian Aubourg <[email protected]> > > > > > >> So, I talked about making a plugin I would be the only one to use, > didn't > >> I? ;) > >> http://www.tfuture.org/julian/jquery.classname.js > >> > >> The test page is here: http://www.tfuture.org/julian/classname.html< > http://www.tfuture.org/julian/jquery.classname.js> > >> > >> (I borrowed a piece of internet from a friend) > >> > >> The plugin replaces jQuery.className and .hasClass(), .addClass(), > >> .removeClass(). It also adds .replaceClass(). The thing is, it enables > >> regexps so you can do something like .removeClass(/color\-.*/) and it > will > >> work. I'm currently thinking about re-implementing .toggleClass() using > the > >> same implementation trick. > >> > >> So anyway, what is the trick? > >> > >> Rather than splitting the classNames given AND the element.className, I > >> transform the classNames into a single regular expression that's > >> matched/used onto element.className. The beauty of it is, using this > >> technique I can take regexps or strings as classNames, it just works. > Also, > >> the regexp is computed only once per call to every xxxClass() method but > >> that's a trick that could be applied onto the current implementation. > >> > >> Now my real problem is that I try & get timings comparisons and I can't > get > >> it right. Results change given the order in which you do the tests Oo. I > >> probably made a huge mistake in the way I handled my timers but it's > like > >> 4am and an half here in Paris and my eyes just refuse to find the > problem > >> (ANY HELP IS WELCOME ;) ). > >> > >> Sad about the timer thingy because at first glance it seemed to be a 20% > >> performance gain on a single node. I'm pretty confident that the new > >> implementations are at least on par with current ones (save from > hasClass, > >> given it uses .is() actually) but I'd like to be sure. > >> > >> -- Julian > >> > >> 2009/3/26 Julian Aubourg <[email protected]> > >> > >> > >>> > $(node).filter('.color-black').removeClass('color-black').addClass('color-white').end() > >>> And you find that more readable than > >>> $(node).replaceClass('color-black','color-white') ? ;) > >>> > >>> The main issue here is that I dunno what the class will be in the first > >>> place. I just know it will be "color-XXX" but I have no idea what the > XXX > >>> is. All I have are clickable elements that basically say: "set > backroung to > >>> red", "set background to green", etc etc. It could also be "set > background > >>> to image1 and font-weight to bold" or anything else, the point is I'm > not > >>> supposed to know the exact changes it is supposed to do visually to the > >>> targeted element (that's the whole point: keeping the style info in the > css > >>> and use classes to switch the visual properties). > >>> > >>> So clearly, the first step is to find which of the color-XXX the > element > >>> is tagged with, then replace it with color-YYY as asked by the other > >>> clickable element. So, yes, regexp support on hasClass / removeClass > would > >>> be greatly appreciated (you don't wanna know how horrible my current > code is > >>> -- basically relying on ids and a secondary structure to keep track of > the > >>> actual color class -- hence duplicating the information). > >>> > >>> Now, onto the replaceClass. Well, node.removeClass(X).addClass(Y) is > >>> basically: > >>> - 1 split of X to arrayX > >>> - 1 split of Y to arrayY > >>> - (arrayX.length + arrayY.length) splits of the node's class attribute > >>> - (arrayX.length + arrayY.length) times searches in the resulting split > >>> > >>> On a side note, I don't even get why add and remove actually delegate > to > >>> jQuery.classname.has() knowing the function does a split of the class > >>> attribute each time it is called rather then splitting the class > attribute > >>> themselves and be done with it once and for all. It sure saves some > bytes in > >>> the filesize department but it does not seem right to me from a > performance > >>> point of view. > >>> > >>> Even if removeClass and addClass only did one split of the class > attribute > >>> each, it would still be one split too many for a replacement. > >>> > >>> All I'm saying in the end is that a replaceClass() function would be > >>> simpler in usage and much more efficient (depending on the performance > >>> penalty of a regexped split) than chaining removeClass() and > addClass(). > >>> > >>> I guess that, today, most people do set style properties manually but > >>> class switching is so much more elegant, solid (since you don't have to > keep > >>> track of which style properties were set previously so that you reset > them > >>> before applying new ones) and efficient (you only change a string > portion in > >>> an attribute and you don't have to go through jQuery's style engine). > I'm > >>> just a bit puzzled jQuery makes it difficult by design in that it does > not > >>> provide regexp support for class search and forces into an efficient > >>> solution to change a class for another. > >>> > >>> Probably nitpicking anyway but then again, I'm just telling because I > have > >>> a real-life case on the table right now ;) > >>> > >>> Oh well, I guess it's time to make another plugin no-one will use apart > >>> from me ;) > >>> > >>> Thanks for the feedback, Dan, > >>> > >>> -- Julian > >>> > >>> 2009/3/26 Daniel Friesen <[email protected]> > >>> > >>> > >>> > >>>> Having .hasClass / .removeClass support regex has been discussed > before, > >>>> there is a ticket open for one of them so it might be a possibility. > >>>> > >>>> I don't see much use for replaceClass, rather I think the semantics of > >>>> reading it would be a little confusing. I can't even understand what > the > >>>> code you have there is even supposed to do. > >>>> I see no reason to combine add and remove into one. > >>>> > >>>> Just a quick tip, if you're trying to do boolean stuff: > >>>> > >>>> > $(node).filter('.color-black').removeClass('color-black').addClass('color-white').end()... > >>>> That there would replace color-black with color-white but only for > nodes > >>>> with color-black, the .end() returns back to the original $(node) so > >>>> chaining can continue. > >>>> > >>>> ~Daniel Friesen (Dantman, Nadir-Seen-Fire) > >>>> > >>>> Julian Aubourg wrote: > >>>> > >>>>> Hey all, > >>>>> I'm working on a site that offers some customizability regarding > >>>>> > >>>> elements > >>>> > >>>>> colors (background & font). Rather then setting the color with > .css(), > >>>>> > >>>> I use > >>>> > >>>>> classes like color-red, color-green, etc (and of course, red is not > the > >>>>> > >>>> css > >>>> > >>>>> "red" and green is not the css "green"). I find it much cleaner since > >>>>> > >>>> I > >>>> > >>>>> need not have color values referenced within javascript or php (it's > >>>>> > >>>> simply > >>>> > >>>>> in the css). > >>>>> > >>>>> However, the code seems unnecessarily bloated for switching classes. > >>>>> > >>>> What > >>>> > >>>>> would be very useful imo, is to have hasClass accept regexp & return > >>>>> > >>>> the > >>>> > >>>>> array of found classes and also a .replaceClass() function that would > >>>>> > >>>> change > >>>> > >>>>> a class into another. That way I could do the following: > >>>>> > >>>>> var colorClasses = $.hasClass(/color-.+/); > >>>>> if (colorClasses!==false) { > >>>>> var currentColorClass = colorClasses[0]; > >>>>> } > >>>>> // Do stuff with the color class > >>>>> $.replaceClass(currentColorClass,"color-"+newColor); > >>>>> > >>>>> As of today, I have only two solutions: > >>>>> - keep the current color using $.data() or any other custom data > >>>>> > >>>> container > >>>> > >>>>> - OR search the class attribute by hand (hoping classes are in a > >>>>> > >>>> specific > >>>> > >>>>> order, you can imagine the mess) > >>>>> > >>>>> If that wasn't bad enough, after that, to replace the class, I have > to > >>>>> > >>>> call > >>>> > >>>>> $.removeClass() and $.addClass() which seems pretty inefficient to > me. > >>>>> > >>>>> I know I could probably do a plugin for that but I have the feeling > >>>>> > >>>> that, if > >>>> > >>>>> embedded in jQuery with its class related code, it would be much more > >>>>> efficient. > >>>>> > >>>>> I also know I could switch back to the .css("background-color",color) > >>>>> > >>>> but it > >>>> > >>>>> kinda defeats the purpose of having the presentation information in > the > >>>>> > >>>> css > >>>> > >>>>> and ONLY in the css which I find pretty nice for maintenance. > >>>>> > >>>>> Yes, and finally, am I crazy or couldn't this be quite useful? > >>>>> > >>>>> Take care, all, > >>>>> > >>>>> -- Julian > >>>>> > >>>>> > >>>>> > > > > > > > > > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jquery-dev?hl=en -~----------~----~----~----~------~----~------~--~---
