只是两个简单的问题,
Q(1)下面的代码有多个if else语句我想知道是否有一种方法可以使用数组或其他东西来简化它。
Q(2)有没有办法更快地更改bgImg.src,因为更改src需要更长的时间。
const bgImg = document.querySelector('#element-body img');
let icon = "";
if(weatherName.includes("rain")){
icon = "./images/rain.jpg";
}
else if(weatherName.includes("clouds")){
icon = "./images/clouds.jpg";
}
else if(weatherName.includes("snow")){
icon = "./images/snow.jpg";
}
else if(weatherName === "mist"){
icon = "./images/mist.jpg";
}
else if(weatherName === "clear sky"){
icon = "./images/clear-sky.jpg";
}
else if(weatherName === "smoke"){
icon = "./images/smoke.jpg";
}
else if(weatherName === "dust"){
icon = "./images/dust.jpg";
}
else if(weatherName === "drizzle"){
icon = "./images/rain.jpg";
}
else if(weatherName === "haze"){
icon = "./images/haze.jpg";
}
else if(weatherName === "fog"){
icon = "./images/foggy.jpg";
}
else if(weatherName === "thunderstorm"){
icon = "./images/thunderstorm.jpg";
}
else{
icon = "./images/pexels-photo-39811.jpg";
}
}
bgImg.src = icon;
}
您可以使用两个数组进行部分字符串检查,包括并进行精确检查,并返回包含替换空格的查找。
const getIcon = weather => {
var includes = ['rain', 'clouds'],
exact = ['snow', 'mist', 'clear sky', 'smoke', 'dust', 'drizzle', 'haze', 'fog', 'thunderstorm'],
type = includes.find(w => weather.includes(w)) ||
exact.includes(weather) && weather ||
'pexels-photo-39811';
return `./images/${type.replace(/\s/g, '-')}.jpg`;
};
console.log(getIcon('some rain'));
console.log(getIcon('clear sky'));
console.log(getIcon('foo'));
使用由您需要的方法分隔的数组来比较字符串和循环图标列表。如果需要修改列表,可以在阵列中进行修改。
const bgImg = document.querySelector('#element-body img');
const iconListInclude = [
'rain',
'clouds',
'snow',
]
const iconListEqual = [
'mist',
'clear sky',
'smoke',
'dust',
'drizzle',
'haze',
'fog',
'thunderstorm',
]
let icon = "./images/pexels-photo-39811.jpg"
iconListInclude.forEach(i => {
if (weatherName.includes(i)) icon = "./images/"+i+".jpg"
})
iconListEqual.forEach(i => {
if (weatherName === i) icon = "./images/"+i+".jpg"
})
bgImg.src = icon
您可以使用关联数组并遍历键以查找匹配项。按照天气模式的频率对按键进行排序可能会加快速度,但不会显着。
这个片段用weatherName
替换-
中的空格,并将字符串更改为小写只是为了安全。
const weatherName = "Clear Sky";
const bgImg = document.querySelector('#element-body img');
const localWeather = weatherName.replace(/\s/, '-').toLowerCase();
// Default icon name
let icon = 'pexels-photo-39811';
const iconNames = {
'clouds': 'clouds',
'clear-sky': 'clear-sky',
'drizzle': 'rain',
'dust': 'dust',
'fog': 'foggy',
'haze': 'haze',
'mist': 'mist',
'rain': 'rain',
'snow': 'snow',
'smoke': 'smoke',
'thunderstorm': 'thunderstorm',
}
for (let key of Object.keys(iconNames)) {
if (localWeather.includes(key)) {
icon = iconNames[key];
// Icon found so exit the `for()` loop
break;
}
}
bgImg.src = `./images/${icon}.jpg`;
<div id="element-body">
<img id="weather-icon" src="" title="Local weather" />
</div>
在回答问题的第2部分时,交换图像src
属性的值比创建新元素更快。如果它看起来很慢那么这就是Web服务器性能问题。
另一种选择是implement image sprites in CSS。如果将图标图像连接成单个图像,则可以使用CSS类来显示图像的正确部分,新的天气图标应以毫秒为单位显示。
详细信息在演示的每一行都有评论。
演示
/*
Use a block element (ex. <section>...</section>) to contain a
background image. A block element allows greater control.
*/
const bkg = document.querySelector('.bkg');
/*
Have an array of the images. Use only the unique part of each
url which is usually the file name (ex. ./images/UNIQUE_PART.jpg).
*/
const whiteList = ["rain", "clouds", "snow", "mist", "clear", "smog", "dust", "haze", "fog", "storm"];
// Assuming that API provides an array of strings.
const weatherName = ['crappy', 'crappier', 'level 5', 'flash flooding', "mist", 'smog', 'crappiest', 'swamp ass'];
/*
filterList(array1, array2)
Returns all matches in an array, or an empty array if there are
no matches.
*/
const filterList = (arr1, arr2) => arr1.filter(ele => arr2.includes(ele));
// Store result in a variable.
const icon = filterList(whiteList, weatherName);
/*
If there was no match [?] use the default image file name [:]
Otherwise use the first image file name of the returned array.
*/
let image = icon === [] ? `pexels-photo-39811` : icon[0];
/*
Interpolate image file name into a Template Literal that consists
of the common part of the url.
*/
const url = `https://i.ibb.co/y4Ctj4p/${image}.jpg`;
/*
Assign the CSS style property backgroundImage to the [style]
attribute of the block element. There are 2 reasons why [style]
attribute is used:
1. Using the [style] attribute is the simplest way to style any
DOM element.
2. It's nigh impossible to override it and it overrides
everything so there's no suprises.
*/
bkg.style.backgroundImage = `url(${url})`;
html,
body {
width: 100%;
height: 100%;
font: 400 16px/1.45 Verdana;
}
body {
overflow-x: hidden;
overflow-y: scroll;
font-size: 1rem;
}
.bkg {
width: 100%;
height: 100%;
margin: 0 auto;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
<main class='bkg'></main>