1

我正在尝试编写一些更简洁的 Javascript / jQuery 代码。我如何将此功能重构为更清洁和更小的东西。绝对似乎有更好的方法来做到这一点。它有效,但我确信有更好的方法来编写这样的函数。提前致谢!

function filterForm(purpose, entry) {
    switch (purpose) {
        case 'Business' : 
            switch (entry) {
                case 'Single': 
                    $("#moreq1").css( "display", "block" );   
                    $("#moreq2").css( "display", "none"  );   
                    $("#moreq3").css( "display", "none"  );  

                    break;
                case 'Double': 
                    $("#moreq1").css( "display", "block" );   
                    $("#moreq2").css( "display", "none"  );   
                    $("#moreq3").css( "display", "none"  );  

                    break;
                case 'Multiple' : 
                    $("#moreq1").css( "display", "block" );   
                    $("#moreq2").css( "display", "block" );   
                    $("#moreq3").css( "display", "none"  );  

                    break;
                }

                break;
            case 'Private' : 
                switch (entry) {
                    case 'Single'   : 
                        $("#moreq1").css( "display", "block" );   
                        $("#moreq2").css( "display", "none"  );   
                        $("#moreq3").css( "display", "none"  );  

                        break;
                    case 'Double'   : 
                        $("#moreq1").css( "display", "none"  );   
                        $("#moreq2").css( "display", "none"  );   
                        $("#moreq3").css( "display", "none"  );  

                        break;
                    case 'Multiple' : 
                        $("#moreq1").css( "display", "none"  );   
                        $("#moreq2").css( "display", "none"  );   
                       $("#moreq3").css( "display", "none"  );  

                        break;
                }   

                break;
            case 'Tourist' : 
                switch (entry) {
                    case 'Single'   : 
                        $("#moreq1").css( "display", "block" );   
                        $("#moreq2").css( "display", "none"  );   
                        $("#moreq3").css( "display", "block"  );  

                        break;
                    case 'Double'   : 
                        $("#moreq1").css( "display", "none" );   
                        $("#moreq2").css( "display", "none"  );   
                        $("#moreq3").css( "display", "none"  );  

                        break;
                    case 'Multiple' : 
                        $("#moreq1").css( "display", "none"  );   
                        $("#moreq2").css( "display", "none" );   
                        $("#moreq3").css( "display", "none" );  

                        break;
                }       

                break;
            }
    }
}
4

7 回答 7

1

在查看了您的所有条件后,似乎可以归结为:

function filterForm(purpose, entry) {
    var q1 = purpose == 'Business' || entry == 'Single' ? 'block' : 'none';
    var q2 = purpose == 'Business' && entry == 'Multiple' ? 'block' : 'none';
    var q3 = purpose == 'Tourist' && entry == 'Single' ? 'block' : 'none';

    $("#moreq1").css( "display", q1 );   
    $("#moreq2").css( "display", q2 );   
    $("#moreq3").css( "display", q3 ); 
}
于 2013-07-17T18:06:32.247 回答
1

我将从删除所有隐藏语句开始 - 只是一般隐藏所有,然后只显示那些需要的(这里使用if-statements,请参阅@nmynarcik 的答案,了解使用 es 的中间步骤switch):

function filterForm(purpose, entry) {
    $("#moreq1, #moreq2, #moreq3").css("display", "none");

    if (purpose == 'Business') {
        $("#moreq1").css("display", "block");
        if (entry == 'Multiple')
            $("#moreq2").css("display", "block");
    } else if (purpose == 'Private' && entry == 'Single')
         $("#moreq1").css("display", "block");
    } else if (purpose == 'Tourist' && entry == 'Single') {
         $("#moreq1, #moreq3").css("display", "block");
    }
}

可以进一步简化为

function filterForm(purpose, entry) {
    $("#moreq1, #moreq2, #moreq3").css("display", "none");

    if (purpose == 'Business' || entry == 'Single')
         $("#moreq1").css("display", "block");
    if (purpose == 'Business' && entry == 'Multiple')
         $("#moreq2").css("display", "block");
    if (purpose == 'Tourist' && entry == 'Single')
         $("#moreq3").css("display", "block");
}

如果它变得越来越复杂,我建议使用单个显示值的查找图,而不是使用switch包含大量重复语句的语句。对于您的设置,它看起来像

var show = {
    "moreq1": {
        "Business": true,
        "Private": {
            "Single": true
        },
        "Tourist": {
            "Single": true
        }
    },
    "moreq2": {
        "Business": {
            "Multiple": true
        }
    },
    "moreq3": {
        "Tourist": {
             "Single": true
        }
    }
};
for (var id in show) {
    var l = show[id];
    $("#"+id).css("display", l[purpose] === true || l[purpose] && l[purpose][entry] ? "block" : "none");
}

当然,如果它变短,你可以交换purposeand的顺序。entry

于 2013-07-17T18:07:18.887 回答
1

虽然其他答案在组合可能性方面做得不错,但对我来说,使用所有可能性的“地图”似乎更合乎逻辑,并参考:

var filterForm = (function () {
    var moreq = [
        "",        // So you can use indexes starting at 1
        "moreq1",
        "moreq2",
        "moreq3"
    ], Purposes = {
        "Business": {
            "Single": [moreq[1]],
            "Double": [moreq[1]],
            "Multiple": [moreq[1], moreq[2]]
        },
        "Private": {
            "Single": [moreq[1]],
            "Double": [],
            "Multiple": []
        },
        "Tourist": {
            "Single": [moreq[1], moreq[],
            "Double": [],
            "Multiple": []
        }
    };

    return function (purpose, entry) {
        var i, j, cur, display;

        for (i = 1, j = moreq.length; i < j; i++) {
            cur = moreq[i];
            display = Purposes[purpose][entry].indexOf(cur) > -1 ? "block" : "none";
            console.log("Setting " + cur + " as " + display);
            //$("#" + cur).css("display", display);
        }
    };
}());

filterForm("Business", "Multiple");

演示:http: //jsfiddle.net/w3Jnn/1/

对象中的数组是将显示设置为的元素block。只要您想更改特定设置,只需修改Purposes对象的数组即可。

当然,我的函数并没有做太多的检查Purposes[purpose][entry].indexOf(cur) > -1——它假设purposeandentry参数将具有有效值。这可以修改为检查,但现在似乎并不重要。

请注意,这使用闭包(周围的(function () { }))来实例化Purposesanditems变量一次,但将它们保持在全局范围之外。

另请注意,Array.indexOf并非所有浏览器(主要是旧 IE)都支持该方法,因此在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf有一个 shim #Compatibility包含在您的页面上以确保其正常工作,以及您可以通过 Google 找到的其他内容。

于 2013-07-17T18:15:19.977 回答
1

我不确定我有多喜欢这种方式,但这是一种非切换、非如果的方式。它也可以帮助测试,因为您可以独立地对查找进行单元测试。

但是,如果目的条目不是查找中的关键,那么您会抛出一些错误。

function filterForm(purpose, entry) {
    var lookup = {}
    lookup['Business'] = {'Single':{'q1':'block','q2':'none','q3':'none'},
                         {'Double':{'q1':'block','q2':'none','q3':'none'}};

    lookup['Private'] = {...etc...};

    $('#moreq1').css('display', lookup[purpose][entry]['q1]);
}
于 2013-07-17T18:17:55.843 回答
0

如果你想坚持使用switched,给他们一个类,你可以将所有设置为显示:无;当你开始你的方法时。

然后做:

function filterForm(purpose, entry) {

   $('.qItem').hide();

    switch (purpose) {

        case 'Business' : 

            $("#moreq1").css( "display", "block" );

            switch (entry) {

                case 'Multiple' : 

                    $("#moreq2").css( "display", "block" );

                break;

            }

        break;

        case 'Private' : 

            switch (entry) {

                case 'Single'   : 

                    $("#moreq1").css( "display", "block" );   
                    break;

            }   

        break;

        case 'Tourist' : 

            switch (entry) {

                case 'Single'   : 

                    $("#moreq1").css( "display", "block" );   
                    $("#moreq3").css( "display", "block"  );  

                break;

            }       

        break;

    }

}

您可以在这里看到如何使用该类:http: //jsfiddle.net/pMfgy/

于 2013-07-17T18:14:46.033 回答
0

尝试这个:

function filterForm(purpose, entry) {
    var hideMap = {
        Business: {
            Single: [2, 3],
            Double: [2, 3],
            Multiple: [3]
        },
        Private: {
            Single: [2, 3],
            Double: [1, 2, 3],
            Multiple: [1, 2, 3]
        },
        Tourist: {
            Single: [2],
            Double: [1, 2, 3],
            Multiple: [1, 2, 3]
        }
    };

    hideShow(hideMap[purpose][entry]);
}

function hideShow(a) {
    var allEls = '#moreq1, #moreq2, #moreq3';
    for (var i = 0; i < a.length; i++) {
        a[i] = '#moreq' + a[i];
    }
    var hideEls = a.join(',');
    $(hideEls).hide(a.join());
    $(allEls).not(hideEls).show();
}

jsFiddle

于 2013-07-17T18:32:00.390 回答
0

正如许多人所说,看起来您可以大大简化显示逻辑,但是如果根据 、 和 元素的 、 和 变量值维护不同的状态对您很moreq1重要moreq2moreq3那么purposeentry建议您将大部分显示“逻辑”转移到 CSS,而不是 JS/jQuery 。. .

大部分逻辑都可以替换为与purposeentry值相关的 CSS 样式定义:

CSS

// "Business" display styles
// "Business - Single" display styles
.business.single #moreq1 {display: block}
.business.single #moreq2,
.business.single #moreq3 {display: none}

// "Business - Double" display styles
.business.double #moreq1 {display: block}
.business.double #moreq2,
.business.double #moreq3 {display: none}

// "Business - Multiple" display styles
.business.multiple #moreq1,
.business.multiple #moreq2 {display: block}
.business.multiple #moreq3 {display: none}

// "Private" display styles
// "Private - Single" display styles
.private.single #moreq1 {display: block}
.private.single #moreq2,
.private.single #moreq3 {display: none}

// "Private - Double" display styles
.private.double #moreq1,
.private.double #moreq2,
.private.double #moreq3 {display: none}

// "Private - Multiple" display styles
.private.multiple #moreq1,
.private.multiple #moreq2,
.private.multiple #moreq3 {display: none}

// "Tourist" display styles
// "Tourist - Single" display styles
.tourist.single #moreq1,
.tourist.single #moreq3 {display: block}
.tourist.single #moreq2 {display: none}

// "Tourist - Double" display styles
.tourist.double #moreq1,
.tourist.double #moreq2,
.tourist.double #moreq3 {display: none}

// "Tourist - Multiple" display styles
.tourist.multiple #moreq1,
.tourist.multiple #moreq2,
.tourist.multiple #moreq3 {display: none}

之后,您可以使用 jQuery 简单地将样式分配给父容器(甚至是<body>标签),使用purposeandentry值:

JS

function filterForm(purpose, entry) {
    var dynamicClasses = purpose + " " + entry;
    $("#parent_element_ID").addClass(dynamicClasses.toLowerCase());
}

届时,CSS 将根据您的 CSS 规则接管并显示/显示元素。

虽然它可能看起来像很多 CSS,但它不仅将 CSS 用于其预期目的,而且还进行任何更改(或添加新部分),即简单的 CSS 更新,而不是 JS 代码更改。

于 2013-07-17T18:42:38.647 回答