![]() | |
![]() |
| | Thread Tools | Display Modes |
#11
| |||
| |||
|
|
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_... (AT) yahoo (DOT) com> wrote: On Apr 27, 2:20 pm, "david.karr" <davidmichaelk... (AT) gmail (DOT) com> wrote: It's probably best to use reusable code for operations like this, and fortunately all of the major JS frameworks include this. The following URL provides a good summary of this: http://www.openjs.com/scripts/dom/class_manipulation.php Wow, I guess libraries are still using capturing groups. I thought it was pretty common knowledge to use non-capturing groups. They've got that right in the tutorial and I can even see in Prototype JS: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
A capturing group stores the whitespace: (\\s+|$) A non-capturing group does not: (?:\\s+|$) |
|
It is less efficient to use a capturing group. |
#12
| |||
| |||
|
|
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_... (AT) yahoo (DOT) com> wrote: On Apr 27, 2:20 pm, "david.karr" <davidmichaelk... (AT) gmail (DOT) com> wrote: It's probably best to use reusable code for operations like this, and fortunately all of the major JS frameworks include this. The following URL provides a good summary of this: http://www.openjs.com/scripts/dom/class_manipulation.php Wow, I guess libraries are still using capturing groups. I thought it was pretty common knowledge to use non-capturing groups. They've got that right in the tutorial and I can even see in Prototype JS: removeClassName: function(element, className) { if (!(element = $(element))) return; element.className = element.className.replace( new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); return element; } A capturing group stores the whitespace: (\\s+|$) A non-capturing group does not: (?:\\s+|$) It is less efficient to use a capturing group. A capturing group increases the count of the backreference number, so for more complicated expressions, it would be harder to keep track of which group is which number, e.g. \1 or $1. It would actually be possible to make the Prototype JS function even less efficient by adding the batch() functionality of YUI. But I'd have to day they've done a pretty bad for a major library. The assignment in the conditional, the extra call to $(), the capturing regexp (^|\\s+), the misnaming of trim() as "strip()" (and the adding of this misnamed trim() function to String.prototype). At first guess, it seems that Prototype JS's "strip()" is a normalize() function, but it's not. It's a trim() function, misnamed. trim() (or strip()) doesn't wipe out the whitespace in the middle, so you end up with "foo bar baz quux" -> remove "bar" -> "foo baz quux" - remove "baz -> "foo quux". The add It's quite surprising to see such code in such a popular library, at least to me. In takinga look at jQuery, i find another algorithm that is even slower. So I have to take back what I said above about "the only thing that could make the Prototype JS function slower". I didn't think about the jQuery approach. Create a method "addClass" that delegates to className.add, which splits the classname to an array, then uses an each() function, then inside that function, check to make sure the nodeType is 1. Here it is:http://code.jquery.com/jquery-latest.js className: { // internal only, use addClass("class") add: function( elem, classNames ) { jQuery.each((classNames || "").split(/\s+/), function(i, className) { if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) elem.className += (elem.className ? " " : "") + className; }); }, The function is intended to be called on a Decorated collection, which would mean an extra call to each(). In most cases, that could be replaced by adding a fragment identifier to the css file, and then adding a class to the ancestor. .window .link {} /* adding a class to .window object's changes the links */ .window-raised .link { color: red } /* jQuery tends to encourage this instead */ .window .link-active { color: red } Cool, thanks! I'd actually managed to google up JQuery but I wasn't sure about JavaScript "libraries" and all that.... I'm not so sure about those JavaScript libraries, either. |
#13
| |||
| |||
|
|
On May 1, 5:03 pm, dhtml <dhtmlkitc... (AT) gmail (DOT) com> wrote: On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_... (AT) yahoo (DOT) com> wrote: On Apr 27, 2:20 pm, "david.karr" <davidmichaelk... (AT) gmail (DOT) com> wrote: It's probably best to use reusable code for operations like this, and fortunately all of the major JS frameworks include this. The following URL provides a good summary of this: http://www.openjs.com/scripts/dom/class_manipulation.php Wow, I guess libraries are still using capturing groups. I thought it was pretty common knowledge to use non-capturing groups. They've got that right in the tutorial and I can even see in Prototype JS: removeClassName: function(element, className) { if (!(element = $(element))) return; element.className = element.className.replace( new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); return element; } A capturing group stores the whitespace: (\\s+|$) A non-capturing group does not: (?:\\s+|$) It is less efficient to use a capturing group. A capturing group increases the count of the backreference number, so for more complicated expressions, it would be harder to keep track of which group is which number, e.g. \1 or $1. It would actually be possible to make the Prototype JS function even less efficient by adding the batch() functionality of YUI. But I'd have to day they've done a pretty bad for a major library. The assignment in the conditional, the extra call to $(), the capturing regexp (^|\\s+), the misnaming of trim() as "strip()" (and the adding of this misnamed trim() function to String.prototype). At first guess, it seems that Prototype JS's "strip()" is a normalize() function, but it's not. It's a trim() function, misnamed. trim() (or strip()) doesn't wipe out the whitespace in the middle, so you end up with "foo bar baz quux" -> remove "bar" -> "foo baz quux" - remove "baz -> "foo quux". The add It's quite surprising to see such code in such a popular library, at least to me. In takinga look at jQuery, i find another algorithm that is even slower. So I have to take back what I said above about "the only thing that could make the Prototype JS function slower". I didn't think about the jQuery approach. Create a method "addClass" that delegates to className.add, which splits the classname to an array, then uses an each() function, then inside that function, check to make sure the nodeType is 1. Here it is:http://code.jquery.com/jquery-latest.js className: { // internal only, use addClass("class") add: function( elem, classNames ) { jQuery.each((classNames || "").split(/\s+/), function(i, className) { if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) elem.className += (elem.className ? " " : "") + className; }); }, The function is intended to be called on a Decorated collection, which would mean an extra call to each(). In most cases, that could be replaced by adding a fragment identifier to the css file, and then adding a class to the ancestor. .window .link {} /* adding a class to .window object's changes the links */ .window-raised .link { color: red } /* jQuery tends to encourage this instead */ .window .link-active { color: red } Cool, thanks! I'd actually managed to google up JQuery but I wasn't sure about JavaScript "libraries" and all that.... I'm not so sure about those JavaScript libraries, either. Assignment in conditional is done to extend ('normalize') an element (so that you can simply pass string into Element#removeClassName) and "return" if it's not a valid element. Such "normalization" is consistent throughout a library. Capturing groups, afaik, are not supported by some of the browsers that Prototype supports. #strip is |
#14
| |||
| |||
|
|
remove "baz -> "foo quux". |

![]() |
| Thread Tools | |
| Display Modes | |
| |