Как упростить код, в котором много операторов if, и как быстрее изменить изображение - PullRequest
0 голосов
/ 21 февраля 2019

просто два простых вопроса,

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;
    }

Ответы [ 4 ]

0 голосов
/ 21 февраля 2019

Подробности комментируются в каждой строке демо.

Демо

/*
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>
0 голосов
/ 21 февраля 2019

Вы можете взять буксирные массивы для проверки строки детали с помощью include и для точной проверки и вернуть находку с замененными пробелами.

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'));
0 голосов
/ 21 февраля 2019

Вы можете использовать ассоциативный массив и перебирать ключи, чтобы найти совпадение.Сортировка клавиш в порядке частоты погодных условий может ускорить его, но незначительно.

Этот фрагмент заменяет пробелы в 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 происходит быстрее, чем создание нового элемента.Если он кажется медленным, то это проблема производительности веб-сервера.

Альтернативный вариант - реализовать спрайты изображений в CSS .Если изображения значков объединяются в одно изображение, вы можете использовать CSS-классы для отображения правильной части изображения, и новый значок погоды должен появляться в миллисекундах.

0 голосов
/ 21 февраля 2019

Используйте массивы, разделенные методом, который вам нужен, чтобы сравнить строку и перебрать списки значков.Если вам нужно изменить списки, вы можете просто сделать это в массивах.

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
...