> Thanks, perfect!

No worries!

> Can that be done with my inline code, though?

It _can_, yes, just put the queue parameter in your existing options
blocks.  But as Walter indicates, you really don't need to be using
inline event attributes anymore.

> For example, this is what I'm trying, but it isn't working:
> <script type="text/javascript" language="javascript">
>         function navicon1on {
>                 effect.appear('navicon1', {duration: 0.3});
>                 }
>         function navicon1off {
>                 effect.fade('navicon1', {duration: 0.3});
>                 }
> </script>

A couple of things.  Case (capitalization) is significant in
JavaScript, so you need to be sure you're using exactly the right
capitalization.  Script.aculo.us makes each effect available in two
ways:  A constructor that takes the element to act on as a parameter,
or as a method of an extended element.  You're using the constructor
there, and script.aculo.us' constructors and Effect namespace are both
initially capped (the first letter is capitalized).  You're also
missing the "new" operator.  It might help to go back and review the
demos and examples on the script.aculo.us documentation site[1].

Looking at the source of the page you linked, I think you might want
to review your use of IDs and class names.  IDs are for uniquely
identifying elements; class names are for marking elements (usually
more than one) that share common characteristics.  You seem to be
using class names a bit like IDs.

> I'm really getting confused as to how to name things, reference
> elements, etc.

It's pretty straightforward.  There are basically three ways to
reference an element:

1. By its ID, if it has one.  You're already doing that in your code:

$('navicon1').appear({duration: 0.3});

That's referencing an element with the ID 'navicon1', using
Prototype's $ function.  So you're on the way.  Read up on $ here[2]

2. Via CSS selectors.  Prototype provides very powerful CSS selector
functionality.  For instance, suppose you want to get an array of
every element in your document with the CSS class "foo".  You can use
Prototype's $$ function[3] to do that:

    var a = $$('.foo');

The syntax supported is (nearly all of) CSS3, so that's pretty
powerful stuff.

3. By its relationship with some other element you already have a
reference to.  So say you have this structure:

    <span>Blah blah blah</span>
    <span>Humdee doo</span>

Now, suppose you have a reference to the first span element, and you
want to refer to the span that follows it.  You can do that using DOM
traversal, and Prototype provides some very nice DOM traversal stuff,
including the Element#next function[4], which finds the next sibling
of the element that matches the selector you give it.  Since the spans
in the example above are siblings (they have the same parent),
assuming 's1' is a reference to the first span, I can get a reference
to the second span using s1.next():

    var s2 = s1.next('span');

This is useful for when you know the relationship between elements,
and if you know that relationship is stable.  There's also
Element#down to find descendant elements, Element#up to find
ancestors, etc.

Let's bring a few of these things together.  Suppose I have this
structure which I'll call an "item":

<div class='item'>
    <a href='...'>Blah blah</a>
    <div class='icon'>...</div>

And let's suppose the structure of each item is stable; I'm not likely
to change it without expecting to make code changes as well.  Suppose
there are several items on a page, and I want the link within each
item to do something to the div that follows it.  I *could* put an
onclick attribute on each link, but that's a lot of work and I'm
lazy.  Instead, I'll use Prototype's dom:loaded event (which happens
when the page has been loaded, but without waiting for the images to
load -- so, sooner than window.load):

<script type='text/javascript'>
document.observe('dom:loaded', function() {
    // ...my code here...

Okay, so now I have code being called when the page loads.  What do I
want to do?  First, find all the item links:

    var links;
    links = $$('.item a');

(That selector matches any anchor within an element with the "item"

Then I want to loop through the array of links and hook up a couple of
event handlers on each of them.  I could use a normal for loop and
there's nothing wrong with that, but Prototype extends arrays with a
function called Enumerable#each[5] which makes things like this pretty

    links.each(function(link) {
        // ...my code here...

#each will call the function you give it for each item in the array,
passing it as the first parameter to the function.  It's just a
shorthand way of writing this:

    var n, link;
    for (n = 0; n < links.length; ++n) {
        link = links[n];
        // ...my code here...

So, for each link I want to set up a couple of event handlers -- one
for mouseover, another for mouseout.  I can use Prototype's
Element#observe[6] for that:

    links.each(function(link) {
        link.observe('mouseover', function(event) {
            // ...mouseover code here...
        link.observe('mouseout', function(event) {
            // ...mouseout code here...

So far, so good.  But within my handler, I'm going to want to
reference the element that the handler's attached to -- how do I do
that?  Prototype's Element#observe makes sure that when the event
handler is called, "this" refers to the element that the handler was
hooked up to.  So within the handler, 'this' will refer to the link.

Now, what do I want to do in my event handlers?  On mouseover, I want
the "icon" div next to the link to appear; on mouseout, I want it to
disappear.  How do I get a reference to the "icon" div next to my
link?  Element#next:

    links.each(function(link) {
        link.observe('mouseover', function(event) {
        link.observe('mouseout', function(event) {

So, just an interim "where we are" (this is not complete), let's bring
that all together:

<script type='text/javascript'>
document.observe('dom:loaded', function() {
    var links;

    // Get the item links
    links = $$('.item a');

    // Hook them up to the icons that follow them
    links.each(function(link) {
        // On mouseover, make the icon appear
        link.observe('mouseover', function(event) {
        // On mouseout, make the icon fade
        link.observe('mouseout', function(event) {

That's pretty much what your code was doing with inline onclick
handlers on the various navigation links.  But there are still four
problems:  1. "mouseover" happens whenever the mouse moves over the
element, repeatedly, every pixel or two.  We don't want to fire off
the effect every time.  2. 'mouseout' happens when the mouse moves
"out" of the element, including when it moves "out" of it into one of
its children!  So if you had a <strong> element within your link, for
instance, you'd get multiple mouseouts and things would flicker like
mad as the user moved the mouse over the <strong> bit.  3. We need to
make the icons start out invisible, and we can't do it with a CSS
style because the appear effect can't make something appear if its CSS
style says it's invisble.  4. The effects will interrupt each other.

The answer to #1 and #2 is to use the mouseenter and mouseleave events
instead, but those are provided essentially only on IE (yes, something
IE does better than other browsers!).  The good news is that Prototype
1.6.1 provides emulation of them on all browsers it supports, so if
you can use 1.6.1, use 'em.  Otherwise, provided you don't put other
elements within your links and you only fire off the appear effect if
the icon isn't currently visible, you should be okay.

The answer to #3 is to either use inline style (style="display:
none"), or hide them within your dom:loaded handler.  I'd probably use
inline style.

There are several answers for #4; let's use event queues in this case.

Last version, which is completely untested but I'm guessing pretty
nearly works:

Our markup for each item is:

<div class='item'>
    <a href='...'>Blah blah</a>
    <div class='icon' style='display: none'>...</div>

...and our script is:

<script type='text/javascript'>
document.observe('dom:loaded', function() {
    var links;

    // Get the item links
    links = $$('.item a');

    // Hook them up to the icons that follow them
    links.each(function(link) {
        var queue;

        // Create the queue option for this link
        queue = {'scope': 'q' + link.identify(), 'position': 'end'};

        // On mouseover...
        link.observe('mouseover', function(event) {
            var icon;

            // Make the icon appear if it isn't already showing
            icon = this.next('div.icon');
            if (!icon.visible()) {
               icon.appear({'duration': 0.3, 'queue': queue});

        // On mouseout...
        link.observe('mouseout', function(event) {
            // Make the icon fade
            this.next('div.icon').fade({'duration': 0.3, 'queue':

I slipped something in, there, didn't I?  Prototype provides an
Element#identity function[7] which is quite handy, it returns the
element's ID or (if it doesn't have one) assigns it a unique ID and
returns that.  I used that to give each element its own queue of

Sorry, didn't mean to go on like that.  Hopefully that gives you
something to chew over and think about!

It's well worth just reading the Prototype API[8] from front to back,
doesn't take too long.  You might find some of the articles on the
Prototype "Tips & Tutorials" page[9] and the unofficial wiki[10]
useful as well.

[1] http://wiki.github.com/madrobby/scriptaculous
[2] http://prototypejs.org/api/utility/dollar
[3] http://prototypejs.org/api/utility/dollar-dollar
[4] http://prototypejs.org/api/element/next
[5] http://prototypejs.org/api/enumerable/each
[6] http://prototypejs.org/api/element/observe
[7] http://prototypejs.org/api/element/identity
[8] http://prototypejs.org/api
[9] http://prototypejs.org/learn
[10] http://proto-scripty.wikidot.com

Happy coding,
T.J. Crowder
tj / crowder software / com
Independent Software Engineer, consulting services available

On May 22, 2:07 pm, BB Design <bradbans...@gmail.com> wrote:
> For example, this is what I'm trying, but it isn't working:
> <script type="text/javascript" language="javascript">
>         function navicon1on {
>                 effect.appear('navicon1', {duration: 0.3});
>                 }
>         function navicon1off {
>                 effect.fade('navicon1', {duration: 0.3});
>                 }
> </script>
> <div class="posnavtext1"><a onmouseover="navicon1on();"
> onmouseout="navicon1off();" href="index.asp">HOME</a></div>
> <div id="navicon1" class="posnavicon1" style="display: none;"><img
> src="art/ic_homeHover.gif" alt="Home" width="71" height="55"
> border="0" /></div>
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
For more options, visit this group at 

Reply via email to