为什么乘法只在刷新后发生?

时间:2017-02-26 18:10:13

标签: javascript html

我有一个计算器。这有一种形式,对于某些计算,只有在我刷新页面时才有效。添加有效但乘法仅在刷新后有效。那是为什么?

我不想使用JQuery!



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <title>Card Form</title>

  <link href="styles/cardform.css" rel="stylesheet" type="text/css" />
</head>

<body onload='hideTotal()'>
  <div id="wrap">
    <form action="" id="cardform" onsubmit="return false;">
      <div>
        <div class="cont_order">
          <fieldset>
            <legend>Check Quotes</legend>
            <label>Size Of the Card</label>
            <label>Width in cm:  </label> <input type="text" id="width" />
            <label>Height in cm:  </label> <input type="text" id="height" />
            <br/>

            <br/>

            <label class='radiolabel'><input type="radio"  name="selectedcard1" value="Round13"  onclick=""/>Standard</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard1" value="Round14" onclick="" />Toughened</label><br/>

            <br/>
            <label>Card:  </label>
            <label class='radiolabel'><input type="radio"  name="selectedcard2" value="Round17"  onclick=""/>Clear</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard2" value="Round18" onclick="" />Frosted</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard2" value="Round19" onclick="" />Leaded</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard2" value="Round20" onclick="" />White Bar</label>
            <br/>
            <label>Frame:  </label>
            <label class='radiolabel'><input type="radio"  name="selectedcard3" value="Round21"  onclick=""/>uPVC</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard3" value="Round22" onclick="" />Metal</label>
            <label class='radiolabel'><input type="radio"  name="selectedcard3" value="Round23"  onclick=""/>Wood</label>

            <br/>
            <input type="submit" value="Calculate" onClick="calculateTotal()" />
            <INPUT TYPE="reset" VALUE="RESET" onClick="resetIt()" />
            <div id="totalPrice"></div>

          </fieldset>
        </div>

      </div>
    </form>
  </div>
  <!--End of wrap-->

</body>
<script>
  var size1 = document.getElementById("width").value;
  var size2 = document.getElementById("height").value;

  var total_size = ((size1 * size2) / 10000);

  var card_prices = new Array();


  card_prices["Round13"] = (total_size * 67);
  card_prices["Round14"] = (total_size * 87);

  card_prices["Round17"] = (total_size * 0.05);
  card_prices["Round18"] = (total_size * 0.65);
  card_prices["Round19"] = (total_size * 0.85);
  card_prices["Round20"] = (total_size * 0.95);






  function getCardSizePrice2() {

    var cardSizePrice = 0;
    //Get a reference to the form id="cardform"
    var theForm = document.forms["cardform"];
    //Get a reference to the card the user Chooses name=selectedCard":
    var selectedCard1 = theForm.elements["selectedcard1"];
    //Here since there are 4 radio buttons selectedCard.length = 4
    //We loop through each radio buttons
    for (var i = 0; i < selectedCard1.length; i++) {
      //if the radio button is checked
      if (selectedCard1[i].checked) {
        //we set cardSizePrice to the value of the selected radio button
        //i.e. if the user choose the 8" card we set it to 25
        //by using the card_prices array
        //We get the selected Items value
        //For example card_prices["Round8".value]"
        cardSizePrice = card_prices[selectedCard1[i].value];
        //If we get a match then we break out of this loop
        //No reason to continue if we get a match
        break;
      }
    }
    //We return the cardSizePrice
    return cardSizePrice;
  }

  function getCardSizePrice3() {

    var cardSizePrice = 0;
    //Get a reference to the form id="cardform"
    var theForm = document.forms["cardform"];
    //Get a reference to the card the user Chooses name=selectedCard":
    var selectedCard = theForm.elements["selectedcard2"];
    //Here since there are 4 radio buttons selectedCard.length = 4
    //We loop through each radio buttons
    for (var i = 0; i < selectedCard.length; i++) {
      //if the radio button is checked
      if (selectedCard[i].checked) {

        cardSizePrice = card_prices[selectedCard[i].value];

        break;
      }
    }

    return cardSizePrice;
  }

  function getCardSizePrice4() {
    card_prices["Round21"] = 2;
    card_prices["Round22"] = 5;
    card_prices["Round23"] = 5;

    var cardSizePrice = 0;
    //Get a reference to the form id="cardform"
    var theForm = document.forms["cardform"];
    //Get a reference to the card the user Chooses name=selectedCard":
    var selectedCard = theForm.elements["selectedcard3"];
    //Here since there are 4 radio buttons selectedCard.length = 4
    //We loop through each radio buttons
    for (var i = 0; i < selectedCard.length; i++) {
      //if the radio button is checked
      if (selectedCard[i].checked) {

        cardSizePrice = card_prices[selectedCard[i].value];

        break;
      }
    }

    return cardSizePrice;
  }
  var divobj = document.getElementById('totalPrice');

  function calculateTotal() {
    //Here we get the total price by calling our function
    //Each function returns a number so by calling them we add the values they return together
    var cardPrice = getCardSizePrice2() + getCardSizePrice3() + getCardSizePrice4();
    //display the result

    divobj.style.display = 'block';
    divobj.innerHTML = "Total Price For the Card: &pound;" + " " + cardPrice;
    displaytotal(divobj);

  }

  function displaytotal() {


  }

  function hideTotal() {
    var divobj = document.getElementById('totalPrice');
    divobj.style.display = 'none';
  }

  function resetIt() {
    var divobj = document.getElementById('totalPrice');
    divobj.style.display = 'none';
  }
</script>

</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

我知道你发现了自己的问题(我认为这与您使用提交按钮设置代码的事实有关,并且一旦触发了页面加载事件,您就会计算总数,而不是点击总按钮)。

但是,除此之外,您可能仍然需要非常仔细地查看此答案,因为您的代码在许多方面都很糟糕:

<强> HTML

  • 您的HTML未正确使用。你没有使用<label><fieldset>元素。
  • 因为你真的只需要一个实际上没有的计算器 在任何地方提交数据,您都不应该有提交按钮。
  • 您使用的是内联HTML事件处理程序(onsubmitonclick, 等),不应该使用,因为:
    • 他们创造了难以阅读并导致的“意大利面条代码” 重复代码。
    • 它们会导致全局事件处理包装函数隐式 围绕您提供的属性值创建的 this对象的绑定无法按预期工作。
    • 他们不遵循 W3C Standards for Event Handling

<强> JavaScript的:

  • 您正在为要使用的HTML元素设置变量 在你的各种功能里面使用,这意味着每一次 函数运行后,它必须重新扫描文档再次查找 元素。
  • 当对象更合适时,您正在使用数组。
  • 你基本上写了3次相同的功能,而不仅仅是 拥有它并传递一个可以随你变化的论点 需要它。

这是一个清理版本,遵循最佳实践,语义并且不会重复。有关详细信息,请参阅内联注释。

window.addEventListener("DOMContentLoaded", function(){

  // Get references to DOM elements that we'll need access to just once. Don't set variables
  // up to store their values at first. Set the variable to the elmement. That way, you can
  // go back to the element as often as you need to in order to get any property value you
  // like, without having to re-scan the document for it all over again:
  var size1 = document.getElementById("width");
  var size2 = document.getElementById("height");
  var divObj = document.getElementById('totalPrice');
  var theForm = document.getElementById("cardform");
  var selectedCard1 = theForm.querySelectorAll("[name=selectedcard1]");
  var selectedCard2 = theForm.querySelectorAll("[name=selectedcard2]");
  var selectedCard3 = theForm.querySelectorAll("[name=selectedcard3]"); 
  var calc = document.querySelector("input[type=button]");
  var res = document.querySelector("input[type=reset]");
  
  // Set up event handlers for various DOM elements:
  calc.addEventListener("click", calculateTotal);
  res.addEventListener("click", reset);  
  
  // Create a storage mechanism that holds "keys" and associated "values"
  // Arrays can only do this with sequential numeric indexes. Objects, do it
  // with string property names.
  var card_prices = {};
  
  // No reason to have 3 functions that all do basically the same thing but only 
  // to different objects. Just have one function that accepts a reference to the
  // radiobuttons it needs to work with
  function getCardSizePrice(cards){  

    var cardSizePrice = 0;
    
    // Loop through each radio button in the passed in group
    for(var i = 0; i < cards.length; i++) {
        //if the radio button is checked
        if(cards[i].checked) {
            // Lookup the value of the selected radio button in our object and get the 
            // associate property value
            cardSizePrice = card_prices[cards[i].value];
            
            // No reason to continue if we get a match
            break;
        }
    }
    // We return the cardSizePrice
    return cardSizePrice;
  }     
  
  function calculateTotal() {
  
    // You didn't have the following code in this funciton, so it was running immediately
    // when the page loaded.
  
    // Remember, values that you take out of form elements are strings!
    // If you want to treat them as numbers, you should explicitly convert them
    // to numbers first:
    var s1 = parseFloat(size1.value);
    var s2 = parseFloat(size2.value);
  
    var total_size = (s1 * s2) / 10000;

    // Set all the property values
    card_prices["Round13"] = total_size * 67,
    card_prices["Round14"] = total_size * 87,
    card_prices["Round17"] = total_size * .05,
    card_prices["Round18"] = total_size * .65,
    card_prices["Round19"] = total_size * .85,
    card_prices["Round20"] = total_size * .95, 
    card_prices["Round21"] = 2;
    card_prices["Round22"] = 5;
    card_prices["Round23"] = 5;    
 
    // Here we get the total price by calling our function
    // Each function returns a number so by calling them we add the values they return together
    var cardPrice =  getCardSizePrice(selectedCard1) + 
                     getCardSizePrice(selectedCard2) + 
                     getCardSizePrice(selectedCard3);
   
    displayTotal(cardPrice);
  }
  
  function displayTotal(price) {
    // display the result
    divObj.classList.remove("hidden");
    divObj.innerHTML = "Total Price For the Card: &pound;"  + " " +  price.toFixed(2);
  }
  
  function reset(){
    divObj.innerHTML = "";
  }

});
#totalPrice { background-color:#ff0; } // Default style for element
#panel { margin-top: 1em;}
fieldset { margin-bottom:1em; }
<body>
  <div id="wrap">
    <form action="#" id="cardform">
      <div class="cont_order">
         <h1>Check Quotes</h1>
         
         <!-- Fieldsets are for logical grouping of form elements. While they do have a 
              visual component to them, they are primarially for accessibility for
              visually impaired. -->
         <fieldset>
            <legend>Size Of the Card</legend>
            <!-- Labels associate with form elements via the "for" attribute and the target
                 element's "id" attribute. They aren't just for displaying random text.
                 They are a key aspect of designing for accessibility. You can click/touch the 
                 label and activate the associated form element. -->
            <label for="width">Width in cm:</label> <input type="text" id="width">
            <label for="height">Height in cm:</label> <input type="text" id="height">
            <br><br>
            <input type="radio" name="selectedcard1" id="selectedcard1a" value="Round13">
            <label for="selectedcard1a" class='radiolabel'>Standard</label>
            <input type="radio" name="selectedcard1" id="selectedcard1b" value="Round14">
            <label for="selectedcard1b" class='radiolabel'>Toughened</label><br>
          </fieldset>
         <fieldset>
            <legend>Card</legend>          
            <input type="radio" name="selectedcard2" id="selectedcard2a" value="Round17">
            <label for="selectedcard2a" class='radiolabel'>Clear</label>
            <input type="radio" name="selectedcard2" id="selectedcard2b" value="Round18">
            <label for="selectedcard2b" class='radiolabel'>Frosted</label>
            <input type="radio"  name="selectedcard2" id="selectedcard2c" value="Round19">
            <label for="selectedcard2c" class='radiolabel'>Leaded</label>
            <input type="radio"  name="selectedcard2" id="selectedcard2d" value="Round20">
            <label for="selectedcard2d" class='radiolabel'>White Bar</label>
          </fieldset>
         <fieldset>
            <legend>Frame</legend>          
            <input type="radio"  name="selectedcard3" id="selectedcard3a" value="Round21">
            <label for="selectedcard3a" class='radiolabel'>uPVC</label>
            <input type="radio"  name="selectedcard3" id="selectedcard3b" value="Round22">
            <label for="selectedcard3b" class='radiolabel'>Metal</label>
            <input type="radio"  name="selectedcard3" id="selectedcard3c" value="Round23">
            <label for="selectedcard3c" class='radiolabel'>Wood</label>
          </fieldset>
          <div id="panel">
            <input type="button" value="Calculate">
            <input type="reset" value="Reset">
            <div id="totalPrice"></div>
          </div>
        </div>  
       </form>
    </div>