javascript - 为什么乘法仅在刷新后发生?

标签 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>

最佳答案

我知道您已经发现了问题(我相信这与您使用提交按钮设置代码并且在页面加载事件触发后立即计算总数有关,而不是在单击总计按钮)。

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

HTML:

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

关于javascript - 为什么乘法仅在刷新后发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42472227/

相关文章:

javascript - 通过代码检查我的单选按钮并触发更改事件

javascript - 表单 php、html、js

javascript - 转换为 Typescript 后出现 "this"错误

javascript - Vue.js - 无法将日期/时间选择器添加到 vue.js 渲染的 html 元素中

html - 如何将 SVG 中的链接编写为 URL 相对而不是 web 服务器根(文件系统)相对?

javascript - Bootstrap Jquery <li> 点击添加图标到列表

html - 如何在 Twitter Bootstrap 中扩展容器的宽度

javascript - 日语字符的字符串比较

javascript - 动态添加的单选按钮在 IE6、IE7 中点击时不更新

javascript - 限制Node js中的Q promise 并发