多个处理程序附加到同一个HTML元素

Multiple handlers attached to the same HTML element

本文关键字:同一个 HTML 元素 处理 程序      更新时间:2023-09-26

我有一个简单的代码。每次我点击"开始"按钮,3个具有唯一id和值的新按钮被创建并附加到我的div。

对于每个新按钮,如果我点击它,它会提醒按钮内的值。我的问题是,如果我点击"开始"按钮4次,所以有12个新按钮创建(这是OK的),但每当我点击任何新创建的按钮,它提醒几次(不是我期望的1次)。

我想问题是,每次我点击按钮"开始",一个新的处理程序附加到按钮。如何避免这个问题。我已经谷歌jQuery off(),但它没有帮助太多。非常感谢您的帮助。

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript">
var count =1;
$( document ).ready(function() {
$('#start').on('click', function(e) {
    var i;
    for (i=0;i< 3;i++)
        {
        $('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>').appendTo('#mydiv');    
        count++;
        }       
    for(i=1;i<= count;i++)
        {
        $(document).on("click", '#Button' + i , function(){
              alert (  $(this).attr('value')  );
            });         
        }               
});
});
</script>
</head>
<body>
<h1>Test dynamically created button</h1>
<div id = "mydiv">
<button id ="start">START</button> 
</div>                       
</body>
</html>

你猜对了。您添加了几次处理程序。

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
var count = 1; //no need to make it global
$('#start').on('click', function(e) {
    var i;
    for (i=0;i< 3;i++)
        {
        $('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>')
            .click(function(){//add handler when button created... and never more
              alert (this.value);//or $(this).val()
            })         
            .appendTo('#mydiv');    
        count++;
        }       
    /* here you add handlers more and more times
    for(i=1;i<= count;i++)
        {
        $(document).on("click", '#Button' + i , function(){
              alert (  $(this).attr('value')  );
            });         
        } 
    */
});
});
</script>
</head>
<body>
<h1>Test dynamically created button</h1>
<div id = "mydiv">
<button id ="start">START</button> 
</div>                       
</body>
</html>

如果你的按钮留在DOM中(就像现在看起来的那样),为什么不直接在新添加的按钮上添加EventListener,像这样:

$('#start').on('click', function(e) {
    var i;
    for (i=0;i< 3;i++) {
        var myNewButton = $('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>');
        myNewButton.appendTo('#mydiv');
        myNewButton.on("click", function() {
              alert (  $(this).attr('value')  );
        });
        count++;
     }               
});

否则,正如您在问题中已经猜到的那样,由于要循环遍历所有按钮,您需要向现有按钮添加额外的侦听器。

在每次点击开始时,你也为已经在页面上的按钮创建事件处理程序,这意味着它们得到几个处理程序附加到它们上,你越点击开始按钮。

只需在document ready(不是on click)上添加以下处理程序,如果它有一个类似Button*的id,它将捕获任何未来的按钮单击:

$(document).on('click', '[id^=Button]', function () {
    alert ($(this).attr('value')  );
});

从开始按钮的处理程序中删除创建这样的单击处理程序。

代码变成:

$(document).ready(function() {
    var count = 0;
    $(document).on('click', '[id^=Button]', function () {
        alert ($(this).attr('value')  );
    });
    $('#start').on('click', function(e) {
        var i;
        for (i=0;i<3;i++) {
            $('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>').appendTo('#mydiv');    
            count++;
        } 
    });
});

这样,您只有两个处理程序:一个用于开始按钮,另一个用于所有其他Button*按钮。无需动态添加新的处理程序