views:

190

answers:

4

Hi, 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!!!

A: 

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 … });
Konrad Rudolph
does ul count as a container as well?my buttons are like this<ul id="buttons"> <li id = "aa">aa</li> <li id = "bb">bb</li> <li id = "cc">cc</li></ul>
christinelalala
Yes, of course. Any nesting of HTML elements will do.
Konrad Rudolph
+2  A: 

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' });
}
Diodeus
this is a very oldie but a goodie. I think it's been around since the dawn of DHTML
slf
i have a very dumb question, how should I call it? I mean this will be in another js file, how do I call it from my html file? thanks again.
christinelalala
call it with: regEvents('aa')
Diodeus
I kept is pretty simple to follow since you're new to this stuff. There are shorter ways to do it, but they are more difficult to understand and follow.
Diodeus
i'm sorry but where exactly should I put regEvents('aa')? I tried to put it in <li><a href = "#" onclick = "regEvents('aa')">aa</a></li> but it doesnt work and I have no idea where else can I put it. thanks
christinelalala
A: 

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.

sblundy
A: 

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...

eyelidlessness