Более эффективный оператор переключения в jQuery / JavaScript - PullRequest
0 голосов
/ 01 июля 2011

Я работаю над приложением, которое использует оператор switch для предоставления пользовательских анимаций в зависимости от того, какая ссылка была нажата для запуска анимации. Кажется, что много кода получается, чтобы получить то, что я хочу, но у меня есть небольшая проблема с поиском лучшего способа сделать это.

Что происходит, когда вы нажимаете на ссылку, div открывается, чтобы показать скрытый контент, а другой divs скользит в сторону экрана. Вроде как обычный аккордеон.

Мой оператор switch выглядит следующим образом - параметр history берется из идентификатора нажатой ссылки. Div хранятся в объекте с именем 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;
}

Надеюсь, должно быть совершенно очевидно, что я здесь делаю!

Функции myAnimation() и fadeinCloseLink() являются пользовательскими функциями. Последнее должно быть выполнено с последним элементом объекта, который при завершении запускает пользовательскую анимацию для выбранного div. Функция fadeinCloseLink() выполняет следующие действия:

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

Где disFull относится к div, которое будет затронуто.

Надеюсь, это достаточно ясно, чтобы ответить на мой вопрос.

Ответы [ 3 ]

2 голосов
/ 01 июля 2011

Вот что я быстро придумал

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();
2 голосов
/ 01 июля 2011

Вы можете выполнить рефакторинг своего кода, чтобы все повторяющиеся части перешли в одну функцию.

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;
    }
0 голосов
/ 01 июля 2011

Если я вижу это правильно, каждый случай имеет следующую последовательность вызовов:

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

... и меняется только то, какие элементы вызваны.Так что это наша первая возможность для рефакторинга.

Вторая, вероятно, что мы можем сделать таблицу поиска:

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]
};

и так:

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();

Теперь, будь тоэто более приемлемо, это другой вопрос, но, обладая более широкими знаниями о проекте в целом, вы вполне можете применять методы таким способом, который одновременно является кратким и обслуживаемым.

...