If you take the dataset
attribute, you can associate input and output elements in such a way that calculations can be performed with any number of inputs. The comments in the javascript below should explain what's going on
/* 在計(jì)算平均數(shù)時(shí)使用的實(shí)用回調(diào)函數(shù)。 reducer用于Array.reduce()方法。 average用于Array.map()方法。 */ const reducer=(a,c)=>a+c; const average=(n)=>parseFloat( n.value ) / 2 || 0; /* 綁定到文檔(或適當(dāng)?shù)母冈兀┑奈惺录O(jiān)聽器 監(jiān)聽并處理來(lái)自文本輸入的keyup事件。在實(shí)踐中,這個(gè)條件可以(應(yīng)該)更加具體。 */ const keyuphandler=(e)=>{ if( e.target instanceof HTMLInputElement && e.target.type=='text' ){ /* 使用EVENT來(lái)識(shí)別感興趣的HTML元素。 */ let table=e.target.closest('table'); let tr=e.target.closest('tr'); let group=tr.dataset.group; let elem=e.target.dataset.elem; /* 使用上述變量,現(xiàn)在可以很容易地識(shí)別HTML中的其他元素, 因?yàn)槲覀冎懒薲ataset屬性 - 請(qǐng)注意,HTML具有多個(gè)data-name類型的屬性, 用于根據(jù)化學(xué)類型和表行相關(guān)輸入。 inputs是一個(gè)節(jié)點(diǎn)列表,不是數(shù)組,所以必須將其轉(zhuǎn)換為數(shù)組, 以便我們可以使用數(shù)組方法“map”和“reduce” 這是使用“splat”或展開運(yùn)算符...完成的 */ let result=table.querySelector(`tr[data-group="${group}"] input[data-elem="${elem}"].result`); let inputs=table.querySelectorAll(`tr[data-group="${group}"] input[data-elem="${elem}"].input`); /* 使用數(shù)組方法對(duì)輸入值進(jìn)行計(jì)算,并將結(jié)果分配給正確標(biāo)識(shí)的input.result元素。 */ result.value = [...inputs] .map( average ) .reduce( reducer, 0 ) } }; document.addEventListener('keyup',keyuphandler);
table { width: 50px; box-sizing:border-box; border: 1px solid black; border-collapse: collapse; font-family:monospace } td { border: 1px solid black; padding: 0px; font-size: 10px; } th { border: 1px solid black; padding: 0px; } form { width: 4px; } div { display: grid; } label { display: block; width: 4px; font-size: 14px; } input [type="date"] { width: 4px; } /* 以下僅用于美化 示例 ;-) */ table { box-sizing:border-box; font-family:monospace } td,th{padding:0.25rem;} [data-elem='carbon']{background:rgba(0,0,100,0.1)} [data-elem='sulphur']{background:rgba(0,100,0,0.1)} [readonly]{background:rgba(255,0,0,0.1)} .input{width:3rem} .result{width:3.5rem} input{border:1px solid grey;padding:0.2rem;}
<!-- 注意:輸入元素的名稱在任何計(jì)算中都沒有起作用, 因此從以下內(nèi)容中刪除了這些名稱。 --> <table> <tr> <th>%<br />Sulphur</th> <th>%<br />Carbon</th> <th>Average<br />Sulphur</th> <th>Average<br />Carbon</th> </tr> <tr data-group=1> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td><input type='text' class='result' data-elem='sulphur' readonly /></td> <td><input type='text' class='result' data-elem='carbon' readonly /></td> </tr> <tr data-group=1> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td colspan=2> </td> </tr> <tr data-group=2> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td><input type='text' class='result' data-elem='sulphur' readonly /></td> <td><input type='text' class='result' data-elem='carbon' readonly /></td> </tr> <tr data-group=2> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td colspan=2> </td> </tr> <!-- 只需更改任何添加的附加表行對(duì)的data-group值, 就可以輕松擴(kuò)展此內(nèi)容。 例如: <tr data-group=3> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td><input type='text' class='result' data-elem='sulphur' readonly /></td> <td><input type='text' class='result' data-elem='carbon' readonly /></td> </tr> <tr data-group=3> <td><input type='text' class='input' data-elem='sulphur' /></td> <td><input type='text' class='input' data-elem='carbon' /></td> <td colspan=2> </td> </tr> --> </table>
I know you are new to JavaScript, so much of what you see here may be very intimidating and confusing. Still, as your knowledge grows, you'll hopefully find value in some of the techniques presented here - but if you have questions, feel free to ask!