0

I'm working on an app that uses a switch statement to provide custom animations depending on which link has been clicked to trigger the animation. It seems like a lot of code to get what I want, but I'm having a little trouble figuring out a better way to do it.

What happens is that when you click on a link, a div will open up to reveal hidden content and the other divs will slide to the side of the screen. Kinda like a custom accordian.

My switch statement looks like this - the history paramater is taken from the id of the clicked link. The divs are stored in an object called rpsObject.

switch( history ) {
    case "biography" :
        $("#" + rpsObject.boxId[1]).myAnimation();
        $("#" + rpsObject.boxId[2]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[3]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[4]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[5]).fadeInCloseLink();
    break;
    case "blog" :
        $("#" + rpsObject.boxId[0]).myAnimation();
        $("#" + rpsObject.boxId[2]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[3]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[4]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[5]).fadeInCloseLink();
    break;
    case "diary" :
        $("#" + rpsObject.boxId[0]).myAnimation();
        $("#" + rpsObject.boxId[1]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[3]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[4]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[5]).fadeInCloseLink();
    break;
    case "reviews" :
        $("#" + rpsObject.boxId[0]).myAnimation();
        $("#" + rpsObject.boxId[1]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[2]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[4]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[5]).fadeInCloseLink();
    break;
    case "images" :
        $("#" + rpsObject.boxId[0]).myAnimation();
        $("#" + rpsObject.boxId[1]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[2]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[3]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[5]).fadeInCloseLink();
    break;
    case "contact" :
        $("#" + rpsObject.boxId[0]).myAnimation();
        $("#" + rpsObject.boxId[1]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[2]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[3]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[4]).fadeInCloseLink();
    break;
}

Hopefully it should be pretty obvious what I'm doing here!

The functions myAnimation() and fadeinCloseLink() are custom functions. The latter must be performed on the last item of the object, which on complete trigger a custom animation for the selected div. The function fadeinCloseLink() does the following:

$.fn.fadeInCloseLink = function() {
    $(this).animate({ "left" : "640px", "top" : "320px", "height" : "80px" }, 300,
    function(){
        disFull.animate({ "opacity" : "toggle", "height" : "toggle" }, 500);
    });
}

Where disFull refers to the div that will be affected.

Hopefully this is clear enough to get my question across.

2
  • Hi T. J. - thanks for your comment. I appreciate the tip! I'll try and get my posts in order. Apologies for not being more organized! Commented Jul 1, 2011 at 10:52
  • Not a problem at all, happy to help. Best, Commented Jul 1, 2011 at 10:56

3 Answers 3

2

Here is what I came up with quickly

var historyItems = "biography,blog,diary,reviews,images,contact".split(",")
var currentSettings = [];
for (var i=0;i< historyItems.length; i++) {
  if (historyItems[i] != history) currentSettings.push(i)
}  
$("#" + rpsObject.boxId[currentSettings[0]]).myAnimation();
$("#" + rpsObject.boxId[currentSettings[1]]).myAnimation({ top : 80 });
$("#" + rpsObject.boxId[currentSettings[2]]).myAnimation({ top: 160 });
$("#" + rpsObject.boxId[currentSettings[3]]).myAnimation({ top: 240 });
$("#" + rpsObject.boxId[currentSettings[4]]).fadeInCloseLink();
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you mplungjan! Very elegant solution - this was exactly what was on the tip of my brain, but I just haven't enough experience to think this clearly! Works perfectly. Many thanks. I'd give you a +1 if I hadn't such a terrible reputation here!!
2

You could refactor your code so that all the repeated portions go into a single function.

var myFunction = function(indexes){
        $("#" + rpsObject.boxId[indexes[0]]).myAnimation();
        $("#" + rpsObject.boxId[indexes[1]]).myAnimation({ top : 80 });
        $("#" + rpsObject.boxId[indexes[2]]).myAnimation({ top: 160 });
        $("#" + rpsObject.boxId[indexes[3]]).myAnimation({ top: 240 });
        $("#" + rpsObject.boxId[indexes[4]]).fadeInCloseLink();
    }

    switch( history ) {
    case "biography" :
       myFunction([1,2,3,4,5]);
    break;
    case "blog" :
        myFunction([0,2,3,4,5]);
    break;
    case "diary" :
        myFunction([0,1,3,4,5]);
    break;
    case "reviews" :
        myFunction([0,1,2,4,5]);
    break;
    case "images" :
        myFunction([0,1,2,3,5]);
    break;
    case "contact" :
        myFunction([0,1,2,3,4]);
    break;
    }

Comments

0

If I'm seeing it correctly, each case features this sequence of calls:

.myAnimation();
.myAnimation({ top : 80 });
.myAnimation({ top: 160 });
.myAnimation({ top: 240 });
.fadeInCloseLink();

...and it's just which elements those are called on that varies. So that's our first opportunity for refactoring.

The second is probably that we can do a lookup table:

var elementMap = {
    "biography": [1, 2, 3, 4, 5],
    "blog":      [0, 2, 3, 4, 5],
    "diary":     [0, 1, 3, 4, 5],
    "reviews":   [0, 1, 2, 4, 5],
    "images":    [0, 1, 2, 3, 5],
    "contract":  [0, 1, 2, 3, 4]
};

and so:

var elements = elementMap[history];
rpsObject.boxId[elements[0]].myAnimation();
rpsObject.boxId[elements[1]].myAnimation({ top : 80 });
rpsObject.boxId[elements[2]].myAnimation({ top: 160 });
rpsObject.boxId[elements[3]].myAnimation({ top: 240 });
rpsObject.boxId[elements[4]].fadeInCloseLink();

Now, whether that's more maintainable is another question, but with your broader knowledge of the overall project, you may well be able to apply the techniques in a way which is both concise and maintainable.

2 Comments

Thanks also for your solution T.J! Slowly getting my head around JavaScript id made easier by having such a helpful, positive community. Thanks for your help!
@Richard: No worries, good luck with it. Not touting (it's not monetized and not likely to be), but if you're new to JavaScript, you might want to take a look at my blog, particularly some of the earlier entries. Years after using JavaScript as a play language, I started paying attention to how it actually worked, and wrote things up periodically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.