I have what I hope is a very simple question. In fact I think it’s silly I haven’t figured it out. I have an example of my code here:
http://jsfiddle.net/joeljoelbinks/pVSDL/
excerpt:
function lighten() {
jQuery(this).css('opacity', '0.5');
jQuery(this).html('DO IT!');
}
function darken() {
jQuery(this).css('opacity', '1');
jQuery(this).html('CLICK TO EXPAND');
}
function expand() {
jQuery(this).off('click', expand);
jQuery(this).off('mouseover', lighten);
jQuery(this).on('click', contract);
darken(); //this doesn't get called
jQuery(this).animate({width: '200px', height: '200px'}, 500);
}
function contract() {
jQuery(this).off('click', contract);
jQuery(this).on('mouseover', lighten);
jQuery(this).on('click', expand);
lighten(); //this doesn't get called
jQuery(this).animate({width: '100px', height: '100px'}, 250);
}
This is a simplified prototype of an expanding div design I am implementing on a website I am working on. Everything works as designed except the lighten() and darken() functions do not get called when inside the expand() or contract() functions. I have tried multiple ways to call them from within the functions but they don’t work. Notice that I left them there just to show you that that’s what needs to be fixed. How do I get them to fire when within the expand/contract functions? They work as when bound to mouseover/mouseout events which I coded at the beginning, but not within the other function. If I make them execute an alert() function, then they work in all contexts but not if I am trying to modify JQuery(this) with them.
Bonus question: also, look at the top of the js: how do I bind both variables to the same events as opposed to the current code where I have to bind them separately? I have tried bind() and several other things but I can only get them to bind when I do them separately which is a violation of DRY principles 😉
You need to make sure that
thisrefers to the right thing:instead of
The value of
thisis determined upon every function call, so you need to make sure that it’s correct by using.call(). Alternatively, you could change yourdarken()andlighten()functions so that they took a parameter for the element to affect.edit — as to your “bonus”, you can’t do that without some other function to “serialize” the calls to the two event handlers you need to bind to “click” (or whatever). That’s certainly possible, but it’s questionably valuable. You could always just write a single function to call the two functions in question (again being careful to explicitly pass on
thisappropriately).