通过使用setAttribute()(Javascript)使用Switch语句对多个元素进行样式/着色

时间:2017-10-15 12:07:30

标签: javascript css switch-statement weather-api setattribute

我正在构建一个网页,用于检测您当地的天气预报。但是,为了使其独一无二,我试图让网页在界面上改变颜色。它会根据天气api中的天气图标改变颜色。 (即weath.weather [0] [" icon"])。我试图让它尽可能快地运行,同时让它更容易理解。所以我正在寻找另一种方法。

我决定将颜色更改功能存储在变量中,因此可以多次重复使用,这样我就可以缩短Switch语句。它包含一个可以重用的CSS字符串变量。 string是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> &#9400; Thomas Jackson</h6>
      <h6>(Project for Free Code Camp, Full Stack course)</h6></div>
</body>
&#13;
&#13;
&#13;

我会从api获取图标数据,然后switch语句将确定需要更改哪些颜色,具体取决于它是哪个图标。使用coloring()函数的每个Switch Case都会将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;}

}

如果我以错误的方式解决这个问题,那将会很有用。我的主要目标是让其他开发人员更加高效和清晰。

2 个答案:

答案 0 :(得分:0)

你实现这一目标的方式实际上与我称之为“正确”的方式相距太远了。&#34;方式(通常不止一个) - 虽然有一些微观优化和清晰度提升器的空间。

首先,如果您想提高其他维护者的可读性,我建议您将图标代码存储在命名常量中。 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' }, { ... }]);

...这个想法是,如果你传递完成整个开关案例所需的所有信息,只需要调用一次。

答案 1 :(得分:0)

在功能上思考

switch语句很有用,但它不适合你编写的其他功能代码。它有副作用,有可能改变状态,副作用,主要是不能组成与其他功能

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

将currying技术应用于上述方法并使用三元而不是传统的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"])
);

将对象保存在单独的变量中以获得更好的可维护性。将所有着色方法移动到如上所述的一个方法中。把它们写成单独的函数

希望用上面的代码优化性能