订阅并处理对多个输入的更改

rkttyhzu  于 2021-09-08  发布在  Java
关注(0)|答案(2)|浏览(308)

我想向输入元素添加一个事件侦听器,该元素的元素id已存储在列表中,然后获取它们的乘积。例如:

a = ['id1', 'id2', 'id3']

我想做一些类似的事情:

input element id1 = 0.5
input element id2 = 0.6
input element id3 = 1.0
return 0.5*0.6*1

我希望随着用户更改输入框中的值,这个更新。
因此,我从以下内容开始:

function calcProduct(values){
    var product = 1;
    for(i=0; values.length; i++){
        product = product*values[i];
    }
    return product
}

id_list = ['id1', 'id2', 'id3']
function calcProduct(id_list){
    for(i=0; id_list.length; i++){
        //how do I get the values as they change so I can feed it to calcProduct?
        document.getElementById(id_list[i]).addEventListener("onchange", calcProduct(values) )
    }
}
l7mqbcuq

l7mqbcuq1#

使用事件侦听器和 reduce() 你可以累积最终产品。注意:在事件侦听器中,省略“on”,因此使用 change 而不是 onchange . 为了更简单,我对将要计算的输入使用了一个类名

window.addEventListener('load', () => {
  document.querySelectorAll('.to-calc').forEach(el => el.addEventListener('change', calcProduct))
  calcProduct()
})

function calcProduct(e) {
  let output = [...document.querySelectorAll('.to-calc')].reduce((b, a) => b * +a.value, 1)
  console.log(output.toFixed(2))
  return output.toFixed(2)
}
<input class='to-calc' type='number' value='0.5'> <input class='to-calc' type='number' value='0.6'> <input class='to-calc' type='number' value='0.1'>
iezvtpos

iezvtpos2#

为此,我将结合事件授权和React式编程。
将事件侦听器连接到父节点,并在事件传入时对其进行筛选:
input 事件被调度到父级 <div> 抓住它。
这个 filter 操作员确保我们使用正确的事件。
这个 scan 运算符将新值写入Map。
这个 map 运算符将贴图中的值相乘。
最后,订户接收并显示产品。
这样我们就可以处理多组数字。
(注意Map如何与dom中的ID和值相对应。)

const mult = nums =>
  fromEvent(document.querySelector('div'), 'input')                       //1
  .pipe( filter(e => e.target.id in nums)                                 //2
       , scan((acc, {target: {id, value}}) => (acc[id]=value, acc), nums) //3
       , map(ns => Object.values(ns).reduce((p, n) => p * n, 1)));        //4

mult({n1: 1, n2: 1, n3: 1}).subscribe(display('#p1'));                    //5
mult({n4: 1, n5: 1, n6: 1}).subscribe(display('#p2'));                    //5
mult({n7: 1, n8: 1, n9: 1}).subscribe(display('#p3'));                    //5
input{width:30px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.2.0/rxjs.umd.min.js" integrity="sha512-MlqMFvHwgWJ1vfts5fdC2WzxDaIXWfYuAd9Tb2lobtF61Gk+HIRDrbtxgasBSM9lZgOK9ilwK9LqFIYEV+k0IA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const {fromEvent} = rxjs;
const {filter, map, scan} = rxjs.operators;
const display = sel => val => document.querySelector(sel).textContent = val;
</script>
<div>
  <input id="n1" type="number" value="1"/> ×
  <input id="n2" type="number" value="1"/> ×
  <input id="n3" type="number" value="1"/> = <span id="p1">1</span>
  <hr/>
  <input id="n4" type="number" value="1"/> ×
  <input id="n5" type="number" value="1"/> ×
  <input id="n6" type="number" value="1"/> = <span id="p2">1</span>
  <hr/>
  <input id="n7" type="number" value="1"/> ×
  <input id="n8" type="number" value="1"/> ×
  <input id="n9" type="number" value="1"/> = <span id="p3">1</span>
</div>

相关问题