jQuery on()方法不适用于已添加的DOM元素

6

我有这个:

$(document).on("click", ".prev", function(){
    $(this).closest("div").find(".slider").animate({
        "left": "+=450px"
    }, 800, "easeInOutBack");
    return false;
});

当新元素添加到DOM中时,它可以正常工作,但对于已经存在于DOM中的元素则不起作用。
当我执行以下操作:
$(".prev").on("click", function(){
    $(this).closest("div").find(".slider").animate({
        "left": "+=450px"
    }, 800, "easeInOutBack");
    return false;
});

它适用于DOM中的元素,但对于添加到DOM的新元素不起作用。是否有一种方法可以在不写两次或调用另一个函数的情况下使其同时适用于两者?

这是截图:

Shot

因此,以下是更详细的描述它的工作原理。

<div id="simple-pevs" style="padding-right: 20px;">
    <?php require_once __DIR__ . "/data/get/PEVSection.php"; ?>
</div>

当某人想要添加另一个部分时,他们会点击添加按钮,该按钮会运行以下代码:
    $(".add-another-pev").click(function(){
        $.get("./data/get/PEVSection.php?pev="+pevGroup, function(data){
            $("#simple-pevs").append(data);
        });
        pevGroup++;
        return false;
    });

你可以看到它调用的是与php预加载相同的函数。新的函数(以及添加的任何其他函数)都可以与单击事件一起使用,而第一个函数则不行。
@ArunPJohny
在添加新元素后,输入console.log($(".prev"));:
[a.prev, a.prev, prevObject: b.fn.b.init[1], context: document, selector: ".prev", jquery: "1.9.1", constructor: function…]
0: a.prev
1: a.prev
context: #document
length: 2
prevObject: b.fn.b.init[1]
selector: ".prev"
__proto__: Object[0]

9
第一个代码片段应该适用于新旧元素。请提供一个 jsfiddle 来展示它是否不起作用。 - Kevin B
3
你是在$(document).ready()中运行它吗? - Michael Berkowski
1
@RyanNaddy 请看Michael Berkowski的评论 - 你需要将这个放在document.ready处理程序中。jsfiddle会自动(且不可见地)完成此操作。 - Alnitak
2
文档就绪状态不应影响此代码,他直接绑定到文档上。https://dev59.com/22gv5IYBdhLWcg3wYvyi#10642199 - Kevin B
2
请查看此问题的症状。使用委托方法只能使其适用于新元素,而使用非委托方法只能使其适用于现有元素。很可能新元素与现有元素的结构存在差异,这才是导致真正问题的原因。请提供相关的HTML代码。(或者如最初所要求的那样提供JSFiddle链接) - Kevin B
显示剩余16条评论
2个回答

2
以下是我从Jquery官网复制的内容,可以很清楚地说明: 事件处理程序仅绑定到当前选择的元素;它们必须在代码调用.on()时存在于页面上。为确保元素存在且可被选择,请在文档准备好处理程序内执行事件绑定,以针对在页面上的HTML标记中的元素。如果正在将新的HTML注入页面,则在将新的HTML放置到页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序,如下所述。 委派事件的优点在于,它们可以处理稍后添加到文档中的后代元素的事件。通过选择保证在附加委派事件处理程序时存在的元素,您可以使用委派事件来避免频繁附加和删除事件处理程序。例如,这个元素可以是Model-View-Controller设计中视图的容器元素,或者如果事件处理程序想要监视文档中的所有冒泡事件,则可以是文档。文档元素在加载任何其他HTML之前在文档头中可用,因此可以安全地在那里附加事件而无需等待文档准备就绪。 除了它们处理尚未创建的后代元素的事件的能力之外,委派事件的另一个优点是它们在需要监视许多元素时具有更低的开销潜力。在其tbody中有1,000行数据表上,此示例将处理程序附加到1,000个元素:
$("#dataTable tbody tr").on("click", function(event){
alert($(this).text());
});

委托事件的方法只将事件处理程序附加到一个元素,即tbody元素,事件只需要向上冒泡一级(从被点击的tr元素到tbody元素):
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});

注意:委托事件不适用于SVG。 http://api.jquery.com/on/

这在最新版本的jQuery中是正确的 - 但是OP没有提供他正在使用哪个版本的jQuery。 - JakeJ

-1

如果您像这样创建新元素,则需要重新绑定事件处理程序。

function bindHandler() {
    $(document).on("click", ".prev", function(){
        $(this).closest("div").find(".slider").animate({
            "left": "+=450px"
        }, 800, "easeInOutBack");
        return false;
    });
}
bindHandler();

$(".add-another-pev").click(function(){
    $.get("./data/get/PEVSection.php?pev="+pevGroup, function(data){
        $("#simple-pevs").append(data);
    });
    pevGroup++;

    bindHandler();
    return false;
});

这是不正确的,jQuery中.on()事件的正确用法会自动处理事件的初始绑定和重新绑定,避免需要手动操作。 - JakeJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接