款式/颜色多种元素,通过使用的setAttribute(的)(JavaScript)的
我建立了一个网页,检测您当地的天气预报。但是,为了使它具有独特性,我试图让网页在界面上改变颜色。它会根据天气api中的哪个天气图标更改颜色。 (即weath.weather [0] [“icon”])。我试图让它运行得尽可能快,同时让它更容易理解。所以我正在寻找一种替代方法。款式/颜色多种元素,通过使用的setAttribute(的)(JavaScript)的
我决定来存储颜色变化功能在一个变量,因此它可以被多次重复使用,所以我可以缩短switch语句。它包含一个可以重用的CSS字符串变量。字符串为函数的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>
我会得到来自API的图标数据,则switch语句将决定需要根据哪个图标就改变什么颜色。与使用着色()函数中的每一个开关箱会改变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;}
}
如果我要对这个错误的方式,将是很好的了解。我的主要目标是让其他开发人员更高效,更清晰。
你要对这个办法其实不是太远了,从我称之为“正确”的方式(通常有不止一个) - 有空间的一对夫妇微优化和清晰度增强器。
首先,如果你想增加其他的维护者可读性,我建议你存储命名常量的图标代码。一个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' }, { ... }]);
...的想法是,它只需要被调用一次,如果你通过完成整个开关案例所需的所有信息。
感谢您的反馈意见。事实上,你说的“正确”方式离我们不远,这告诉我我正在改进。我明白你来自使用变量的地方。但我不是更好地使用对象列表而不是个别变量吗?我有一个以前的对象列表形式的图标选择列表。我摆脱了它,因为我认为它会跑得更快,我只是在每个开关盒旁边写上引号。正如你所看到的,我已经做到了。无论如何感谢您的反馈。 –
@TommyJackson是的!你打赌,这绝对是那种“比一种”更多的方式。在一个switch语句和一个object map之间,无论你选择哪一个小数值,你的性能收益在差异上都可以忽略不计。如果您希望特别聪明(以一些可读性为代价),您甚至可以通过图标代码(如{'01d':{text:'...'等})来键入对象。 – wosevision
但是,只要在每个开关盒旁边添加引号,我会不会更好?那会使用更少的代码,并解释每个代码。 –
在功能
switch
声明思考是很有用的,但它不适合与功能代码休息你write.It有副作用,变异状态,副作用的机会,主要是不能与其它功能
组成应该有几乎总是一个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
}
}
应用钻营技术上述方法并使用三元取代传统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"])
);
保存在单独的变量中的对象为更好的可维护性。将所有着色方法移动到上面指定的一种方法中。它们写成单独的功能
希望将优化性能与上面的代码
由于代码已经是功能性的,我认为这个问题更适合在代码审查stackexchange:https://codereview.stackexchange.com/ 。在那里,人们可能会给你更好的反馈。 –
谢谢。有没有办法将这个转移到StackExchange代码审查与复制和粘贴? –
我不认为它有可能在那里移植它。 –