是否可以在通过javascript修改过的对象上添加事件监听器?

时间:2019-01-07 23:49:05

标签: javascript

我有一张表,其中当用户更改弹出模式中的数量时,使用javascript更新行的总和。我希望每次行总数更改时都可以更新所有行的总数。

我试图在我的每一行的总数上添加一个事件监听器onchange和oninput,但是它不起作用。我试图通过在用户更改的数量上添加事件侦听器来找到解决方法,但是没有任何效果。我已经在控制台中尝试了该代码,并且该代码正在运行,但是事件监听器似乎没有触发。

 document.getElementById("work_quantity_<%= @work_detail.id %>").addEventListener("change", grandTotal)


 var work_detail_quantity = document.getElementById("work_quantity_<%= @work_detail.id %>").value;
 var work_detail_block = document.getElementById("work-<%= @work_detail.id %>");
 var quant = work_detail_block.getElementsByTagName('td')[1];
  quant.innerHTML = work_detail_quantity+" <%= @work_detail.work_resource.unit_measure%>";


function grandTotal() {
  var sub_total = document.getElementById("subtotal_lign").innerHTML
  var table = document.getElementById("invoice_summary"), sumVal = 0;

  for(var i = 1; i < table.rows.length; i++)
  {
      sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
  }
  document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};

如果有人可以给我一个提示,那将不胜感激,我是javascript的新手。谢谢

enter image description here

3 个答案:

答案 0 :(得分:1)

像这样解析DOM以获得值不是一个好主意。

解决方案1 ​​

您将获得包含表形式Ruby值的对象。像这样:

var works = <%= @works.to_json %>;

然后,当用户更新其订单时,您首先更新对象,然后根据更新后的对象更新表。

解决方案2

用户更新其订单时,会将更新发送到服务器,然后在服务器端更新表。

解决方案3(不推荐)

如果您仍然想通过解析DOM来做到这一点,请查看MutationObserver来监听表中的更改。

答案 1 :(得分:0)

已更新

我以为我在下面写的是行得通的,但实际上总数总是落后一个计算,因为它是在更改数量后更新修改后的行的总数之前进行行的总和。


好的,它正在解决,但我仍然相信MutationObservers可能是将来解决此类问题的好方法

Good tutorial:用于MutationObservers

为了使我的事件监听器正常工作,我添加了一个在用户更改数量之前定义它(不是吗)

1)将事件侦听器添加到要跟踪的对象

document.getElementById("work_quantity_<%= @work_detail.id %>").addEventListener("input", grandTotal)

2)这是我用javascript更改对象的地方

var work_detail_block = document.getElementById("work-<%= @work_detail.id %>");
  var quant = work_detail_block.getElementsByTagName('td')[1];
  quant.innerHTML = work_detail_quantity+" <%= @work_detail.work_resource.unit_measure%>";

3)我定义了在步骤1中调用的功能

function grandTotal() {
  var sub_total = document.getElementById("subtotal_lign").innerHTML
  var table = document.getElementById("invoice_summary"), sumVal = 0;

  for(var i = 1; i < table.rows.length; i++)
  {
    sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
  }
document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};

答案 2 :(得分:0)

我承认,我没有说过这个尝试;但我确实在jQuery中尝试过类似的操作,主要是因为您的示例缺少表的详细信息;

但是您需要在发生更改时触发事件,我在这里假设您未使用标准输入字段,因此您是否使用了 之类的格式,因此无法监视它们的更改,但必须进行键控并且可以监视模糊,因此,如果要触发模糊计算,则在该事件发生时,触发表和事件...

我实际上会为此使用jQuery,但是这里...

document.getElementById("work_quantity_<%= @work_detail.id %>").addEventListener("change", grandTotal)
 ...
function grandTotal() {
    var sub_total = document.getElementById("subtotal_lign").innerHTML
    var table = document.getElementById("invoice_summary"), sumVal = 0;

    for(var i = 1; i < table.rows.length; i++) {
        sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
    }
    document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};

// something like this
(function() {
    // i assume it's cell[4] that is being edited, and it's like contenteditable
    var table = document.getElementById("invoice_summary");

    for(var i = 1; i < table.rows.length; i++) {
        /* assign listener on the cell, 
        when it blurs, trigger the update, 
        you could also monitor keyup
        */
        table.rows[i].cells[4].addEventListener("blur", function(e) {
            document.getElementById("work_quantity_<%= @work_detail.id %>").dispatchEvent("change", grandTotal);

        });

    }

})();