Приложение «Погода» — эффективен ли мой код?

Я создал погодное приложение, которое меняет цвет фона в зависимости от температуры и описания погоды.

Это код, который я должен заставить работать.

const body = document.querySelector('body');

const colorList = [
  {weather: 'Clear', color1: '#7AE7C7', color2: '#72C1E1'},
  {weather: 'Clouds', color1: '#F981BB', color2: '#7F7E84'},
  {weather: 'Drizzle', color1: '#b2c9c8', color2: '#698b8b'},
  {weather: 'Fog', color1: '#C5B2A6', color2: '#7F7E84'},
  {weather: 'Rain', color1: '#504AC4', color2: '#59AED1'},
  {weather: 'Snow', color1: '#bfc9cf', color2: '#77BDE0'},
  {weather: 'Thunderstorm', color1: '#314F71', color2: '#4A4176'},
  {weather: 'Tornado', color1: '#939393', color2: '#e47977c5'}


 ]



const colorList2 = [
      {color1: '#C94926', color2: '#BB9F34'},
      {color1: '#89a1dd', color2: '#E4E5E7' }
   ]



if(weather.list[0].main.temp < 5 && weather.list[0].weather[0].main == 'Clear') {
      body.style.backgroundImage = `linear-gradient(to bottom right, 
      ${colorList2[1].color1}, ${colorList2[1].color2})`;
   } else if(weather.list[0].main.temp > 15 && weather.list[0].weather[0].main == 'Clear'){
        body.style.backgroundImage = `linear-gradient(to bottom right, 
        ${colorList2[0].color1}, ${colorList2[0].color2})`;
     } else {
          colorList.forEach(color => {
             if(color.weather == weather.list[0].weather[0].main) {
                body.style.backgroundImage = `linear-gradient(to bottom right, 
                ${color.color1}, ${color.color2})`;
   }

Есть ли более эффективный способ сделать то же самое? Являются ли циклы forEach излишними? Следует ли использовать операторы if else? Должен ли я вообще делать это на JavaScript?

Спасибо заранее.

2 ответа
2

Во-первых, ваш список цветов погоды уникален weather key, и вы запрашиваете цвет на его основе. Я бы посоветовал превратить это в объект, цвета которого зависят от погодных условий. Таким образом легче найти цвета по условию, чем с помощью цикла. Вы также получаете одно дополнительное преимущество: вы можете добавить свои особые случаи Clear в один и тот же объект, только с уникальным значением ключа.

Затем вы захотите присвоить эти свойства переменным. Считывание длинных доступов к свойствам затруднено.

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

Вот как бы я это сделал.

const colorsByCondition = {
  Clear: {
    color1: '#7AE7C7',
    color2: '#72C1E1'
  },
  // Special forms of Clear
  Clear5: {
    color1: '#89a1dd',
    color2: '#E4E5E7'
  },
  Clear15: {
    color1: '#C94926',
    color2: '#BB9F34'
  },
  // Other conditions
  Clouds: {
    color1: '#F981BB',
    color2: '#7F7E84'
  },
  // and so on...
}

// Assign to variables
// const weather = weather.list[0]
// const temp = weather.main.temp
// const conditions = weather.weather[0].main

// Assuming these values represent our weather
const temp = 6
const conditions="Clear"

// Find the right colors
const { color1, color2 } = temp < 5 && conditions == 'Clear'
  ? colorsByCondition.Clear5
  : temp > 15 && conditions == 'Clear'
    ? colorsByCondition.Clear15
    : colorsByCondition[conditions]

// Apply to the body
document.body.style.backgroundImage = `linear-gradient(to bottom right, ${color1}, ${color2})`

  • Спасибо, ваша помощь очень ценится! Да, мне показалось, что иметь дополнительный список под названием «colorList2» было немного беспорядочно. Ваш путь кажется намного лучше и чище.

    — МБГ

Использовать CSS для стиля

Вы пытаетесь добавить стили с помощью JavaScript. Это заставляет ваш JavaScript смешивать логику и стили вместе. Я бы предложил разделить стили на CSS.

Например, ваш Javascript:

{weather: 'Clear', color1: '#7AE7C7', color2: '#72C1E1'},
/* ... */
{color1: '#C94926', color2: '#BB9F34'},
/* ... */
body.style.backgroundImage = `linear-gradient(to bottom right, ${color.color1}, ${color.color2})`;

Вы можете преобразовать его в CSS, например

.weather-clear { --color-start: #7AE7C7; --color-end: #72C1E1; }
/* ... */
.weather-clear.weather-cold { --color-start: #C94926; --color-end: #BB9F34; }
/* ... */
body { background-image: linear-gradient(to bottom right, var(--color-start), var(--color-end)); }

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

const body = document.body;
body.classList.add('weather-' + weather.list[0].weather[0].main.toLowerCase());
if (weather.list[0].main.temp < 5) body.classList.add('weather-cold');
if (weather.list[0].main.temp > 15) body.classList.add('weather-hot');

Сложите все вместе:

const body = document.body;
const temp = 18, main = 'Clear';
body.classList.add('weather-' + main.toLowerCase());
if (temp < 5) body.classList.add('weather-cold');
if (temp > 15) body.classList.add('weather-hot');
.weather-clear { --color-start: #7AE7C7; --color-end: #72C1E1; }
.weather-clouds { --color-start: #F981BB; --color-end: #7F7E84; }
.weather-drizzle { --color-start: #b2c9c8; --color-end: #698b8b; }
.weather-fog { --color-start: #C5B2A6; --color-end: #7F7E84; }
.weather-rain { --color-start: #504AC4; --color-end: #59AED1; }
.weather-snow { --color-start: #bfc9cf; --color-end: #77BDE0; }
.weather-thunderstorm { --color-start: #314F71; --color-end: #4A4176; }
.weather-tornado { --color-start: #939393; --color-end: #e47977c5; }
.weather-clear.weather-cold { --color-start: #C94926; --color-end: #BB9F34; }
.weather-clear.weather-hot { --color-start: #89a1dd; --color-end: #E4E5E7; }

body { background-image: linear-gradient(to bottom right, var(--color-start), var(--color-end)); }
body { height: 100vh; box-sizing: border-box; margin: 0; }

[Note] Если вы нацелены на поддержку старых браузеров (без поддержки CSS var): удалите переменные CSS, используйте linear-gradient прямо в .weather-clear и так.

    Добавить комментарий

    Ваш адрес email не будет опубликован.