目標是人們應該在輸入欄位中輸入一個值,而 JavaScript 應該乘以一個固定值。
代碼應該對每一行執行此操作,并且無需重繪 即可自動執行此操作。
JavaScript 適用于第一行,但如果我添加回圈(前 3 行代碼),則它不再起作用。
表看起來像這樣
<table class="u-table-entity" id="table_geb?ck">
<script src="calculation.js"></script>
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody >
<tr style="height: 55px;">
<b>
<td ><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td ></td>
<td ><b>Einzelpreis</b></td>
<td ><b>Menge</b></td>
<td ><b>Gesamtpreis</b></td>
</b>
</tr>
<tr style="height: 55px;">
<td >Kornspitz</td>
<td ></td>
<td >
<p value="1.39" id="basePrice">1,39 €</p>
</td>
<td >
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td >
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
<tr style="height: 55px;">
<td >Row 2</td>
<td ></td>
<td >
<p value="5.39" id="basePrice">5,39 €</p>
</td>
<td >
<form id="Menge">
<input type="number" min="0" id="quantity" value="0" step="1.0">
</form>
</td>
<td >
<form id="sum">
<p><output id="field_sum" for="quantity">0</output> €</p>
</form>
</td>
</tr>
</tbody>
</table>
以及我迄今為止創建的 JavaScript 代碼
var table = document.getElementById("table_geb?ck");
for (var i = 0, row; row = table.rows[i]; i ) {
let row = table.rows[i]
(function () {
const basePrice = document.getElementsByClassName("basePrice");
const quantityInput = document.getElementsByClassName("quantity");
const resOutput = document.getElementsByClassName("field_sum");
quantityInput.addEventListener("change", function () {
let currentQuantity = parseFloat(quantityInput.value);
let currentBasePrice = parseFloat(basePrice.getAttribute("value"));
resOutput.textContent = currentQuantity * currentBasePrice;
});
}());
}
編輯
這也幫助了我
使用 JavaScript 通過在表中迭代來計算總價
uj5u.com熱心網友回復:
除了標記清理/清理任務之外,還可以實作一種微組件方法。
一個可行的解決方案也與(解耦)某個 DOM 層次結構無關,它可以基于自定義資料屬性并dataset與系結處理程式資料一起訪問......
function jsonParse(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
function initializeUpdateTotalValue(componentRoot) {
const source = componentRoot
.querySelector('[data-base-value]');
const target = componentRoot
.querySelector('[data-total-value]');
const baseValue = sanitizeFloatValue(source.dataset.baseValue) || 0;
const config = jsonParse(componentRoot.dataset.updateTotalValue) ?? {};
const toFixed = sanitizeFloatValue(config.toFixed);
const context = { source, target, baseValue, toFixed };
source
.addEventListener('input',
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
function main() {
document
.querySelectorAll('[data-update-total-value]')
.forEach(initializeUpdateTotalValue);
}
main();
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<form name="product-orders">
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Kornspitz"
id="quantity-Kornspitz"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Kornspitz" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 2}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="0" step="1"
name="quantity-Row_2"
id="quantity-Row_2"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_2" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value>
<td class="u-table-cell">float number calculation</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="1.39">1,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="5" step="1"
name="quantity-Row_3"
id="quantity-Row_3"
data-base-value="1.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_3" data-total-value>0</output>
€
</p>
</td>
</tr>
<tr style="height: 55px;" data-update-total-value='{"toFixed": 4}'>
<td class="u-table-cell"><code>toFixed</code> set to 4</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p value="5.39">5,39 €</p>
</td>
<td class="u-table-cell">
<input type="number"
min="0" value="3" step="1"
name="quantity-Row_4"
id="quantity-Row_4"
data-base-value="5.39"
/>
</td>
<td class="u-table-cell">
<p>
<output for="quantity-Row_4" data-total-value>0</output>
€
</p>
</td>
</tr>
</tbody>
</table>
</form>
編輯
“非常感謝您分享這個,但我不知道如何使用它 – Setzi138”
好吧,那我試試吧……
首先,OP 需要撰寫有效的標記,因此任何元素的id屬性永遠不會有重復的值。
Secondly, this task should be solved as generic as possible. One e.g. should not implement any code which is tightly coupled to both a specific DOM hierarchy (or markup) or a too specific task like calculating a total price.
Thus one has to find a solution which easily adapts to other environments with equal tasks like here which actually is ... "Updating and displaying a total value calculated from a base value and a currently changed multiplier whenever this multiplier value changes".
The above carefully worded requirement gives the direction or even points to a solution's corner stones.
A main initialization task firstly needs to identify each structure before it can be initialized.
A viable approach is to utilize custom data-* attributes instead of class (coupled to layout and styling) and id (too specific, disqualifies for generic solutions) attributes. In addition one can provide any string based data to a custom attribute which can be accessed via an HTMLElement's dataset property.
Even though the approach claims to be as markup agnostic as can be, there is one precondition to it. The structure of such a "micro component" needs to have a root element and two other elements which both need to be nested under/within the component root. One element is the trigger or source of the quantity changes and the other serves as target for the updated total value.
Utilizing [data-*] attributes also has no disadvantage with accessing such elements within the DOM since a solutions makes use of modern element queries via <element >.querySelector and <element >.querySelectorAll.
The only things left now are a proper naming and the implementation itself.
...
to be continued
...
With more iterations over the first shown approach one finally could provide a module based implementation of a highly generic, customizable and self-initializing component which due to the customization ability also runs in DOM environments where one is not allowed of changing the markup on a large scale ...
// utility functions
function parseJSON(value) {
let result = null;
try {
result = JSON.parse(value);
} catch(exception) {}
return result;
}
function sanitizeFloatValue(value) {
value = parseFloat(value);
return Number.isFinite(value) ? value : null;
}
function getCustomKeyFromAttributeSelector(selector) {
return (/\[\s*data-(?<customKey>[^\s\]] )(?:\s|\])/)
.exec(selector)
?.groups
?.customKey;
}
function getDatasetKeyFromCustomAttributeSelector(selector) {
return getCustomKeyFromAttributeSelector(selector)
?.toLowerCase()
?.replace((/-(\p{Ll})/gu), (match, char) => char.toUpperCase());
}
// component specific module based code
const updateTotalValueModule = (function () {
const DEFAULT_CONFIG = {
calculation: {
baseValue: 0,
toFixed: 2,
},
selectors: {
source: '[data-base-value]',
target: '[data-total-value]',
},
eventType: 'input',
}
const DEFAULT_SELCTOR_COMPONENT = '[data-update-total-value]';
function updateTotalValueFromBoundContextData(/* evt */) {
const { source, target, baseValue, toFixed } = this;
const totalValue = baseValue * (sanitizeFloatValue(source.value) || 0);
target.value = (typeof toFixed === 'number')
? totalValue.toFixed(toFixed)
: totalValue;
}
let currentConfigKey;
function initializeUpdateTotalValue(componentRoot) {
const { // config values.
selectors = DEFAULT_CONFIG.selectors,
eventType = DEFAULT_CONFIG.eventType,
calculation = DEFAULT_CONFIG.calculation
} = (parseJSON(
componentRoot.dataset[currentConfigKey]
) ?? DEFAULT_CONFIG);
const source = componentRoot.querySelector(
selectors.source || DEFAULT_CONFIG.selectors.source
);
const target = source && componentRoot.querySelector(
selectors.target || DEFAULT_CONFIG.selectors.target
);
if (source && target) {
const baseValue = (
calculation.baseValue ||
sanitizeFloatValue(source.dataset[
getDatasetKeyFromCustomAttributeSelector(
selectors.source || DEFAULT_CONFIG.selectors.source
)
]) || 0
);
const toFixed = sanitizeFloatValue(
calculation.toFixed || DEFAULT_CONFIG.calculation.toFixed
);
const context = { source, target, baseValue, toFixed };
source.addEventListener(
eventType,
updateTotalValueFromBoundContextData.bind(context)
);
// initial update call
updateTotalValueFromBoundContextData.call(context);
}
}
function initialize(customAttributeSelector) {
const selector = (typeof customAttributeSelector === 'string')
&& customAttributeSelector
|| DEFAULT_SELCTOR_COMPONENT;
currentConfigKey = getDatasetKeyFromCustomAttributeSelector(selector);
document
.querySelectorAll(selector)
.forEach(initializeUpdateTotalValue);
}
// (module) export(s)
return {
initialize
};
}());
// running the component ...
// ... does target any default-config conform component.
updateTotalValueModule.initialize();
// ... does target any custom specific component.
updateTotalValueModule.initialize('[data-auto-total-price]');
body { zoom: .8; }
tr, td { margin: 0!important; padding: 0!important; height: unset!important; }
<!-- <script src="calculation.js"></script> //-->
<table class="u-table-entity" id="table_geb?ck">
<colgroup>
<col width="20%">
<col width="2.1%">
<col width="22%">
<col width="21.7%">
<col width="34.2%">
</colgroup>
<tbody class="u-table-alt-grey-5 u-table-body">
<tr style="height: 55px;">
<td class="u-table-cell u-table-cell-1"><b>Produkt</b><span style="font-weight: 700;"></span>
</td>
<td class="u-table-cell"></td>
<td class="u-table-cell u-table-cell-3"><b>Einzelpreis</b></td>
<td class="u-table-cell u-table-cell-4"><b>Menge</b></td>
<td class="u-table-cell u-table-cell-5"><b>Gesamtpreis</b></td>
</tr>
<tr style="height: 55px;" data-update-total-value ='{"calculation":{"baseValue":1.39,"toFixed":2},"selectors":{"source":"form input[type=\"number\"]","target":"form output"},"eventType":"input"}'>
<td class="u-table-cell">Kornspitz</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>1,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Kornspitz">
<input type="number" value="0" min="0" step="1" id="amount_Kornspitz">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Kornspitz">
<p>
<output for="amount_Kornspitz">0</output>
€
</p>
</form>
</td>
</tr>
<tr style="height: 55px;" data-auto-total-price='{"calculation":{"toFixed":4},"selectors":{"target":"form output"}}'>
<td class="u-table-cell">Row 2</td>
<td class="u-table-cell"></td>
<td class="u-table-cell">
<p>5,39 €</p>
</td>
<td class="u-table-cell">
<form name="amount_Row_2">
<input type="number" value="5" min="0" step="1" id="amount_Row_2" data-base-value="5.39">
</form>
</td>
<td class="u-table-cell">
<form name="price_total_Row_2">
<p>
<output for="amount_Row_2">0</output>
€
</p>
</form>
</td>
</tr>
</tbody>
</table>
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318030.html
標籤:javascript dom 数据绑定 事件处理 dom事件
