0

I'm currently trying to develop an interactive chart using the RaphaelJS vector library. I have succeeded in creating a chart ( http://lmhbc.com/newsite/trial1.html it will take a while to load) but have had to use the eval() function repeatedly in the process.

Here is an simplified example of what I have used: (Here item and class are dynamically created and not linked i.e. multiple items have the same class)

thisArray[item] = paper.path("M"+xStart+" "+yStart+"L"+xEnd+" "+yEnd);
eval("thisArray[item].click(function() {clickHandler("+class+");}");

This is a very simplified version of what I am using in practice, as I use 3 layer arrays etc. I have over 15000 of these objects being created and I am not only adding click handler, but also mouse over and mouse out which is leading to quite a few eval()'s popping up.

So my question is how do I avoid these evals. I believe they are one of the main issues with speed. Since my items are named dynamically I cannot retrieve their name once clicked as they have no real 'name'.

Thanks for the help,

Josh

Notes: paper.path(...) creates a vector line which is what I want to click on

An example of the actual code:

var crew = crewOrders[year][day][position]['crew'];
crewOrders[year][day][position]['line'] = canvas.path("M"+xStart+" "+yStart+"L"+xEnd+" "+yEnd)
                                                    .attr({stroke: 'white', 'stroke-width': 2, 'stroke-linecap': 'round'});
eval("crewOrders[year][day][position]['line'].mouseover(function() {mouseOverCrew("+crew+");document.body.style.cursor = 'hand';})"+
                                                            ".mouseout(function() {mouseOutCrew("+crew+");document.body.style.cursor = 'default';})"+
                                                            ".click(function() {selectedCrew("+crew+");})");

2 Answers2

3

Try:

thisArray[item].click = function(class) {
  return function() { clickHandler(class); };
}(class);

That allows you to preserve a copy of "class" for use by the handler function.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    Perfect. Thanks for the quick response. As you may have guessed I'm new to stackoverflow but I will make more use of it from now on. Thanks again. – user1449077 Jun 11 '12 at 16:02
2

Javascript Closures will help you.

function getOnClickHandler(class) {
  return function() {
    clickHandler(class);
  }
}
thisArray[item].click(getOnClickHandler(class));

See How do JavaScript closures work?

Community
  • 1
  • 1
Nayjest
  • 1,089
  • 8
  • 14
  • Using bind (not supported by old browsers, but it's many implementations of this function for old browsers): thisArray[item].click(clickHandler.bind(null, class)); – Nayjest Jun 11 '12 at 14:25