简体   繁体   English

如何为表行结果的每个按钮添加事件侦听器?

[英]How can I add an event listener to each button for a table row result?

In my rails app, I am loading a table from an @results variable such that each table row is a @result .在我的 rails 应用程序中,我从@results变量加载一个表,这样每个表行都是一个@result For each @result table row I'm looking to have buttons associated with that @result .对于每个@result表行,我希望有与该@result相关联的按钮。 I'm trying to use a Javascript eventlistener for each button and then listen for the event in the js.erb file我正在尝试为每个按钮使用 Javascript 事件侦听器,然后在 js.erb 文件中侦听事件

When running the app, it looks like only the first row of button has the event listener, how can I fix this?运行应用程序时,看起来只有第一行按钮有事件监听器,我该如何解决这个问题?

Also, how would I be able to pass my @result to my Javascript so I can utilize parts of that object?另外,我如何才能将@result传递给我的 Javascript,以便我可以利用该对象的一部分?

I'm trying to do this through Javascript as I'd like to copy something in to the clipboard and save a file onto the computer.我正在尝试通过 Javascript 执行此操作,因为我想将某些内容复制到剪贴板并将文件保存到计算机上。

js.erb js.erb

var copyTextareaBtn = document.querySelector('.button1');

copyTextareaBtn.addEventListener('click', function(event) {

# work with the @result that was clicked over here
});

html.erb html.erb

<% @results.each { |result|  %>
    <tr>
      <td><%= result[:id] %></td>
      <td> 
        <button class="button1"> B1 </button> 
        <button class="button2"> B2 </button> 
        <button class="button3"> B3 </button> 
      </td>
    </tr>

    <% } %>

You can indeed add an event listener to every element.您确实可以为每个元素添加一个事件侦听器。 The issue is document.querySelector will return the first first matched element.问题是document.querySelector将返回第一个匹配的元素。 To get all of them, you would use document.querySelectorAll .要获得所有这些,您将使用document.querySelectorAll We could rewrite your JavaScript to:我们可以将您的 JavaScript 重写为:

var btns = document.querySelectorAll('.button1');

Array.prototype.forEach.call(btns, function addClickListener(btn) {
  btn.addEventListener('click', function(event) {
    // code here to handle click
  });
});

Note that querySelectorAll returns a NodeList which is like an array but unfortunately not an array.请注意, querySelectorAll返回一个NodeList ,它类似于一个数组,但不幸的是不是一个数组。 So it doesn't have forEach and similar methods found on the Array class.所以它没有在Array类上找到forEach和类似的方法。 Thus the work around above to iterate over the nodes by using forEach from Array.prototype .因此,上面的工作通过使用Array.prototype forEach来迭代节点。

However, a much better approach is to listen for events up at the parent element or container for your form or at the document level.但是,更好的方法是在表单的父元素或容器或文档级别侦听事件。 Events bubble up so you can listen to the click event once and filter to only the type you want to respond to.事件会冒泡,因此您可以收听一次单击事件并仅过滤到您想要响应的类型。 That would be one event listener instead of N (where N is the number of buttons).那将是一个事件侦听器而不是 N(其中 N 是按钮的数量)。

The problem is you incremented the numbers of each className like button1 , button2 and called in javascript only class button1 in order to call all button1 's you need to give class button1 to each of your buttons in HTML.问题是您增加了每个className的数字,如button1button2并在仅 JavaScript 类button1中调用,以便调用所有button1 ,您需要将 class button1赋予 HTML 中的每个按钮。

EDIT: Try the code below then.编辑:然后尝试下面的代码。

var button1 = document.getElementsByClassName("button1");
Object.keys(button1).map( function (key) {
    var button = button1[key] 
    button.addEventListener("click", function(){
        alert("button1")
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM