以编程方式创建按钮的onclick事件未触发

时间:2022-03-27 20:08:25

I'm creating a button through JavaScript and am trying to assign it to an onclick event. At runtime the button is created but the onclick event isn't firing when I click it. Also in Chrome's Inspector, no error is generated when I click the button.

我正在通过JavaScript创建一个按钮,并尝试将其分配给onclick事件。在运行时,会创建按钮,但单击它时onclick事件不会触发。同样在Chrome的Inspector中,单击按钮时不会生成错误。

Here's my code:

这是我的代码:

function truncator(){
      $.each($('td.rawdata-field').not(':empty'), function(i,v){
        var count = parseInt($(v).text().length);
        var maxChars = 650;
        if(count > maxChars){
          var str = $(v).text();
          var trimmed = str.substr(0, maxChars - 2);
          $(v).text(trimmed + '...');

          var btn = document.createElement('button');

          btn.setAttribute('content', 'test content');
          btn.setAttribute('class', 'show-full-text-button');
          btn.innerHTML = 'Show Full Log';

          btn.onclick = function() {
              alert("assd");
          };

          $(v).append(btn);
        }  
      });
    };

v is the parent container, which in this case is a td element.

v是父容器,在本例中是一个td元素。

What's the problem here?

这有什么问题?

EDIT: One additional detail I can offer is that the above is being executed many times over a page, which is have something to do with why it isn't working. All the buttons are being created fine, but the alert's aren't working when done through the above method.

编辑:我可以提供的另一个细节是,上面的页面正在多次执行,这与它无法正常工作有关。所有按钮都正常创建,但通过上述方法完成时警报不起作用。

The container already exists when the above code is executed.

执行上述代码时,容器已存在。

EDIT 2: I've updated the code above to include more of what is going on. The function truncator basically is supposed to go through all td elements with class rawdata-field that are not empty, and check if the text mentioned in it is longer than 650 characters. If it is, it truncates the text to 650 characters and then puts a button there to showing the complete log if the user wishes to do so. The table on which the above function operates already exists when truncator is called.

编辑2:我已经更新了上面的代码,以包含更多正在发生的事情。函数截断器基本上应该遍历所有非空的类rawdata-field的td元素,并检查其中提到的文本是否超过650个字符。如果是,则将文本截断为650个字符,然后在那里放置一个按钮以显示完整的日志(如果用户希望这样做)。调用truncator时,上面函数运行的表已经存在。

2 个解决方案

#1


0  

Your code work fine here: https://jsfiddle.net/dusfqtr9/

你的代码在这里工作正常:https://jsfiddle.net/dusfqtr9/

  $(document).ready(function() {
    var btn = document.createElement('button');

    btn.setAttribute('content', 'test content');
    btn.setAttribute('class', 'show-full-text-button');
    btn.innerHTML = 'Show Full Log';
    btn.onclick = function() {
        alert("Hello !");
    };
    $("#container").append(btn);
  });

Maybe your script is run before the parent container created, so $(v).append(btn) do nothing.

也许你的脚本在父容器创建之前运行,所以$(v).append(btn)什么都不做。

#2


0  

onclick only works with the elements that already exist at the time when the script (containing your onclick handler) is loaded. As such, elements that get created after that, are no longer bound to the onclick event that you specified in the loaded script.

onclick仅适用于加载脚本(包含onclick处理程序)时已存在的元素。因此,之后创建的元素不再绑定到您在加载的脚本中指定的onclick事件。

I'm not sure what your full code set is, but I'm guessing that your button is regenerated probably several times after the script is loaded. This is the most likely reason why the onclick event does not fire.

我不确定你的完整代码集是什么,但我猜你的按钮在加载脚本后可能会重新生成几次。这是onclick事件不会触发的最可能原因。

As such, what you would want to do is to "attach" the event handler to a higher level in the DOM tree (highest being your html) that you are sure won't get 'programmatically' regenerated, then you'd want to check if the element in question, which is inside the DOM, exists. You then run your function when this element is found.

因此,你想要做的是将事件处理程序“附加”到DOM树中的更高级别(最高的是你的html),你肯定不会“以编程方式”重新生成,然后你想要检查是否存在DOM内部的相关元素。然后在找到此元素时运行您的函数。

Below is a JQuery implementation of this logic using the .on :

下面是使用.on的这个逻辑的JQuery实现:

EDIT1: I've edited the code based on your latest comment. You'll notice that I've separated the function that handles the click of your buttons. I urge you to try doing this in your original code set, and you'll see that the onclick event will always be bound to your buttons regardless of when your buttons are created, or even how many times you regenerate them.

编辑1:我根据您的最新评论编辑了代码。您会注意到我已经分离了处理按钮点击的功能。我建议您尝试在原始代码集中执行此操作,并且您将看到onclick事件将始终绑定到您的按钮,无论您何时创建按钮,甚至重新生成它们的次数。

EDIT2: I just noticed in the comments that you wanted to show the full text in the alert. Edited the code to show one way of doing that.

编辑2:我刚刚在评论中注意到你想在警报中显示全文。编辑代码以显示一种方法。

function truncator(){
      $.each($('td.rawdata-field').not(':empty'), function(i,v){
        var origContent = $(v).text();
      	$(v).attr('orig-content',origContent);
        var count = parseInt($(v).text().length);
        var maxChars = 10;
        if(count > maxChars){
          var str = $(v).text();
          var trimmed = str.substr(0, maxChars - 2);
          $(v).text(trimmed + '...');

          var btn = document.createElement('button');

          btn.setAttribute('content', 'test-content');
          btn.setAttribute('class', 'show-full-text-button');
          btn.innerHTML = 'Show Full Log';         
          $(v).append(btn);
        }  
      });
    };

    $('html').on('click', '.show-full-text-button', function(){
      content = $(this).closest('td').attr('orig-content');
      alert(content);
    });

    truncator();
table td {
  border:1px solid black;
  padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
  <td class="rawdata-field"> this is a very long text </td>
  <td class="rawdata-field"> another long text </td>
  <td class="rawdata-field"> this is getting out ofhand </td>
</tr>
<tr>
  <td class="rawdata-field"> okay another longtext </td>
  <td class="rawdata-field"> more content here, and there's another one here </td>
  <td class="rawdata-field"> what am i doing here </td>
</tr>
</table>

#1


0  

Your code work fine here: https://jsfiddle.net/dusfqtr9/

你的代码在这里工作正常:https://jsfiddle.net/dusfqtr9/

  $(document).ready(function() {
    var btn = document.createElement('button');

    btn.setAttribute('content', 'test content');
    btn.setAttribute('class', 'show-full-text-button');
    btn.innerHTML = 'Show Full Log';
    btn.onclick = function() {
        alert("Hello !");
    };
    $("#container").append(btn);
  });

Maybe your script is run before the parent container created, so $(v).append(btn) do nothing.

也许你的脚本在父容器创建之前运行,所以$(v).append(btn)什么都不做。

#2


0  

onclick only works with the elements that already exist at the time when the script (containing your onclick handler) is loaded. As such, elements that get created after that, are no longer bound to the onclick event that you specified in the loaded script.

onclick仅适用于加载脚本(包含onclick处理程序)时已存在的元素。因此,之后创建的元素不再绑定到您在加载的脚本中指定的onclick事件。

I'm not sure what your full code set is, but I'm guessing that your button is regenerated probably several times after the script is loaded. This is the most likely reason why the onclick event does not fire.

我不确定你的完整代码集是什么,但我猜你的按钮在加载脚本后可能会重新生成几次。这是onclick事件不会触发的最可能原因。

As such, what you would want to do is to "attach" the event handler to a higher level in the DOM tree (highest being your html) that you are sure won't get 'programmatically' regenerated, then you'd want to check if the element in question, which is inside the DOM, exists. You then run your function when this element is found.

因此,你想要做的是将事件处理程序“附加”到DOM树中的更高级别(最高的是你的html),你肯定不会“以编程方式”重新生成,然后你想要检查是否存在DOM内部的相关元素。然后在找到此元素时运行您的函数。

Below is a JQuery implementation of this logic using the .on :

下面是使用.on的这个逻辑的JQuery实现:

EDIT1: I've edited the code based on your latest comment. You'll notice that I've separated the function that handles the click of your buttons. I urge you to try doing this in your original code set, and you'll see that the onclick event will always be bound to your buttons regardless of when your buttons are created, or even how many times you regenerate them.

编辑1:我根据您的最新评论编辑了代码。您会注意到我已经分离了处理按钮点击的功能。我建议您尝试在原始代码集中执行此操作,并且您将看到onclick事件将始终绑定到您的按钮,无论您何时创建按钮,甚至重新生成它们的次数。

EDIT2: I just noticed in the comments that you wanted to show the full text in the alert. Edited the code to show one way of doing that.

编辑2:我刚刚在评论中注意到你想在警报中显示全文。编辑代码以显示一种方法。

function truncator(){
      $.each($('td.rawdata-field').not(':empty'), function(i,v){
        var origContent = $(v).text();
      	$(v).attr('orig-content',origContent);
        var count = parseInt($(v).text().length);
        var maxChars = 10;
        if(count > maxChars){
          var str = $(v).text();
          var trimmed = str.substr(0, maxChars - 2);
          $(v).text(trimmed + '...');

          var btn = document.createElement('button');

          btn.setAttribute('content', 'test-content');
          btn.setAttribute('class', 'show-full-text-button');
          btn.innerHTML = 'Show Full Log';         
          $(v).append(btn);
        }  
      });
    };

    $('html').on('click', '.show-full-text-button', function(){
      content = $(this).closest('td').attr('orig-content');
      alert(content);
    });

    truncator();
table td {
  border:1px solid black;
  padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
  <td class="rawdata-field"> this is a very long text </td>
  <td class="rawdata-field"> another long text </td>
  <td class="rawdata-field"> this is getting out ofhand </td>
</tr>
<tr>
  <td class="rawdata-field"> okay another longtext </td>
  <td class="rawdata-field"> more content here, and there's another one here </td>
  <td class="rawdata-field"> what am i doing here </td>
</tr>
</table>