【问题标题】:How to simplify code that has a lot if statement and how to change image faster如何简化包含大量 if 语句的代码以及如何更快地更改图像
【发布时间】:2019-02-21 09:46:36
【问题描述】:

只有两个简单的问题,

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

【问题讨论】:

  • 不要同时问两个不同的问题。并且写I asked this question before but the answered code doesn't work with me而不提及它是哪个问题,这不是一个好主意,如果我不知道其他答案是什么,我为什么要花时间回答这个问题。
  • 这似乎并不复杂。为什么你觉得它需要简化?它看起来很“简单”。是什么让您认为这段代码“效率低下”?几乎不使用 CPU 来计算这将需要一秒的时间。真的不清楚你为什么这么反对这段代码?
  • @Liam 问题不是执行速度,问题是重复代码。
  • @Liam 啊,我忽略了第二个问题...
  • @Liam 我问如何更快地加载 bgImg 的原因是,当 API 发出新请求时,图像加载速度不快,更改图像 src 需要 1 或 2 秒,我认为这是表现不佳,这就是我问的原因。

标签: javascript performance if-statement ecmascript-6 ecmascript-5


【解决方案1】:

您可以使用两个数组进行包含包含的部分字符串检查,并进行精确检查并返回带有替换空格的查找。

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'));

【讨论】:

    【解决方案2】:

    使用由您需要的方法分隔的数组来比较字符串并循环遍历图标列表。如果您需要修改列表,您可以在数组中进行。

    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
    

    【讨论】:

    • 注意:这绝不会比 OP 已有的“更快”
    • 这将匹配 smoke something 但给定代码中的条件是 weatherName === "smoke" 所以它必须是完全匹配的。
    • @t.niese 在这里我对其进行了编辑以正确检查条件并给出正确的结果。
    • 我认为这是一个更复杂的解决方案,绝对不会更快
    【解决方案3】:

    您可以使用关联数组并遍历键以找到匹配项。按天气模式的频率顺序对键进行排序可能会加快速度,但不会显着。

    此 sn-p 将 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 类来显示图像的正确部分,并且新的天气图标应该以毫秒为单位出现。

    【讨论】:

      【解决方案4】:

      demo 的每一行都有详细的注释。

      演示

      /*
      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;
      }
      &lt;main class='bkg'&gt;&lt;/main&gt;

      【讨论】:

        猜你喜欢
        • 2018-12-30
        • 2019-08-24
        • 1970-01-01
        • 2014-08-30
        • 2022-01-22
        • 1970-01-01
        • 2021-11-20
        • 2014-06-18
        • 1970-01-01
        相关资源
        最近更新 更多