search

Home  >  Q&A  >  body text

I'm trying to learn JavaScript and trying to calculate the average of sulfur and carbon in user input text

Please refer to the HTML table below to understand the question. I've created a table and I've numbered my text boxes for clarity. I'm trying to calculate the average of text input 1 (% sulfur) and text input 2 (% sulfur) and display the result in a read-only text input 5 (average sulfur). This is for sulfur. I'm also trying to calculate the average of text input 3 (% carbon) and text input 4 (% carbon) and display the results in a read-only text input 6 (average carbon). This is for carbon. Additionally, I would like the JavaScript to do this repeatedly, averaging the next text inputs in the table (input7 and input8) and display the result in read-only input 11. The formula should also do the same for inputs 9 and 10, displaying the result in read-only input 12
P粉323374878P粉323374878457 days ago531

reply all(1)I'll reply

  • P粉530519234

    P粉5305192342023-09-04 00:56:41

    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

    /*
      在计算平均数时使用的实用回调函数。
      
      reducer用于Array.reduce()方法。
      average用于Array.map()方法。
    */
    const reducer=(a,c)=>a+c;
    const average=(n)=>parseFloat( n.value ) / 2 || 0;
    
    
    /*
      绑定到文档(或适当的父元素)的委托事件监听器
      监听并处理来自文本输入的keyup事件。在实践中,这个条件可以(应该)更加具体。
    */
    const keyuphandler=(e)=>{
      if( e.target instanceof HTMLInputElement && e.target.type=='text' ){
        /*
          使用EVENT来识别感兴趣的HTML元素。
        */
        let table=e.target.closest('table');
        let tr=e.target.closest('tr');
        
        let group=tr.dataset.group;
        let elem=e.target.dataset.elem;
        /*
          使用上述变量,现在可以很容易地识别HTML中的其他元素,
          因为我们知道了dataset属性
          - 请注意,HTML具有多个data-name类型的属性,
          用于根据化学类型和表行相关输入。
          
          inputs是一个节点列表,不是数组,所以必须将其转换为数组,
          以便我们可以使用数组方法“map”和“reduce”
          这是使用“splat”或展开运算符...完成的
          
        */
        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`);
        /*
          使用数组方法对输入值进行计算,并将结果分配给正确标识的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;}
    <!--
      注意:输入元素的名称在任何计算中都没有起作用,
      因此从以下内容中删除了这些名称。
    -->
    
    <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>&nbsp;</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>&nbsp;</td>
      </tr>
      
      <!-- 
        只需更改任何添加的附加表行对的data-group值,
        就可以轻松扩展此内容。
        例如:
        
      <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>&nbsp;</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!

    reply
    0
  • Cancelreply