每个人,我使用jQuery制作了这个产品计算器,虽然它有效,但第二个选择让我头疼,因为当你点击一个选项时我无法让它保持选择,即使它做了它应该做的事情。我知道这种情况发生的原因,但解决方案让我不知所措。我尝试使用计算器事件块中的注释代码手动设置选项,但这只是冻结了第二个选择,它对我来说并不是真的有用。 我评论了所有重要的内容,因此更容易阅读。我的主要问题是我认为的javascript的第一部分。
$(document).ready(function() {
// Set initial weights for first row
var typeVal = $('#calcT1').val();
var weights = weightOptions[typeVal];
setWeights(weights, '#calcW1');
// Letter Type change event
$('.letterType').on('change', function () {
var typeId = '#' + $(this).attr('id');
var typeVal = $(typeId).val();
var weightId = '#' + $(this).parents('.calculator-row').find('.letterWeight').attr('id');
//console.log (weight);
var weights = weightOptions[typeVal];
setWeights(weights, weightId);
});
// Basically the calculator events
$('.calculator-row').on('change keyup', function() {
//var rowId = '#' + $(this).attr('id');
// var typeId = '#' + $(this).find('.letterType').attr('id');
//var typeVal = $(typeId).val();
var weightId = '#' + $(this).find('.letterWeight').attr('id');
var weightPrice = $(weightId + ' option:selected').attr('data-price');
var weightValue = $(weightId).val();
var inputId = '#' + $(this).find('.letterNumber').attr('id');
var inputVal = $(inputId).val();
var resultId = '#' + $(this).find('.letterSubtotal').attr('id');
/* $(weightId).val(weightValue);
$(typeId).change(function () {
});*/
calculateRow(weightPrice, inputVal, resultId);
calculateAll('.letterSubtotal', '#calcTotal');
});
// Set weight for target row using JSON Array
function setWeights(json ,target) {
$(target).empty();
// Loop through the JSON object where i = index, and set data- attributes to <option> tags
for (var i in json) {
$(target).append($('<option>', {
value: json[i]['wid'],
text: json[i]['name'],
'data-wmin': json[i]['wmin'],
'data-wmax': json[i]['wmax'],
'data-price': json[i]['price']
}));
}
}
/*
// Set weights for the initial row
/!* setWeights(optionId, weightOptions);*!/
// Set weights for sequential rows
/!* typeSelect.change(function () {
optionId = $(this).val();
setWeights(optionId, weightOptions);
});*!/
*/
// Add a new row
var regex = /^(.+?)(\d+)$/i;
var cloneIndex = $(".calculator-row").length;
function addRow() {
cloneIndex++;
$(this).parents(".calculator-row").clone(true)
.appendTo("#calculator")
.attr("id", "calcRow" + cloneIndex)
.find("*")
.each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
}
if ($(this).hasClass('calcDelRow')) {
$(this).removeClass('hidden');
}
if ($(this).hasClass('letterNumber')) {
$(this).val('');
}
if ($(this).hasClass('letterSubtotal')) {
$(this).text('0.00');
}
/*if ($(this).hasClass('calcAddRow')) {
$(this).addClass('hidden');
}*/
});
calculateAll('.letterSubtotal', '#calcTotal');
}
// Remove row
function removeRow(){
$(this).parents(".calculator-row").remove();
calculateAll('.letterSubtotal', '#calcTotal');
}
$("button").blur();
$("button.calcAddRow").on("click", addRow);
// Add remove event to button
$("button.calcDelRow").on("click", removeRow);
// Calculate a single row
function calculateRow(a, b, target) {
var x;
x = parseFloat(a) * parseFloat(b);
x = x.toFixed(2);
if (!isNaN(x)) {
$(target).text(x);
} else {
$(target).text('0.00');
}
}
// Calculate total rows
function calculateAll(rows, target) {
var result = 0;
$(rows).each(function () {
if(!isNaN($(this).text())) {
result += parseFloat($(this).text());
} else {
result = 0;
}
});
$(target).text(result.toFixed(2));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div id="calculator">
<div class="calculator-row" id="calcRow1">
<div class="col-md-4">
<div class="form-group">
<select id="calcT1" class="form-control letterType">
<option value="1">Ordinaria piccolo</option>
<option value="2">Ordinaria medio</option>
<option value="3">Ordinaria extra</option>
<option value="4">Raccomandata con avviso di ricevimento piccolo</option>
<option value="5">Raccomandata con avviso di ricevimento medio</option>
<option value="6">Raccomandata con avviso di ricevimento extra</option>
<option value="7">Raccomandata semplice</option>
<option value="8">Raccomandata con avviso di ricevimento</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<select id="calcW1" class="form-control letterWeight"></select>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<input type="number" id="calcNum1" class="form-control letterNumber" placeholder="No." min="0" max="999">
</div>
</div>
<div class="col-md-2">
<h4><span>€
</span><span id="calcSubtotal1" class="letterSubtotal">0.00</span></h4>
</div>
<div class="col-md-2 center">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default calcAddRow">Add
</button>
<button type="button" class="btn btn-default calcDelRow hidden">Remove
</button>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-9">
<h3><span>Totale: €
</span><span id="calcTotal">0.00</span></h3>
</div>
</div>
</div>
<script>
//Hardcoded Json
var weightOptions = {
"1": {
"1": {
"price": "0.95",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.55",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
}
},
"2": {
"1": {
"price": "2.55",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.55",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "2.85",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "3.50",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "4.35",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "5.40",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "5.95",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
},
"3": {
"1": {
"price": "2.55",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.85",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "3.50",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "4.35",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "5.95",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "5.95",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "6.50",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
},
"4": {
"1": {
"price": "0.95",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.55",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
}
},
"5": {
"1": {
"price": "2.55",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.55",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "2.85",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "3.50",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "4.35",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "5.40",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "5.95",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
},
"6": {
"1": {
"price": "2.55",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "2.85",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "3.50",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "4.35",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "5.95",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "5.95",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "6.50",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
},
"7": {
"1": {
"price": "4.50",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "5.80",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "6.20",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "6.70",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "7.50",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "9.20",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "12.30",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
},
"8": {
"1": {
"price": "5.45",
"wmin": "0",
"wmax": "20",
"name": "fino a 20 g"
},
"2": {
"price": "6.75",
"wmin": "21",
"wmax": "50",
"name": "Oltre 20 g e fino a 50 g "
},
"3": {
"price": "7.15",
"wmin": "51",
"wmax": "100",
"name": "Oltre 50 g e fino a 100 g"
},
"4": {
"price": "7.65",
"wmin": "101",
"wmax": "250",
"name": "Oltre 100 g e fino a 250 g"
},
"5": {
"price": "8.45",
"wmin": "251",
"wmax": "350",
"name": "Oltre 250 g e fino a 350 g"
},
"6": {
"price": "10.15",
"wmin": "351",
"wmax": "1000",
"name": "Oltre 350 g e fino a 1000 g"
},
"7": {
"price": "13.25",
"wmin": "1001",
"wmax": "2000",
"name": "Oltre 1000 g e fino a 2000 g"
}
}
}
;
//console.log(weightOptions);
</script>
答案 0 :(得分:1)
您可以通过分离事件处理程序来解决它,以便在使用第一个选择时不会继续更新权重。 我将一种方法是使用HTML5模板并为其分配唯一ID父元素。然后,使用find查询子项并相应地更新它们。$('.calculator-row')
选择器更改为$('.letterType, .letterNumber')
,以避免在更改第二个选择后重新填充权重。
function UpdateTotal() {
var total = 0;
$('.letterNumber').each(function() {
total += parseInt($(this).val(), 10);
});
$('#calcTotal').text(total);
}
function AddCalcRow() {
var row = 'calc_row_' + $('.calculator-row').length;
var rowId = '#' + row;
var template = document.getElementById('template');
template.content.querySelector('.calculator-row').id = row;
var clone = document.importNode(template.content, true);
document.getElementById('calculator').appendChild(clone);
// Find and bind elements specific to the current row.
$(rowId).find('.letterType').on('change', function(e) {
// Update weight elements here.
$(rowId).find('.letterWeight').append($('<option>' + Math.random() + '</option>'));
});
$(rowId).find('.letterNumber').on('input', function(e) {
// Update subtotal.
$(rowId).find('.letterSubtotal').text(e.target.value);
UpdateTotal();
});
}
document.getElementById('add').addEventListener('click', AddCalcRow);
AddCalcRow();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<template id="template">
<div class="calculator-row">
<div class="col-md-4">
<div class="form-group">
<select class="form-control letterType">
<option value="1">Ordinaria piccolo</option>
<option value="2">Ordinaria medio</option>
<option value="3">Ordinaria extra</option>
<option value="4">Raccomandata con avviso di ricevimento piccolo</option>
<option value="5">Raccomandata con avviso di ricevimento medio</option>
<option value="6">Raccomandata con avviso di ricevimento extra</option>
<option value="7">Raccomandata semplice</option>
<option value="8">Raccomandata con avviso di ricevimento</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<select class="form-control letterWeight"></select>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<input type="number" class="form-control letterNumber" placeholder="No." min="0" max="999">
</div>
</div>
<div class="col-md-2">
<h4><span>€
</span><span class="letterSubtotal">0.00</span></h4>
</div>
</div>
</template>
<div class="container">
<div class="row">
<div id="calculator">
</div>
</div>
<div class="row">
<div class="col-md-2 center">
<div class="btn-group" role="group">
<button type="button" id="add" class="btn btn-default calcAddRow">Add
</button>
<button type="button" class="btn btn-default calcDelRow hidden">Remove
</button>
</div>
</div>
<div class="col-md-3 col-md-offset-9">
<h3><span>Totale: €
</span><span id="calcTotal">0.00</span></h3>
</div>
</div>
</div>