在两个js函数中重复代码,如何消除和使代码优雅

时间:2017-03-29 03:29:39

标签: javascript html

好的,我有以下javascript代码:

<script type="text/javascript">
window.onload=function() {
    // variables for the different pulldown menu's
    var selectPotency = document.getElementById("select-potency");
    var selectEssence = document.getElementById("select-essence");
    var selectAspect = document.getElementById("select-aspect");


    // defualt values of runes
    document.getElementById('potencyRune').innerHTML = 'Jode';
    document.getElementById('essenceRune').innerHTML = 'Oko';
    document.getElementById('aspectRune').innerHTML = 'Ta';

    // start with white glyph text
    document.getElementById('glyph').style.color = "#FFF";
    document.getElementById('select-potency').style.color = 'inherit';
    document.getElementById('select-essence').style.color = 'inherit';
    document.getElementById('select-aspect').style.color = 'inherit';

    // lookup tables for runes and translations
    var PotencyTable1 = {...};
    var PotencyTable0 = {...};
    var EssenceTable = {...};
    var AspectTable = {...};

    // This function changes the potency rune from select-potency
    selectPotency.onchange=function getPotency() {
        var potency = this.value;
        var elem = document.getElementById('select-essence');
        var polarity = elem.options[elem.selectedIndex].value;

        if (polarity == 0) {
            document.getElementById('potencyRune').innerHTML = PotencyTable0[potency]();
        }
        if (polarity == 1) {
            document.getElementById('potencyRune').innerHTML = PotencyTable1[potency]();
        }   
    }

    // This function changes the essence rune from select-essence
    selectEssence.onchange=function getEssence() {
        var essence  = this.options[this.selectedIndex].text;
        var polarity = this.options[this.selectedIndex].value;

        var elem = document.getElementById('select-potency');
        var potency = elem.options[elem.selectedIndex].value;

        document.getElementById('essenceRune').innerHTML = EssenceTable[essence]();

        if (polarity == 0) {
            document.getElementById('potencyRune').innerHTML = PotencyTable0[potency]();
        }
        if (polarity == 1) {
            document.getElementById('potencyRune').innerHTML = PotencyTable1[potency]();
        }
    }

    // This function changes the color of the glyph name & aspect rune from select-aspect
    selectAspect.onchange=function getAspect() {
        var aspect = this.value;
        var colour = $(this).find('option:selected').attr('data-color');

        document.getElementById('glyph').style.color = colour;
        document.getElementById('aspectRune').innerHTML = AspectTable[aspect]();
    }
}

现在有3个不同的区域,我重复了代码,因为我不知道该怎么做:

1)符文的默认值 - 当用户从下拉菜单中选择时,3个不同函数中的每一个都设置这些值,但我不知道如何在页面加载时运行这些函数获取下拉选项的初始值,以便我这样设置默认值。

2)//以白色字形文字开头 - 再次,类似于#1,我不知道如何在页面加载时运行getAspect函数以将颜色设置为白色所以我手动操作将文字颜色设置为白色。

3)在函数getPotency和getEssence中有两个if语句完全相同。它们属于getPotency函数,但getEssence函数也改变了它们,但我不知道如何调用它,所以我重复了代码。

4)最后,如果你有任何改动让我的代码更优雅/专业,我将非常感激。我是自学成才,这是我第一次涉足javascript。

非常感谢您提供所有反馈!

Here's the website I've got soo far with the code

1 个答案:

答案 0 :(得分:1)

通常情况下这是一个更适合Code Review的问题,但由于很明显您在问题上花了一些时间和精力,我会在这个网站上提供答案。

以下是一些帮助您了解我如何重构代码的指示:

  • 让每个Table存储值作为字符串,而不是返回字符串的函数;
  • 使用长度为2的数组将PotencyTable组合在一起,这会产生副作用,即在根据极性访问符文时无需使用if语句;
  • #glyph上的默认#fff颜色(color: inherit)和#glyph > select最好由CSS而不是JavaScript设置;

  • 当您没有插入代码时,将innerHTML更改为textContent;

  • <script>移到</body>标记之前,以避免使用onload;

  • 使用不同的嵌套数据结构将<select>,符文和查找值表存储在一个位置(PotencyEssenceAspect);

  • select.options[select.selectedIndex].value可以缩短为select.value;

  • 将您的颜色和极性放在嵌套数据结构中,而不是嵌入HTML;

  • 将所有事件侦听器合并到一个update函数中,并使用select循环将它们添加到每个forEach;以及

  • 在脚本结束前拨打update()一次,而不是手动设置默认符文。

运行下面的代码段时,请务必点击“完整页面”,否则内容会被截断。

<小时/>

重构代码:

#glyph > select {
  color: inherit;
}
<!DOCTYPE html>
<html>

<head>
  <link rel="icon" sizes="16x16 32x32" href="http://dstealth.com/favicon.ico">
  <link rel="stylesheet" type="text/css" href="http://eso.dstealth.com/style.css" />
  <title>ESODEX - Enchanting Glyph Calculator</title>
  <meta name="viewport" content="width=device-width, height=device-height, initial-scale=0.85, minimum-scale=0.85">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>

<body>
  <div id="body">
    <div id="header" class="fog">
      <div id="table-cell">
        <div align="center">
          <span class="f30">Lethal's ESODEX</span><br/>
          <span class="f20 teal fog">&nbsp;&nbsp;Enchanting&nbsp;&nbsp;</span>
        </div>
      </div>
    </div>
    <div id="smoketop">&nbsp;</div>
    <div id="wrapper">
      <div id="fogcontent" class="fogcontent">
        <div id="content" align="center">
          <br/>
          <span id="glyph">
			<select id="select-potency">
				<option value="trifling">LVL .1 - Trifling</option>
				<option value="inferior">LVL .5 - Inferior</option>
				<option value="petty">LVL 10 - Petty</option>
				<option value="slight">LVL 15 - Slight</option>
				<option value="minor">LVL 20 - Minor</option>
				<option value="lesser">LVL 25 - Lesser</option>
				<option value="moderate">LVL 30 - Moderate</option>
				<option value="average">LVL 35 - Average</option>
				<option value="strong">LVL 40 - Strong</option>
				<option value="major">LVL C10 - Major</option>
				<option value="greater">LVL C30 - Greater</option>
				<option value="grand">LVL C50 - Grand</option>
				<option value="splendid">LVL C70 - Splendid</option>
				<option value="monumental">LVL C100- Monumental</option>
			</select>
			&nbsp;Glyph of&nbsp;
			<select id="select-essence" name="essence-all">
				<option>Absorb Health</option>
				<option>Absorb Magicka</option>
				<option>Absorb Stamina</option>
				<option>Bashing</option>
				<option>Crushing</option>
				<option>Decrease Health</option>
				<option>Decrease Physical Harm</option>
				<option>Decrease Spell Harm</option>
				<option>Disease Resist</option>
				<option>Fire Resist</option>
				<option>Flame</option>
				<option>Foulness</option>
				<option>Frost</option>
				<option>Frost Resist</option>
				<option>Hardening</option>
				<option>Health</option>
				<option>Health Regen</option>
				<option>Increase Magical Harm</option>
				<option>Increase Physical Harm</option>
				<option>Magicka</option>
				<option>Magicka Regen</option>
				<option>Poison</option>
				<option>Poison Resist</option>
				<option>Potion Boost</option>
				<option>Potion Speed</option>
				<option>Rage</option>
				<option>Reduce Feat Cost</option>
				<option>Reduce Spell Cost</option>
				<option>Shielding</option>
				<option>Shock</option>
				<option>Shock Resist</option>
				<option>Stamina</option>
				<option>Stamina Regen</option>
				<option>Weakening</option>
			</select>
			&nbsp;
			<select id="select-aspect">
				<option style="color:#FFF;" value="base">Base</option>
				<option style="color:#2DC50E;" value="fine">Fine</option>
				<option style="color:#3A92FF;" value="superior">Superior</option>
				<option style="color:#A02EF7;" value="artifact">Artifact</option>
				<option style="color:#E5CB51;" value="legendary">Legendary</option>
			</select><br/>
		</span>
          <br/>
          <hr><br/><br/>
          <div id="runes" class="f15">
            <span id="potencyRune">&nbsp;</span>&nbsp;&nbsp;
            <span id="essenceRune">&nbsp;</span>&nbsp;&nbsp;
            <span id="aspectRune">&nbsp;</span>
          </div>
          <br/><br/><br/><br/>
        </div>
      </div>
    </div>
    <div id="smokebot">&nbsp;</div>
    <div id="footer" class="fog" align="center">
      <div id="table-cell">
        <div align="center">
          <span class="f10">Last Updated Mar. 26, 2017</span><br/><br/>
          <span id="align-left" class="f10">For ESO version: 2.7.10</span>
          <span id="align-right" class="f10">&copy; Copyright 2017</span>
        </div>
      </div>
    </div>
  </div>

  <script type="text/javascript">
    var Potency = {
      $select: document.getElementById("select-potency"),
      $rune: document.getElementById('potencyRune'),
      runes: {
        "trifling": ["Jode", "Jora"],
        "inferior": ["Notade", "Porade"],
        "petty": ["Ode", "Jera"],
        "slight": ["Tade", "Jejora"],
        "minor": ["Jayde", "Odra"],
        "lesser": ["Edode", "Pojora"],
        "moderate": ["Pojode", "Edora"],
        "average": ["Rekude", "Jaera"],
        "strong": ["Hade", "Pora"],
        "major": ["Idode", "Denara"],
        "greater": ["Pode", "Rera"],
        "grand": ["Kedeko", "Derado"],
        "splendid": ["Rede", "Recura"],
        "monumental": ["Kude", "Cura"]
      }
    }

    var Essence = {
      $select: document.getElementById("select-essence"),
      $rune: document.getElementById('essenceRune'),
      runes: {
        "Absorb Health": "Oko",
        "Absorb Magicka": "Makko",
        "Absorb Stamina": "Deni",
        "Bashing": "Jaedi / Kaderi",
        "Crushing": "Deteri",
        "Decrease Health": "Okoma",
        "Decrease Physical Harm": "Lire / Taderi",
        "Decrease Spell Harm": "Makderi",
        "Disease Resist": "Haoko",
        "Fire Resist": "Rakeipa",
        "Flame": "Rakeipa",
        "Foulness": "Haoko",
        "Frost": "Dekeipa",
        "Frost Resist": "Dekeipa",
        "Hardening": "Deteri",
        "Health": "Oko",
        "Health Regen": "Okoma",
        "Increase Magical Harm": "Makderi",
        "Increase Physical Harm": "Lire / Taderi",
        "Magicka": "Makko",
        "Magicka Regen": "Makkoma",
        "Poison": "Kuoko",
        "Poison Resist": "Kuoko",
        "Potion Boost": "Oru",
        "Potion Speed": "Oru",
        "Rage": "Okori",
        "Reduce Feat Cost": "Denima",
        "Reduce Spell Cost": "Makkoma",
        "Shielding": "Jaedi / Kaderi",
        "Shock": "Meip",
        "Shock Resist": "Meip",
        "Stamina": "Deni",
        "Stamina Regen": "Denima",
        "Weakening": "Okori"
      },
      polarities: {
        "Absorb Health": 0,
        "Absorb Magicka": 0,
        "Absorb Stamina": 0,
        "Bashing": 1,
        "Crushing": 0,
        "Decrease Health": 0,
        "Decrease Physical Harm": 0,
        "Decrease Spell Harm": 0,
        "Disease Resist": 0,
        "Fire Resist": 0,
        "Flame": 1,
        "Foulness": 1,
        "Frost": 1,
        "Frost Resist": 0,
        "Hardening": 1,
        "Health": 1,
        "Health Regen": 1,
        "Increase Magical Harm": 1,
        "Increase Physical Harm": 1,
        "Magicka": 1,
        "Magicka Regen": 1,
        "Poison": 1,
        "Poison Resist": 0,
        "Potion Boost": 1,
        "Potion Speed": 0,
        "Rage": 1,
        "Reduce Feat Cost": 0,
        "Reduce Spell Cost": 0,
        "Shielding": 0,
        "Shock": 1,
        "Shock Resist": 0,
        "Stamina": 1,
        "Stamina Regen": 1,
        "Weakening": 0
      }
    }

    var Aspect = {
      $select: document.getElementById("select-aspect"),
      $rune: document.getElementById('aspectRune'),
      runes: {
        "base": "Ta",
        "fine": "Jejota",
        "superior": "Denata",
        "artifact": "Rekuta",
        "legendary": "Kuta"
      },
      colors: {
        "base": "#FFF",
        "fine": "#2DC50E",
        "superior": "#3A92FF",
        "artifact": "#A02EF7",
        "legendary": "#E5CB51"
      }
    }

    var glyph = document.getElementById('glyph')

    function update() {
      var potency = Potency.$select.value
      var essence = Essence.$select.value
      var aspect = Aspect.$select.value

      var polarity = Essence.polarities[essence]
      var color = Aspect.colors[aspect]


      glyph.style.color = color

      Potency.$rune.textContent = Potency.runes[potency][polarity]
      Essence.$rune.textContent = Essence.runes[essence]
      Aspect.$rune.textContent = Aspect.runes[aspect]
    }

    [Potency, Essence, Aspect].forEach(function(E) {
      E.$select.addEventListener('change', update)
    })

    update()
  </script>

  <script type="text/javascript">
    $(".fade").click(function(event) {
      event.preventDefault();
      linkLocation = this.href;
      $("body").fadeOut(1000, redirectPage);
    });

    function redirectPage() {
      window.location = linkLocation;
    }
  </script>
</body>

</html>