Question

I have a lot of buttons and by clicking on different button, different image and text would appear. I can achieve what I want, but the code is just so long and it seems very repetitive. For example:

   var aaClick = false;
    $("aa").observe('click', function() {
        unclick();
        $('characterPic').writeAttribute('src',"aa.jpg");
        $('characterBio').update("aatext");
        $('aa').setStyle({ color: '#FFFFFF' });
        aaClick = true;
    });

    $("aa").observe('mouseover', function() {
        if (!aaClick) $('aa').setStyle({ color: '#FFFFFF' });
    });

    $("aa").observe('mouseout', function() {
        if (!aaClick) $('aa').setStyle({ color: '#666666' });
    });

    function unclick() {
         aaClick = false;
         $('aa').setStyle({ color: '#666666' });
    }

same thing with bb, cc, etc. and every time I add a new button, I need to add it to unclick function as well. This is pretty annoying and I tried to google it, and I only found observe click on all listed items, so I still couldn't figure out since what I want involves button up when other buttons are clicked.

Is there any way to just have a generic function that takes different id but do the exact same thing? Because from what I can see, if I can just replace aa with other id, I can reduce a lot of code. Thanks!!!

Was it helpful?

Solution

Build it all into a function where you can simply pass it the names of the DIVs you want to register. As long are you are consistent with your .jpg names, it should work.

var clicks = []
function regEvents(divName) {
    $(divName).observe('click', function() {
        unclick(divName);
        $('characterPic').writeAttribute('src',divName+".jpg");
        $('characterBio').update(divName"text");
        $(divName).setStyle({ color: '#FFFFFF' });
        clicks[divName] = true

    });

    $(divName).observe('mouseover', function() {
        if (!clicks[divName]) $(divName).setStyle({ color: '#FFFFFF' });
    });

    $(divName).observe('mouseout', function() {
        if (!clicks[divName]) $(divName).setStyle({ color: '#666666' });
    });
}
function unclick(divName) {
     clicks[divName] = false;
     $(clicks[divName]).setStyle({ color: '#666666' });
}

OTHER TIPS

Event delegation. Give all your buttons a class (eg yourButtonClass), then...

var clicks = [];
$$('.yourButtonClass').each(function(button) {
    clicks.push(button.id);
});
$(document).observe('click', function(e) {
    // If your click registered on an element contained by the button, this comes in handy...
    var clicked = e.element().up('.yourButtonClass') || e.element();

    if(clicked.hasClassName('.yourButtonClass')) {
        unclick();
        $('characterPic').writeAttribute('src', clicked.id + '.jpg');
        $('characterBio').update(clicked.id + 'text');
        $(clicked).setStyle({ color: '#FFFFFF' });
        clicks[clicked.id] = true;
    }
});

And so on...

The event handlers can have an argument that will be set to the event target. Then you could reuse the same function:

var clickedHandler = function(element) { 
  $(element).addClass("selected");
};
$("aa").observe('click', clickedHandler);
$("bb").observe('click', clickedHandler);

You're also in desperate need to CSS styling. Please see my answer to your previous question, but you could just reuse the pattern for the other events.

Do the buttons share a common container? Then the following code works:

$(container).childElements().each(function(element) {
    $(element).observe('click', function () { … });
    …
});

Alternatively, you can also do this:

["aa", "bb", "cc"].each(function(element) { … same code … });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top