重构如何在javascript中切换以获得更干净的代码
How refactor switch in javascript for cleaner code?
我正在尝试编写一些更干净的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;
}
}
}
虽然其他答案在组合可能性方面做得很好,但对我来说,使用所有可能性的"地图"似乎更合乎逻辑,并引用:
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
部分进行太多检查——它假设purpose
和entry
参数将具有有效值。这可以修改以进行检查,但现在似乎并不重要。
值得注意的是,这使用了一个闭包(周围的(function () { })
)来实例化Purposes
和items
变量一次,但将它们排除在全局范围之外。
另外请注意,并非所有浏览器(主要是旧IE)都支持Array.indexOf
方法,因此在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility包括在你的页面上以确保它的工作,以及你可以在谷歌上找到的其他内容。
在查看了您的所有条件后,似乎可以归结为:
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 );
}
我不确定我有多喜欢这种方式,但这是一种非开关、非if的方式。它也有助于测试,因为你可以独立地对查找进行单元测试。
但是,如果目的或条目不是查找中的键,则会引发一些错误。
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]);
}
我会从删除所有隐藏的语句开始——只是一般地隐藏所有语句,然后只显示那些需要的语句(这里使用if
-语句,请参阅@nmynarcik的答案,了解使用switch
es的中间步骤):
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");
}
当然,如果purpose
和entry
的顺序变短,您可以交换。
如果你想坚持使用switched,给它们一个类,你可以设置all显示:none;当你开始你的方法。
然后执行:
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/
正如许多人所说,看起来可以大大简化显示逻辑,但如果基于purpose
和entry
变量值维护基于moreq1
、moreq2
和moreq3
元素的不同状态对您来说很重要,那么我建议您将大部分显示"逻辑"转移到CSS,而不是JS/jQuery。
大部分逻辑可以用与purpose
和entry
值绑定的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>
标记),使用purpose
和entry
值:
JS
function filterForm(purpose, entry) {
var dynamicClasses = purpose + " " + entry;
$("#parent_element_ID").addClass(dynamicClasses.toLowerCase());
}
这时,CSS将接管并显示基于您的CSS规则的元素。
虽然它看起来像是很多CSS,但它不仅将CSS用于其预期目的,而且还进行任何更改(或添加新的部分),一个简单的CSS更新,而不是JS代码更改。
试试这个:
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
- 云代码(javascript)失败,原因是:{代码:1,消息:内部错误
- 简化此If语句,使其不会't重复代码-Javascript
- 十进制到二进制代码Javascript
- 第二次单击时执行不同的代码(JavaScript)
- 在不使用jquery($symbol)knockout.js的情况下分离代码javascript
- 缩短几个元素的onclick代码 - JavaScript
- 英国银行排序代码 JavaScript 正则表达式
- 我无法在谷歌图表的代码 javascript 中获取 json 数据(项目 Python Hello Dashboard
- 和代码 JavaScript 没有被 &.
- 我怎样才能减少这段代码 javascript 代码,这样它就不会那么重复了
- 我想单击一个按钮,一次只执行已经制作的程序中的一行代码.(JavaScript)
- 滑动 DIV 代码 Javascript 的小问题
- 尝试重写代码 JavaScript
- 是否可以检测到在不使用键代码 javascript 的情况下按下了输入键
- 输入网址代码 JavaScript 播放器
- 管理通用客户端代码(javascript/css)
- 理解代码javascript
- 加载json-url参数代码(javascript修改)
- 变量检查错误的代码(javascript)
- css属性仅由代码javascript应用