.append() 和 .html() 之间的不同行为

Different behavior between .append() and .html()

我的代码:https://jsfiddle.net/hbli/xyeoatf9/1/

我想为动态元素添加事件侦听器:

$('.parent').on('mousedown', function(e){
    $('.parent').html('<div class="child"></div>');
    //$('.parent').append('<div class="child"></div>');
    console.log('parent mousedown');
})

$('body').on('click', '.child', function(e){
    console.log('child click');
})

如果我使用“$('.parent').html('<div class="child"></div>');”,则永远不会在“.child”元素上触发点击事件。 但是如果我把.html改成.append,就可以触发事件了。

我想知道为什么他们有不同的行为?

谢谢。

问题是因为您在 .child 元素上使用了委托事件处理程序。因此,事件必须通过 .parent 元素传播,因此 mousedown 事件处理程序在 .child 单击之前触发。

这意味着当您使用 html() 时,.child 会被删除,然后重新创建。反过来,当您使用 append() 时,.child 元素仍然存在,因为委托的点击事件在其上 运行。

当您使用 html() 覆盖内容时,.child 元素不再存在,它被替换因此事件不会传播。

当使用 .append() 时,.child 存在并且事件被传播。所以你收到消息

添加一个计数器让我们证实当 .child 被保留时点击事件被触发,但是当它被替换时你最终得到一个不同的 .child 没有启动任何事件

注意你是如何在一个 .child 上执行 mousedown 而在另一个 .child 上执行 mouseup

let counter = 0;
$('.parent').on('mousedown', function(e){
    ++counter;
    $('.parent').html('<div class="child">' + counter + '</div>');
    //$('.parent').append('<div class="child">' + counter + '</div>');
    console.log('parent mousedown');
})

$('body').on('click', '.child', function(e){
    console.log('child click: ' + $(this).html());
})

$('body').on('mouseup', '.child', function(e){
    console.log('child mouseup: ' + $(this).html());
})

$('body').on('mousedown', '.child', function(e){
    console.log('child mousedown: ' + $(this).html());
})
.parent {
  width:400px;
  height:200px;
  background-color: green;
}

.child {
  width:200px;
  height:20px;
  background-color: yellow;
  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="parent"></div>

如果您想使用方法 HTML 并且仍然想在“.child”元素上添加事件,您可以简单地在标签本身中分配事件方法,例如

$('.parent').on('mousedown', function(e){
    $('.parent').html('<div class="child" onclick="clickMethod();"></div>');
    console.log('parent mousedown');
})

function clickMethod()
{
    console.log('child click');
}

以下是并排演示

let counter1 = 0;
$('.parent-replace').on('mousedown', function(e){
    ++counter1;
    $('.parent-replace').html('<div class="child">' + counter1 + '</div>');
    console.log('parent-replace mousedown');
})

let counter2 = 0;
$('.parent-append').on('mousedown', function(e){
    ++counter2;
    $('.parent-append').append('<div class="child">' + counter2 + '</div>');
    console.log('parent-append mousedown');
})

$('body').on('click', '.child', function(e){
    console.log('child click: ' + $(this).html());
})

$('body').on('mouseup', '.child', function(e){
    console.log('child mouseup: ' + $(this).html());
})

$('body').on('mousedown', '.child', function(e){
    console.log('child mousedown: ' + $(this).html());
})
.parent {
  width:200px;
  height:200px;
}

.parent-replace {
  background-color: green;
}

.parent-append {
  background-color: blue;
}

.child {
  width:200px;
  height:20px;
  background-color: yellow;
}

.side-by-side {
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<div class="side-by-side">
  REPLACING child
  <div class="parent-replace parent"></div>
</div>

<div class="side-by-side">
  APPENDING children
  <div class="parent-append parent"></div>
</div>