我需要一些幫助,因為我對JavaScript相當陌生,
。我希望創建一個計算會員費的函式
。我試著在JavaScript中制作一個函式,檢查是否只選擇了一個選項,但我不知道如何使它在用戶有資格享受一個以上或所有折扣的情況下計算出費用。目前還沒有關于年齡條件(60至80歲之間)的JS,因為我不確定如何做到這一點。
。function feeCalc() {
var ans = document.getElementById("answer") 。
if (document.getElementById('medicalCond-yes').checked) {
ans.value = calculate('medicalCond-yes') 。
}
if (document.getElementById('empstatus-yes').checked) {
ans.value = calculate('empstatus-yes') 。
}
if (document.getElementById('empstatus-no').checked) {
ans.value = calculate('empstatus-no') 。
}
if (document.getElementById('medicalCond-no').checked) {
ans.value = calculate('medicalCond-no') 。
}
}
function calculate(action) {
var standardRate = 10;
var ageRate = 0.1;
var medicalRate = 0.4;
var unemployedRate = 0.3;
var result;
switch (action) {
case 'medicalcond-yes'/span>:
discount = (standardRate * studentRate);
結果 = standardRate - discount;
break;
case 'empstatus-yes'/span>:
discount = (standardRate * unemployedRate);
結果 = standardRate - discount;
break;
case 'empstatus-no'/span>:
result = standardRate;
break;
case 'medicalcond-no':
result = standardRate;
break;
}
return result。
}
<div class="form"> /span>
<label>
年齡
</label>年齡
< input type="range" value="50" min="1"/span> max="100"/span> class="slider"/span> id="age"/span>/>
</div>
<div class="form">
<label>
你是否有任何長期的醫療狀況
會影響日常生活
</label>
<br/>/span>
< input type="radio" name="status" value="yes" id="medicalCond-yes"/> 是的
< string">"status" value="no" id="medicalCond-no"/> 沒有
</div>
<div class="form"/span>>
<label>
你目前是否有作業?
</label>您目前是否有作業?
<br/>/span>
< input type="radio" name="empstatus" value="yes" id="empstatus-yes"/> 是的
< input type="radio" name="empstatus" value="no" id="empstatus-no"/> 沒有
</div>
<div class="form"/span>>
<label>
會員費
</label>
<br/>/span>
總費用。
< input type="text" id="answer" readonly/>
< input type="button" value="計算" onclick="feeCalc()"/>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
uj5u.com熱心網友回復:
盡管對于OP的問題來說,它看起來像是過度工程,但OP提供的代碼足夠小,以證明(更多的)通用方法的優勢,這是......
- 在非常具體的DOM-元素查詢上,
- 依靠"baked in"資料,例如,驗證和邊緣案例處理。
尤其是實作通用方法/行為的原因的JavaScript代碼從一開始就比其非常明確地撰寫的競爭者大。但是,前者并沒有增長的趨勢,甚至不需要為新的折扣選項或改變的折扣值而被觸及。這一部分將由同樣是通用的計算器上層結構中更清潔的通用(因此可重用)子結構所覆寫。
此外,這種基于通用組件的方法可自動實作在同一個檔案中使用多個組件。
。function parseJson(str) {
let result;
try {
result = JSON.parse(str)。
} catch (ex) {
result = null;
}
return 結果。
}
function getDevaluationFactorFromRange(formControl, range) {
let factor = 0;
range = parseJson(range)。
if (range !== null) {
const controlValue = parseFloat(formControl.value)。
物件。
.entries(range)
.some(([devaluationKey, { min, max }]/span>) => {
let isStopIteration = false;
if (
(controlValue >= parseFloat(min)) &&
(controlValue <= parseFloat(max))
) {
factor = parseFloat(devaluationKey)。
isStopIteration = true;
}
return isStopIteration
});
}
return Number.isFinite( factor) ? factor : 0。
}
function getDevaluationFactor(formControl) {
const { dataset } = formControl;
let rawRange = dataset.devaluationRange ? null。
let rawFactor = dataset.devaluationFactor ? null。
let factor = (rawRange !== null)
? getDevaluationFactorFromRange(formControl, rawRange)
: 0;
因素 = (
(factor === 0) && (rawFactor !== null) && parseFloat(rawFactor)
) ||因子。
factor = Number.isFinite( factor) ? factor : 0;
if ( factor !== 0) {
const { type } = formControl;
if ((type === 'radio') || (type== 'checkbox')) {
factor = formControl.checked ? factor : 0;
}
}
return factor。
}
function computeCurrentFee(rootNode, elmFee, baseFee) {
return Array
//陣列來自`HTMLFormControlsCollection`。
.from(rootNode.elements)
//從每個表單元素的資料中計算出當前費用。
.reduce((currentFee, formControl) => {
return currentFee - (baseFee * getDevaluationFactor(formControl))。
}, baseFee)。
}
function updateCurrentValueAtBoundFeeContext(/*evt*/) {
const { rootNode, elmFee, baseFee } = this;
elmFee.value = computeCurrentFee(rootNode, elmFee, baseFee)。
}
function displayCurrentValueAtBoundAgeContext(/*evt*/) {
const { elmRange, elmOutput } = this;
elmOutput.value = elmRange.value。
}
function initializeCurrentAgeDisplay(rootNode) {
const ageNode = rootNode.querySelector('[data-age-range]') 。
if (ageNode) {
const elmRange = ageNode.querySelector('input[type="range"] ')。
const elmOutput = ageNode.querySelector('output')。
if (elmRange & & elmOutput) {
const target = { elmRange, elmOutput };
const boundContextHandler =
displayCurrentValueAtBoundAgeContext.bind(目標)。
elmRange.addEventListener('input', boundContextHandler)。
rootNode.addEventListener('reset', () =>
//解耦自定義dom重繪 和系統的重繪 。
setTimeout(boundContextHandler, 0)
);
//顯示初始年齡值。
// displayCurrentValueAtBoundAgeContext.call(target);
boundContextHandler()。
}
}
}
function initializeMembershipFeeCalculator(rootNode){
const DEFAULT_BASE_FEE = 10;
initializeCurrentAgeDisplay(rootNode)。
const elmFeeValue = rootNode.querySelector('[data-fee-value]') 。
if (elmFeeValue) {
const baseFee = parseFloat(rootNode.dataset.baseFee) 。
const target = {
rootNode,
elmFee: elmFeeValue,
baseFee: Number.isFinite(baseFee) ? baseFee : DEFAULT_BASE_FEE。
};
const boundContextHandler =
updateCurrentValueAtBoundFeeContext.bind(目標)。
rootNode.addEventListener('input', boundContextHandler)。
rootNode.addEventListener('reset', () =>
//從系統的重繪 中解耦自定義dom。
setTimeout(boundContextHandler, 0)
);
//計算初始費用值。
// updateCurrentValueAtBoundFeeContext.call(target);
boundContextHandler()。
rootNode.addEventListener('submit', evt =>; {
evt.preventDefault()。
return false。
});
}
}
function main() {
document()
.querySelectorAll('form[data-membership-fee-calculator] ')
.forEach(initializeMembershipFeeCalculator)。
}
main();
body, form {
margin: 0;
padding: 0;
}
form {
float: left;
width: 50%;
margin-top: -2px。
}
fieldset {
position: relative;
margin: 0 0 2px 0;
padding: 0 10px 2px 10px。
}
fieldset p {
margin: 1px 0 2px 0;
}
fieldset output {
color: #333;
font-weight: bolder;
}
label {
display: inline-block;
}
input[type="range"] {
width: 70%;
}
[data-age-range] output {
display: inline-block;
overflow: hidden;
max-width: 25%;
max-height: 1.2em;
position: relative;
top: 1px;
}
[type="reset"] {
position: absolute;
right: 4px;
top: -4px;
}
< form data-membership-fee-calculator data-base-fee="10"/span>>
<fieldset data-age-range>/span>
<legend>/span>
年齡
</legend>/span>年齡
<input
type="range"/span>
name="age" id="age"value="50" min="1" max="100"data-devaluation-range='{"0.1":{"min":60, "max":80}}'
/>
<output for="age"/span>> ###尚未計算 ###</output>>
</fieldset>/span>
<fieldset>/span>
<p>/span>
你是否有任何長期的醫療狀況
會影響到日常生活?
</p>
<label>/span>
<input
type="radio"
name="state"
value="yes"/span>
data-devaluation-factor="0.4"。
/>
<span class="標簽-拷貝">
有
</span> Yes
</label>/span>
<label>/span>
< input type="radio" name="status" value="no" />
<span class="label-copy">
沒有
</span> 否
</label>/span>
</fieldset>/span>
<fieldset>/span>
<p>
你目前是否有作業?
</p>您目前是否有作業?
<label>/span>
<input
type="radio"
name="empstatus"
value="yes"
data-devaluation-factor="0.3"。
/>
<span class="標簽-拷貝">
有
</span> Yes
</label>/span>
<label>/span>
< input type="radio" name="empstatus" value="no" />
<span class="label-copy">
沒有
</span> 否
</label>/span>
</fieldset>/span>
<fieldset>/span>
<legend>
會員費
</legend>會員費
<label>/span>
<span class="標簽-拷貝">
總費用。
</span>
<output data-fee-value>### not yet computed ###</output>/span>
</label>/span>
<button type="reset"> 恢復基本費用</按鈕>
</fieldset>/span>
</form>
<form data-membership-fee-calculator data-base-fee="20"/span>>
<fieldset data-age-range>/span>
<legend>/span>
年齡
</legend>/span>年齡
<input
type="range"/span>
name="age" id="age"value="21" min="1" max="100"
data-devaluation-range=
'{"0.05":{"min":60,"max":69},"0.1":{"min":70,"max":79},"0.2":{"min":80,"max":120}}'
/>
<output for="age"/span>> ###尚未計算 ###</output>>
</fieldset>/span>
<fieldset>/span>
<p>/span>
你是否有任何長期的醫療狀況
會影響到日常生活?
</p>
<label>/span>
<input
type="radio"
name="state"
value="yes"/span>
data-devaluation-factor="0.3"。
/>
<span class="標簽-拷貝">
有
</span> Yes
</label>/span>
<label>/span>
< input type="radio" name="status" value="no" />
<span class="label-copy">
沒有
</span> 否
</label>/span>
</fieldset>/span>
<fieldset>/span>
<p>
你目前是否有作業?
</p>您目前是否有作業?
<label>/span>
<input
type="radio"
name="empstatus"
value="yes"
data-devaluation-factor="0.3"。
/>
<span class="標簽-拷貝">
有
</span> Yes
</label>/span>
<label>/span>
< input type="radio" name="empstatus" value="no" />
<span class="label-copy">
沒有
</span> 否
</label>/span>
</fieldset>/span>
<fieldset>/span>
<legend>
會員費
</legend>會員費
<label>/span>
<span class="標簽-拷貝">
總費用。
</span>
<output data-fee-value>### not yet computed ###</output>/span>
</label>/span>
<button type="reset"> 恢復基本費用</按鈕>
</fieldset>/span>
</form>/span>
<iframe name="sif2" sandbox="allow-form allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
uj5u.com熱心網友回復:
你可能想一次性檢查完所有的情況,而不是將切換案例路由到一個分支。
。function feeCalc() {
var ans = document.getElementById("answer") 。
ans.value = calculateRate()。
}
function calculateRate() {
let discount = 0;
const age = Number(document. getElementById('age').value)。)
if (age >= 60 & & age <= 80) {
discount = 0.1;
}
if (document.getElementById('medicalCond-yes'/span>).checked) {
discount = 0.4;
}
if (document.getElementById('empstatus-no').checked) {
discount = 0.3;
}
return 1 - discount。
}
<div class="form"> /span>
<label>
年齡
</label>年齡
< input type="range" value="50" min="1"/span> max="100"/span> class="slider"/span> id="age"/span>/>
</div>
<div class="form">
<label>
你是否有任何長期的醫療狀況
會影響日常生活
</label>
<br/>/span>
< input type="radio" name="status" value="yes" id="medicalCond-yes"/> 是的
< string">"status" value="no" id="medicalCond-no"/> 沒有
</div>
<div class="form"/span>>
<label>
你目前是否有作業?
</label>您目前是否有作業?
<br/>/span>
< input type="radio" name="empstatus" value="yes" id="empstatus-yes"/> 是的
< input type="radio" name="empstatus" value="no" id="empstatus-no"/> 沒有
</div>
<div class="form"/span>>
<label>
會員費
</label>
<br/>/span>
總費用。
< input type="text" id="answer" readonly/>
< input type="button" value="計算" onclick="feeCalc()"/>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/320460.html
標籤:
