views:

337

answers:

3

Using the script.aculo.us Effect.Highlight on an onMouseOver event works perfectly - if the user only mouses over the DIV once. If they mouse back over the DIV during the execution of the effect, another Effect gets scheduled (or runs in parallel, depending on whether or not

{queue: 'end'}

is enabled).

Does script.aculo.us have a built-in way of preventing this from happening, so that the DIV will only highlight itself if the user mouse's over the DIV at a resting state? Otherwise I guess I could keep a state variable that gets restored to 'resting':

afterFinish: function(obj) { resting = true; }

I've noticed similar situations before: for example, Effect.Shake, if called multiple times, causes the DIV to shake in a wider frame.

Also, this problem can be seen on the demo site if you click the demo multiple times in rapid succession: click to see demo

A: 

The onMouseOver event will fire every time you mouse over the element. Script.aculo.us does not have a way built in to check what you're asking for.

However, what you could do is onMouseOver add a class to the element called "fired" and if you see that class don't fire trigger the mouseover.

You could also add a timer to onMouseOut, so if they try to mouse over the element before the timer runs out it won't highlight. I admit, this could get hairy though.

Joe.Cianflone
A: 

Since their demo of the highlight has the same problem, I imagine its just built that way.

I'm not familiar with the Scriptaculous library, or Prototype upon which it was built. However, glancing at their source code for Effect.Highlight (currently line 474 of the code), we can see what we might do to fix your problem.

I haven't actually tried this, but what I would be tempted to try is something like this:

function MySiteSetup(){
 var highlight = new Effect.Highlight('id_of_element', [options]);

 var firing = false;
 var oldSetup = highlight.setup;
 highlight.setup = function(){
  if(firing) return; // Short circuit the effect if it's already firing

  firing = true;
  oldSetup();
  firing = false;
 }
}
Matt
+1  A: 

Came up with a solution similar to what I proposed in the question, appears to work:

$('id').writeAttribute('resting');
//
// other code here
//
if($('id').readAttribute('resting') == 'resting') {
 $('id').writeAttribute('resting',false); 
 new Effect.Highlight('id', {queue: 'end', startcolor:'#b3ff8d', endcolor:'#ffffff',afterFinish:function(obj) {obj.element.writeAttribute('resting')}});
}
zaczap