我正在构建一个网页,用于检测您当地的天气预报。但是,为了使其独一无二,我试图让网页在界面上改变颜色。它会根据天气api中的天气图标改变颜色。 (即weath.weather [0] [" icon"])。我试图让它尽可能快地运行,同时让它更容易理解。所以我正在寻找另一种方法。
我决定将颜色更改功能存储在变量中,因此可以多次重复使用,这样我就可以缩短Switch语句。它包含一个可以重用的CSS字符串变量。 string是setAttribute函数的样式属性:
var coloring = function(id, Text, Background) {
var colorChange = "color: " + Text + "; background: " + Background + ";";
document.getElementById(id).setAttribute("style", colorChange);
};
这将用于通过引用其ID来更改Dom的各种元素/部分的颜色。这是Dom:
<body id="background">
<div id="header">
<h1>Local Weather Detector</h1>
</div>
<div id="location">
<h5 id="locIntro">Today's weather from Location...</h5>
</div>
<div id="box">
<div id="temperature">
<p><strong>Today, </strong>The temperature in your area is...
<button id="tempSwap">
</button></p>
</div>
<div id="weather">
<p>- and the general forecast is...</p>
</div>
</div>
<div id="copywrite"><h6> Ⓒ Thomas Jackson</h6>
<h6>(Project for Free Code Camp, Full Stack course)</h6></div>
</body>
&#13;
我会从api获取图标数据,然后switch语句将确定需要更改哪些颜色,具体取决于它是哪个图标。使用coloring()函数的每个Switch Case都会将Dom的颜色更改为自己的设置颜色:
$.getJSON(api, function(weath) {
switch (weath.weather[0]["icon"]) {
case "01d": //clear
coloring("background", "#f1c40f", "#3498db");
coloring("box", "#2980b9", "#ecf0f1");
coloring("temp", "#c0392b", "");
break;
case "01d":
case "03d":
case "04d":
case "50d": //cloud
coloring("background", "#3498db", "#ecf0f1");
coloring("header", "#f1c40f", "");
coloring("box", "", "#2980b9");
coloring("temp", "", "#3498db");
break;
case "02d": //cloudClear
coloring("background", "c0392b", "#2980b9");
coloring("header", "#f1c40f", "");
coloring("box", "", "#ecf0f1");
coloring("temp", "", "#2980b9");
break;
case "11d": //thunder
coloring("background", "#c0392b", "#2980b9");
coloring("header", "#f1c40f", "");
coloring("box", "", "#f1c40f");
coloring("temp", "", "#c0392b");
break;
case "13d": //snow
coloring("background", "#ecf0f1", "#2980b9");
coloring("header", "#34495e", "");
coloring("box", "", "#a5f2f3");
coloring("temp", "", "#34495e");
break;
case "03n":
case "04n":
case "50n": //cloudNight
coloring("background", "#ecf0f1", "#7f8c8d");
coloring("header", "#e74c3c", "");
coloring("box", "#f1c40f", "#34495e");
coloring("temp", "", "#2c3e50");
break;
case "09n":
case "10n": //rainNight
coloring("background", "#3498db", "#2c3e50");
coloring("header", "#f1c40f", "");
coloring("box", "#2980b9", "#95a5a6");
coloring("temp", "#3498db", "#2980b9");
break;
case "11n": //thunderNight
coloring("background", "#f1c40f", "#2c3e50");
coloring("header", "#e74c3c", "");
coloring("box", "#c0392b", "#f1c40f");
coloring("temp", "", "#c0392b");
break;
case "13n": //snowNight
coloring("background", "#f1c40f", "#2c3e50");
coloring("header", "#a5f2f3", "");
coloring("box", "#34495e", "#a5f2f3");
coloring("temp", "#2c3e50", "#f1c40f");
break;}
}
如果我以错误的方式解决这个问题,那将会很有用。我的主要目标是让其他开发人员更加高效和清晰。
答案 0 :(得分:0)
你实现这一目标的方式实际上与我称之为“正确”的方式相距太远了。&#34;方式(通常不止一个) - 虽然有一些微观优化和清晰度提升器的空间。
首先,如果您想提高其他维护者的可读性,我建议您将图标代码存储在命名常量中。 case: "01d"
并没有告诉我任何关于图标是什么的信息,但是这样做:
var ICON_STORMY = "01d";
switch (weath.weather[0].icon) {
case ICON_STORMY:
...
break;
...
}
其次,你的着色功能被大量使用,所以我会把它收紧一点 - 不是很多,但可能只是为了每次id
可以调用一次而不是一次。
function colorAll(elems) {
elems.forEach(function (elem) {
var colorChange = "color: " + elem.text + "; background: " + elem.background + ";";
document.getElementById(elem.id).setAttribute("style", colorChange);
});
}
...然后使用这样的函数:
colorAll([{ id: 'background', text: 'blah blah', background: '#666666' }, { ... }]);
...这个想法是,如果你传递完成整个开关案例所需的所有信息,只需要调用一次。
答案 1 :(得分:0)
在功能上思考
switch
语句很有用,但它不适合你编写的其他功能代码。它有副作用,有可能改变状态,副作用,主要是不能组成与其他功能
在switch语句中应该几乎总是有一个默认情况。我假设。如果没有找到关注值,则不会注册。
weath.weather[0]["icon"]
。让我们来看看我们正在处理的开关案例
$.getJSON(api, function(weath) {
switch (weath.weather[0]["icon"]) {
case "01d": //clear
coloring("background", "#f1c40f", "#3498db");
coloring("box", "#2980b9", "#ecf0f1");
coloring("temp", "#c0392b", "");
break;
case "01d":
case "03d":
case "04d":
case "50d": //cloud
coloring("background", "#3498db", "#ecf0f1");
coloring("header", "#f1c40f", "");
coloring("box", "", "#2980b9");
coloring("temp", "", "#3498db");
break;
default:
console.log(`case is not registered`);
break;
}
}
如果我们转换为三元,代码看起来像这样。我正在使用ES6箭头功能以提高可读性
$.getJSON(api,(weath) => {
const icon = weath.weather[0].icon;
// try to convert switch to if/else or ternary
icon === '01d' ? coloring() : //coloring methods of 01d
icon === '02d' ? coloring() //coloring methods of 02d
: console.log('no case matched');
});
可以使用如下函数
优化此重复代码const switchcase = (cases, defaultCase, key) => {
if (key in cases) {
return cases[key]
} else {
return defaultCase
}
}
将currying技术应用于上述方法并使用三元而不是传统的if else
const switchcase = cases => defaultCase => key =>
key in cases ? cases[key] : defaultCase
现在代码可以像下面那样进行优化
$.getJSON(api, switchcase({
'01d' : coloring1(),
'02d' : coloring2()
})(console.log('no case matched'))(weath.weather[0].icon)
);
这个早期版本的switchcase
有一个问题,因为在传递给switchcase
函数之前会对整个对象文字进行求值。这意味着coloring1()
和coloring2()
都会被评估。这可能非常危险。
如果对象文字中的值是函数,那么只有在匹配的情况下才能执行它们。
代码将更改为
$.getJSON(api, switchcase({
'01d':() => { coloring('x');coloring('...');},
'02d':() => { coloring('y');coloring('...');}
})(() => console.log('no cases matched'))(weath.weather[0].icon)
);
优化代码
$.getJSON(api, switchcase({
01d:() => coloringClear(),
03d:() => coloringCloud(),
04d:() => coloringCloud(),
50d:() => coloringCloud(),
02d:() => coloringCloudClear(),
11d:() => coloringThunder(),
13d:() => coloringSnow(),
03n:() => coloringCloudNight(),
04n:() => coloringCloudNight(),
50n:() => coloringCloudNight(),
09n:() => coloringRainNight(),
10n:() => coloringRainNight(),
11n:() => coloringThunderNight(),
13n:() => coloringSnowNight()
})('Unknown')(weath.weather[0]["icon"])
);
将对象保存在单独的变量中以获得更好的可维护性。将所有着色方法移动到如上所述的一个方法中。把它们写成单独的函数
希望用上面的代码优化性能