Krausers
Krausers

Reputation: 171

Using RaphaelJS vector graphics library - Help interperting example

I'm looking at the source code for this http://raphaeljs.com/australia.html example, and trying to interpret what has been done in order to create a similar project using the RaphaelJS graphics library.

I am, however, confused about part of the code. Specifically, the author uses a parameter "st" in a function inside a for loop, that has not been defined before, while the second parameter "state" has. I'm not sure what I'm missing, but can someone please explain what's going on here? Is this a generic parameter or a call to something specific?

for (var state in aus) {
            aus[state].color = Raphael.getColor();
            (function (st, state) {
                st[0].style.cursor = "pointer";
                st[0].onmouseover = function () {
                    current && aus[current].animate({fill: "#333", stroke: "#666"}, 500) && (document.getElementById(current).style.display = "");
                    st.animate({fill: st.color, stroke: "#ccc"}, 500);
                    st.toFront();
                    R.safari();
                    document.getElementById(state).style.display = "block";
                    current = state;
                };
                st[0].onmouseout = function () {
                    st.animate({fill: "#333", stroke: "#666"}, 500);
                    st.toFront();
                    R.safari();
                };
                if (state == "nsw") {
                    st[0].onmouseover();
                }
            })(aus[state], state);
        }

Upvotes: 1

Views: 348

Answers (2)

Eliran Malka
Eliran Malka

Reputation: 16263

st is a named parameter of the surrounding closure:

(function (st, state) {
    // ...
})(aus[state], state);

This is known as an Immediately-Invoked Function Expression (often called Self-Executing Block or a Temporary Scope) used to "save" a state by extracting code from the surrounding context.

In order to introduce variables from outside the closure, one can pass them to the trailing parentheses as arguments (here aus[state], state), and name them in the function's signature (here st, state).

References

Further Reading

Upvotes: 1

alexdavey
alexdavey

Reputation: 672

The function is called with the values aus[state] and state (look at the second last line). So it equivalent to:

for (var state in aus) {
        aus[state].color = Raphael.getColor();

        var st = aus[state]; // This line replaces the function

        st[0].style.cursor = "pointer";
        st[0].onmouseover = function () {
            current && aus[current].animate({fill: "#333", stroke: "#666"}, 500) && (document.getElementById(current).style.display = "");
            st.animate({fill: st.color, stroke: "#ccc"}, 500);
            st.toFront();
            R.safari();
            document.getElementById(state).style.display = "block";
            current = state;
        };

        st[0].onmouseout = function () {
            st.animate({fill: "#333", stroke: "#666"}, 500);
            st.toFront();
            R.safari();
        };

        if (state == "nsw") {
            st[0].onmouseover();
        }
    }

Upvotes: 0

Related Questions