By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,934 Members | 1,804 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,934 IT Pros & Developers. It's quick & easy.

How Does JavaScript Call Forth CSS??

P: n/a

Okay, Folks,

I guess my real burning concern all along is a "high-level" one: just
how does JavaScript interact with CSS?

Right now, my newbie self only knows JavaScript and CSS to *co-
exist*...but I'm beginning to get the sense that they actually
interact -- or, perhaps more precisely, JavaScript acts upon CSS...but
how, exactly??

I see how JavaScript acts upon HTML, but I'm not so sure where
JavaScript acts upon CSS...moreover, I want to see where they could
create whole new browsing experiences, beyond simply new text and new
images (though I'm only just beginning at the level of new ways of
presenting text and images)....

How do I go about all this?? Ugh, I hope all those $$$ worth of books
will help...so far, I'm learning very basic things which I actually
wouldn't use (though the learning itself is fun), while the things I
would like to do, I either don't have the technical know-how for it or
I don't have the creative imagination to bring together what little I
do know -- sigh!!
Jun 27 '08 #1
Share this Question
Share on Google+
19 Replies


P: n/a
"Prisoner at War" <pr*************@yahoo.comwrote in message
news:c8**********************************@m44g2000 hsc.googlegroups.com...
>
Okay, Folks,

I guess my real burning concern all along is a "high-level" one: just
how does JavaScript interact with CSS?

Right now, my newbie self only knows JavaScript and CSS to *co-
exist*...but I'm beginning to get the sense that they actually
interact -- or, perhaps more precisely, JavaScript acts upon CSS...but
how, exactly??

I see how JavaScript acts upon HTML, but I'm not so sure where
JavaScript acts upon CSS...moreover, I want to see where they could
create whole new browsing experiences, beyond simply new text and new
images (though I'm only just beginning at the level of new ways of
presenting text and images)....

How do I go about all this?? Ugh, I hope all those $$$ worth of books
will help...so far, I'm learning very basic things which I actually
wouldn't use (though the learning itself is fun), while the things I
would like to do, I either don't have the technical know-how for it or
I don't have the creative imagination to bring together what little I
do know -- sigh!!
Basically, you get the element in Javascript, and set its style property.

<div id="content">blah</div>

javascript:

var contentDiv = document.getElementById( "content" );
contentDiv.style.marginLeft = "1em";

Generally (there may be exceptions but I'm not aware of any) the property of
the object corresponds to the name of the CSS property but camel cased.

Jun 27 '08 #2

P: n/a
[Cross-posting snipped.]

On Sat, 26 Apr 2008 16:53:33 -0700, Prisoner at War wrote:
Okay, Folks,

I guess my real burning concern all along is a "high-level" one: just
how does JavaScript interact with CSS?

Right now, my newbie self only knows JavaScript and CSS to *co-
exist*...but I'm beginning to get the sense that they actually interact
-- or, perhaps more precisely, JavaScript acts upon CSS...but how,
exactly??

I see how JavaScript acts upon HTML, but I'm not so sure where
JavaScript acts upon CSS...moreover, I want to see where they could
create whole new browsing experiences, beyond simply new text and new
images (though I'm only just beginning at the level of new ways of
presenting text and images)....
Javascript is a programming language. A simple but useful one.
Javascript, *BY ITS SELF* can not interact with anything.

Style sheets are a set of hints that direct a user agent over how
information should be displayed.

Both Javascript and CSS co-exist in the user agent, typically a web
browser.

(In addition there is a third important player to this game called the
DOM [Document Object Model]. The DOM gives Javascript a way to interact
with the host environment.)
How do I go about all this?? Ugh, I hope all those $$$ worth of books
will help...so far, I'm learning very basic things which I actually
wouldn't use (though the learning itself is fun), while the things I
would like to do, I either don't have the technical know-how for it or I
don't have the creative imagination to bring together what little I do
know -- sigh!!
I don't know any of the Javascript books, but I don't hear any of them
mentioned highly around here. I've learned a lot by lurking the
newsgroup here and the FAQ's.

Javascript may call DOM functions. Those functions, in turn, may update
the 'page' by replacing elements, adding elements, moving or unhiding.
In short, making a site interactive.
Start off reading the group's FAQ. That will give you a good solid
background in some of the more important aspects of Javascript.
When Googling for example code, keep in mind that 90% of everything is
crap. I got bit pretty heavily by learning from some bad examples and
put together a guide to help others avoid my mistake. Might help you.

http://www.mopedepot.com/jjs/HowToRe...criptCode.html

(Hmmm.. I still haven't uploaded the final version of that. That one is
fairly good though.)


Jun 27 '08 #3

P: n/a
On 2008-04-27, Nik Coughlin <nr******@gmail.comwrote:
"Prisoner at War" <pr*************@yahoo.comwrote in message
news:c8**********************************@m44g2000 hsc.googlegroups.com...
>>
Okay, Folks,

I guess my real burning concern all along is a "high-level" one: just
how does JavaScript interact with CSS?
[...]
Basically, you get the element in Javascript, and set its style property.

<div id="content">blah</div>

javascript:

var contentDiv = document.getElementById( "content" );
contentDiv.style.marginLeft = "1em";

Generally (there may be exceptions but I'm not aware of any) the property of
the object corresponds to the name of the CSS property but camel cased.
Yes. Another way to do it is to change the class attributes of elements
with setAttribute.

Then you can organize the styles in style sheets rather than packing
them all into the elements' style attributes, and just switch the
elements' classes so they get selected by different selectors.

This kind of thing:

..active
{
border: 2px solid red;
background-color: yellow;
color: black;
etc.
..
}

contentDiv.setAttribute("class", "active")
Jun 27 '08 #4

P: n/a
Ben C wrote:
On 2008-04-27, Nik Coughlin <nr******@gmail.comwrote:
>"Prisoner at War" <pr*************@yahoo.comwrote in message
news:c8**********************************@m44g200 0hsc.googlegroups.com...
>>>
Okay, Folks,

I guess my real burning concern all along is a "high-level" one:
just how does JavaScript interact with CSS?
[...]
>Basically, you get the element in Javascript, and set its style
property.

<div id="content">blah</div>

javascript:

var contentDiv = document.getElementById( "content" );
contentDiv.style.marginLeft = "1em";

Generally (there may be exceptions but I'm not aware of any) the
property of the object corresponds to the name of the CSS property
but camel cased.

Yes. Another way to do it is to change the class attributes of
elements with setAttribute.

Then you can organize the styles in style sheets rather than packing
them all into the elements' style attributes, and just switch the
elements' classes so they get selected by different selectors.

This kind of thing:

.active
{
border: 2px solid red;
background-color: yellow;
color: black;
etc.
..
}

contentDiv.setAttribute("class", "active")
Yeah, be careful doing this though. Imagine you've got:
<div id="contentDiv" class="class1 class2 inactive">bhakjfh</div>

You want to switch between active and inactive and you do:

contentDiv.setAttribute("class", "active")

and suddenly it's:

<div id="contentDiv" class="active">bhakjfh</div>

Whereas what you really want is:

<div id="contentDiv" class="class1 class2 active">bhakjfh</div>

So you probably want to use the split method on contentDiv.className instead
to get an array of class names, then replace inactive with active, glue the
strings in the array back together and reassign it
Jun 27 '08 #5

P: n/a
On Apr 27, 6:21*am, "Nik Coughlin" <nrkn....@gmail.comwrote:
Yeah, be careful doing this though. *Imagine you've got:
<div id="contentDiv" class="class1 class2 inactive">bhakjfh</div>

You want to switch between active and inactive and you do:

contentDiv.setAttribute("class", "active")

and suddenly it's:

<div id="contentDiv" class="active">bhakjfh</div>

Whereas what you really want is:

<div id="contentDiv" class="class1 class2 active">bhakjfh</div>

So you probably want to use the split method on contentDiv.className instead
to get an array of class names, then replace inactive with active, glue the
strings in the array back together and reassign it
Or do:

function activate_item(){
this.className=this.className.replace(/passive/,'active'); // change
passive to active
}

function passivate_item(){
this.className=this.className.replace(/active/,'passive'); // change
active to passive
}
Jun 27 '08 #6

P: n/a
Garmt de Vries wrote on 27 apr 2008 in comp.lang.javascript:
Or do:

function activate_item(){
this.className=this.className.replace(/passive/,'active'); // change
passive to active
}

function passivate_item(){
this.className=this.className.replace(/active/,'passive'); // change
active to passive
}
Perhaps:

function toggle_item(){
this.className=
(/active/.test(this.className))
? this.className.replace(/active/,'passive')
: this.className.replace(/passive/,'active');
};

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
Jun 27 '08 #7

P: n/a
On Apr 27, 4:21 am, "Nik Coughlin" <nrkn....@gmail.comwrote:
Ben C wrote:
On 2008-04-27, Nik Coughlin <nrkn....@gmail.comwrote:
"Prisoner at War" <prisoner_at_...@yahoo.comwrote in message
news:c8**********************************@m44g200 0hsc.googlegroups.com...
>Okay, Folks,
>I guess my real burning concern all along is a "high-level" one:
just how does JavaScript interact with CSS?
[...]
Basically, you get the element in Javascript, and set its style
property.
<div id="content">blah</div>
javascript:
var contentDiv = document.getElementById( "content" );
contentDiv.style.marginLeft = "1em";
Generally (there may be exceptions but I'm not aware of any) the
property of the object corresponds to the name of the CSS property
but camel cased.
Yes. Another way to do it is to change the class attributes of
elements with setAttribute.
Then you can organize the styles in style sheets rather than packing
them all into the elements' style attributes, and just switch the
elements' classes so they get selected by different selectors.
This kind of thing:
.active
{
border: 2px solid red;
background-color: yellow;
color: black;
etc.
..
}
contentDiv.setAttribute("class", "active")

Yeah, be careful doing this though. Imagine you've got:
<div id="contentDiv" class="class1 class2 inactive">bhakjfh</div>

You want to switch between active and inactive and you do:

contentDiv.setAttribute("class", "active")

and suddenly it's:

<div id="contentDiv" class="active">bhakjfh</div>

Whereas what you really want is:

<div id="contentDiv" class="class1 class2 active">bhakjfh</div>

So you probably want to use the split method on contentDiv.className instead
to get an array of class names, then replace inactive with active, glue the
strings in the array back together and reassign it
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/cl...nipulation.php
Jun 27 '08 #8

P: n/a
Prisoner at War wrote:
Okay, Folks,

I guess my real burning concern all along is a "high-level" one: just
how does JavaScript interact with CSS?
Depends on what level of "interaction" you're specifying. Direct
manipulation of style rules is handled by something called the `CSS
Object Model' (still a WIP, IIRC); but computed style rules can be
affected by DOM mutations. It is the latter that is more often the case.
Right now, my newbie self only knows JavaScript and CSS to *co-
exist*...but I'm beginning to get the sense that they actually
interact -- or, perhaps more precisely, JavaScript acts upon CSS...but
how, exactly??

I see how JavaScript acts upon HTML, but I'm not so sure where
JavaScript acts upon CSS...moreover, I want to see where they could
create whole new browsing experiences, beyond simply new text and new
images (though I'm only just beginning at the level of new ways of
presenting text and images)....
In short, most JavaScript tends to act on CSS only by proxy through the
HTML. In my code, I generally modify styles by changing the classes of
elements.

P.S. The `DOM', or `Document Object Model', is the precise specification
that most people think of when the think of JavaScript; any time you're
dynamically modify DOM (e.g. through document.getElementByID), you're
actually using the DOM. Most literature tends to gloss over this
distinction.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
Jun 27 '08 #9

P: n/a
Garmt de Vries wrote:
On Apr 27, 6:21 am, "Nik Coughlin" <nrkn....@gmail.comwrote:
>Yeah, be careful doing this though. Imagine you've got:
<div id="contentDiv" class="class1 class2 inactive">bhakjfh</div>

You want to switch between active and inactive and you do:

contentDiv.setAttribute("class", "active")

and suddenly it's:

<div id="contentDiv" class="active">bhakjfh</div>

Whereas what you really want is:

<div id="contentDiv" class="class1 class2 active">bhakjfh</div>

So you probably want to use the split method on contentDiv.className instead
to get an array of class names, then replace inactive with active, glue the
strings in the array back together and reassign it

Or do:

function activate_item(){
this.className=this.className.replace(/passive/,'active'); // change
passive to active
}

function passivate_item(){
this.className=this.className.replace(/active/,'passive'); // change
active to passive
}
While easier to program, the downside to this as a general approach is
that you can wind up changing things you didn't mean to change.

class="one alone"

Replace class "one" with class "two":

class="two altwo"

which is probably not what was intended.
Jun 27 '08 #10

P: n/a
"Harlan Messinger" <hm*******************@comcast.netwrote in message
news:67*************@mid.individual.net...
>Or do:

function activate_item(){
this.className=this.className.replace(/passive/,'active'); // change
passive to active
}

function passivate_item(){
this.className=this.className.replace(/active/,'passive'); // change
active to passive
}

While easier to program, the downside to this as a general approach is
that you can wind up changing things you didn't mean to change.

class="one alone"

Replace class "one" with class "two":

class="two altwo"

which is probably not what was intended.
Yep but you can match regular expressions against whole words only which
would avoid that issue

Jun 27 '08 #11

P: n/a
On Apr 29, 3:36 pm, "Nik Coughlin" <nrkn....@gmail.comwrote:
"Harlan Messinger" <hmessinger.removet...@comcast.netwrote in message

news:67*************@mid.individual.net...
Or do:
function activate_item(){
this.className=this.className.replace(/passive/,'active'); // change
passive to active
}
function passivate_item(){
this.className=this.className.replace(/active/,'passive'); // change
active to passive
}
While easier to program, the downside to this as a general approach is
that you can wind up changing things you didn't mean to change.
class="one alone"
Replace class "one" with class "two":
class="two altwo"
which is probably not what was intended.

Yep but you can match regular expressions against whole words only which
would avoid that issue
And that is something that was discussed on DHTML Central about 6
years ago. The first approach is the basic idea, but doesn't work, as
Harlan pointed out.

The pattern "(^|\\s)"+token+"($|\\s)" has been adopted by all the
libraries and further optimized to use non-capturing groups. The
pattern is now: new RegExp("(?:^|\\s)"+token+"(?:$|\\s)");

It can be a performance boost to cache the patterns (though only if
the cache is used). YUI seems to have discovered this, too.

Basic idea is that it's faster to get an object from a cache than
create one, even if it means an extra function call.
http://www.dhtmlkitchen.com/learn/js...exp-cache.html

http://www.dhtmlkitchen.com/ape/buil...classname-f.js

Garrett
Jun 27 '08 #12

P: n/a
On Apr 27, 2:20 pm, "david.karr" <davidmichaelk...@gmail.comwrote:
>

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/cl...nipulation.php

Cool, thanks! I'd actually managed to google up JQuery but I wasn't
sure about JavaScript "libraries" and all that....
Jun 27 '08 #13

P: n/a
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_...@yahoo.comwrote:
On Apr 27, 2:20 pm, "david.karr" <davidmichaelk...@gmail.comwrote:
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/cl...nipulation.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.
Jun 27 '08 #14

P: n/a
dhtml wrote:
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_...@yahoo.comwrote:
>On Apr 27, 2:20 pm, "david.karr" <davidmichaelk...@gmail.comwrote:
>>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/cl...nipulation.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:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Therefore, chances are it is a really bad idea to do that. In fact, it
turns out that non-capturing parentheses are not supported before JavaScript
1.5, JScript 5.5, ECMAScript Ed. 3. Use them and your script will break in
IE before version 5.5, for example.
A capturing group stores the whitespace:
(\\s+|$)

A non-capturing group does not:
(?:\\s+|$)
True, after a fashion.
It is less efficient to use a capturing group.
Nonsense. The tiny amount of memory saved by not storing the backreference
is bought with the tiny amount of runtime that is required more to parse the
non-capturing expression.
F'up2 cljs

PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Jun 27 '08 #15

P: n/a
On May 1, 5:03 pm, dhtml <dhtmlkitc...@gmail.comwrote:
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_...@yahoo.comwrote:
On Apr 27, 2:20 pm, "david.karr" <davidmichaelk...@gmail.comwrote:
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/cl...nipulation.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
named after Ruby's method - as you might know, prototype follows its
conventions in certain cases.

Best,
kangax
Jun 27 '08 #16

P: n/a
On May 1, 2:18 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
dhtml wrote:
turns out that non-capturing parentheses are not supported before JavaScript
1.5, JScript 5.5, ECMAScript Ed. 3. Use them and your script will break in
IE before version 5.5, for example.
OK. It won't work in IE 5.0. A lot of stuff won't e.g. apply(),
push().
>
A capturing group stores the whitespace:
(\\s+|$)
A non-capturing group does not:
(?:\\s+|$)

True, after a fashion.
It is less efficient to use a capturing group.

Nonsense. The tiny amount of memory saved by not storing the backreference
is bought with the tiny amount of runtime that is required more to parse the
non-capturing expression.
No, it is somewhat faster to use a non-capturing group.

(function() {
var token = "bar",
exp = new RegExp("(^|\\s)"+token+"($|\\s)"),
t= new Date;
for(var i = 0; i < 10000; i++) {
exp.exec("foo bar baz quux");
}
return new Date - t;
})();

(function() {
var token = "bar",
exp = new RegExp("(?:^|\\s)"+token+"(?:$|\\s)"),
t= new Date;
for(var i = 0; i < 10000; i++) {
exp.exec("foo bar baz quux");
}
return new Date - t;
})();
[" bar ", " ", " "]
vs
[" bar "]

The first one is faster (and doesn't work in IE 5.0).

F'up2 cljs

PointedEarsv
Jun 27 '08 #17

P: n/a
On May 1, 6:34 pm, kangax <kan...@gmail.comwrote:
On May 1, 5:03 pm, dhtml <dhtmlkitc...@gmail.comwrote:
On Apr 30, 6:59 pm, Prisoner at War <prisoner_at_...@yahoo.comwrote:
On Apr 27, 2:20 pm, "david.karr" <davidmichaelk...@gmail.comwrote:
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/cl...nipulation.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

Non-capturing groups that is.
Jun 27 '08 #18

P: n/a
@dhtml
remove "baz -"foo quux".
I believe your assertion is false, it still only leaves 1 space.
The pattern matches the beginning of the string OR one or more
<spacesthen the className then the end of the string OR one of more
<spacesafter.
This would remove <space>baz<spaceand replace with <spaceturning
the className value into "foo<space>quux".

Info not directed at anyone:
Prototype doesn't officially support IE 5.5
http://www.w3schools.com/browsers/browsers_stats.asp
At some point ya have to let that version go :)

- JDD
Jun 27 '08 #19

P: n/a
On May 1, 4:05 pm, jdalton <John.David.Dal...@gmail.comwrote:
@dhtml
remove "baz -"foo quux".

I believe your assertion is false, it still only leaves 1 space.
The pattern matches the beginning of the string OR one or more
<spacesthen the className then the end of the string OR one of more
<spacesafter.
This would remove <space>baz<spaceand replace with <spaceturning
the className value into "foo<space>quux".
Yes, you're right. THanks for correcting that.

It would then leave, in some cases, a space at the end, that gets
removed by strip()
Info not directed at anyone:
Prototype doesn't officially support IE 5.5http://www.w3schools.com/browsers/browsers_stats.asp
At some point ya have to let that version go :)
IE 5.5 is difficult because of the different CSS box model. IE 5 is
even worse for lack of apply().

Putting this back to c.l.j, as that is where it seems most
appropriate.

Garrett
- JDD
Jun 27 '08 #20

This discussion thread is closed

Replies have been disabled for this discussion.