Mootools highlight() driving me mad
Just spent the best part of my Sunday afternoon trying to get what, on the face of it, was a simple task.
Using mootools, I wanted to have a simple highlight effect using highlight() as the mouse rolled over the elements and, when clicked, an ajax call would, asides from making various database checks and modifications, return a new class for the clicked element.
This new (css) class basically defined either a background image or/and a background color.
I had the highlight() call like this:
// highlight elements function var highlight_it = function(){ this.highlight(highlight_color); } // mouseover effect clickable.addEvent('mouseover', highlight_it);
However, when I clicked on the elements, the code refused to recognise the changed background color.
It would change borders, padding, etc. – anything but the background color.
The moment I removed the mouseover, everything worked fine so this was clearly the problem.
I tried “stopping” the mouseover function by using this line within the “click” event:
this.removeEvent('mouseover', highlight_it);
This worked in that the it stopped highlighting on mouseover, but there was still no way to get the background color to change.
It seemed that the highlight() function was “taking control” of the elements background color and not letting go.
According to mootools docs, highlight() can take two parameters “start” and “end” (colors):
- start – (string, optional: defaults to ‘#ff8’) The color from which to start the transition.
- end – (string, optional: defaults to Element’s set background-color) The background color to return to after the highlight effect.
As I understand that, if there is no second color defined it should (and does) go back to the original color. However it says nothing about this attribute being “stuck” like it. (note, it can be changed by using this.setStyle(‘background’,’red’); but I needed it to use a class).
So, how did I eventually solve it?
The answer was quite simple really and something I probably should have tried from the start – I needed to define and use the color to return to, even though once clicked this would be different.
Here is my adapted and working version:
// highlight elements var highlight_it = function(){ // get current bg color var cur_bg_color=this.getStyle("backgroundColor"); // highlight element this.highlight(highlight_color,cur_bg_color); } // mouseover effect clickable.addEvent('mouseover', highlight_it);
I’m not sure if this is a bug in mootools or if it is expected behaviour, but it certainly kept me busy today 🙂
I hope this helps other users solve the problem quicker than I managed it.
EDIT – I have just added a simplified demo (no ajax, just straight forward mouse and click events) to further demonstrate the problem.
The issue is not a bug in mootools or in your own code, but rather a misunderstanding about how mootools and css work. You have a click event that attaches a class. You have a mouseover effect that changes the background color from a highlight value back to the current color. The mouseover effect always occurs before the click event (it must!) so when you click your element, the element has an inline style set to the original background color. Inline styles ALWAYS win over styles defined in style tags or imported style sheets, so your css values are ignored.
To solve this, you have three options:
1) add an onComplete method to your fade effect that removes the inline background style.
2) explicitly declare the colors you want to use in your javascript.
3) use Fx.Morph and morph between css classes (element.morph(‘.marked’)). This still sets inline styles, but the data for those styles will come from your style sheets and not be defined in your JavaScript, which is a better practice. Note that Fx.Morph, when used this way, does not actually add the class you morph to – just the styles. You’d have to chain a method on to the end of Morph that adds the class if you want it there.
Thanks Aaron for clearing this up for me.
I hadn’t realised that highlight() was setting an inline style, but, on retrospect, this is obvious and is clearly the reason why it works with “this.setStyle(’background’,’red’);”.
Basically highlight() is adding an style inline attribute where there wasn’t one before.
The strange thing however is that it does work if I use the second (end) color parameter which must be updating this added inline style.
Why should this change things? – in theory it should still not work as I expected as the inline styles take preference over the classes.
Anyway, thanks again for your comments, they are greatly appreciated and it is a pleasure (and surprise) to see you stopping by by blog.
Keep up the great work with mootools 😉