- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
大家,我使用 jQuery 制作了这个产品计算器,虽然它可以工作,但第二个选择让我很头痛,因为当你单击一个选项时我无法让它保持选中状态,即使它做了它应该做的事情。我知道发生这种情况的原因,但我找不到解决方案。我尝试使用计算器事件 block 中的注释代码手动设置该选项,但这只会卡住第二个选择,而且这种方式对我来说并不起作用。我评论了所有看起来重要的内容,以便更容易阅读。我认为我的主要问题出在 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>
最佳答案
您可以通过分离事件处理程序来解决这个问题,这样您就不会在使用第一个选择时不断更新权重。
我将
一种方法是使用 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>
关于javascript - jQuery 计算器第二个选择一直在重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41755499/
我正在尝试使用谷歌浏览器的 Trace Event Profiling Tool分析我正在运行的 Node.js 应用程序。选择点样本后,我可以在三种 View 之间进行选择: 自上而下(树) 自上而
对于一个可能是菜鸟的问题,我们深表歉意,但尽管在 SO 上研究了大量教程和其他问题,但仍找不到答案。 我想做的很简单:显示一个包含大量数据库存储字符串的 Android ListView。我所说的“很
我已经开始了一个新元素的工作,并决定给 Foundation 5 一个 bash,看看它是什么样的。在创建带有水平字段的表单时,我在文档中注意到的第一件事是它们使用大量 div 来设置样式。所以我在下
我有一个 Windows 窗体用户控件,其中包含一个使用 BeginInvoke 委托(delegate)调用从单独线程更新的第 3 方图像显示控件。 在繁重的 CPU 负载下,UI 会锁定。当我附加
我有一堆严重依赖dom元素的JS代码。我目前使用的测试解决方案依赖于 Selenium ,但 AFAIK 无法正确评估 js 错误(addScript 错误不会导致您的测试失败,而 getEval 会
我正在制作一款基于滚动 2D map /图 block 的游戏。每个图 block (存储为图 block [21][11] - 每个 map 总共 231 个图 block )最多可以包含 21 个
考虑到以下情况,我是前端初学者: 某个 HTML 页面应该包含一个沉重的图像(例如 - 动画 gif),但我不想强制客户缓慢地等待它完全下载才能享受一个漂亮的页面,而是我更愿意给他看一个轻量级图像(例
我正在设计一个小软件,其中包括: 在互联网上获取资源, 一些用户交互(资源的快速编辑), 一些处理。 我想使用许多资源(它们都列在列表中)来这样做。每个都独立于其他。由于编辑部分很累,我想让用户(可能
我想比较两个理论场景。为了问题的目的,我简化了案例。但基本上它是您典型的生产者消费者场景。 (我关注的是消费者)。 我有一个很大的Queue dataQueue我必须将其传输给多个客户端。 那么让我们
我有一个二元分类问题,标签 0 和 1(少数)存在巨大不平衡。由于测试集带有标签 1 的行太少,因此我将训练测试设置为至少 70-30 或 60-40,因此仍然有重要的观察结果。由于我没有过多地衡量准
我是一名优秀的程序员,十分优秀!