Javascript event.preventDefault();即使在委派事件中也不起作用

Javascript event.preventDefault();即使在委派事件中也不起作用,javascript,jquery,forms,Javascript,Jquery,Forms,我想阻止默认表单在动态生成的表单上的提交行为,但是event.preventDefault();即使委托事件(.on)也不起作用。这是我的js代码: $(document).ready(function() { $("#add").click(function() { var intId = $("#buildyourform div").length + 1; var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"f

我想阻止默认表单在动态生成的表单上的提交行为,但是event.preventDefault();即使委托事件(.on)也不起作用。这是我的js代码:

$(document).ready(function() {
$("#add").click(function() {
    var intId = $("#buildyourform div").length + 1;
    var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + intId + "\"/><br>");
    // I am adding 2 new forms there:
    var topic = $( '<form action = "#" method = "POST" name="new_topic" id="new_topic">'+ document.getElementById('csrf_token').value +
                  '<textarea  name="name" maxlength="1000" cols="25" rows="6" id="new_form"></textarea></form>'+
                  '<br><input type="submit" value="Submit" class="newMygt" />');


    var summary = $('<form action = "#" method = "POST" name="new_summary" id="new_summary">'+ document.getElementById('csrf_token').value +
                    '<textarea  name="content" maxlength="1000" cols="25" rows="6" id="new_form"></textarea></form>'+
                    '<br><input type="submit" value="Submit" class="newMygt" />');


    (topic).appendTo(fieldWrapper).show('slow');
    (summary).appendTo(fieldWrapper).show('slow');
    $("#buildyourform").append(fieldWrapper);


});

// after clicking the '.newMygt' button the form subitms...
$('.fieldwrapper').on("click", ".newMygt",function(e){
    e.preventDefault();
    a = JSON.stringify($('#new_topic, #new_summary').serializeObject()); // turn that "array or smth" into JSON
    alert(a)
});

首先,代码中使用了错误的选择器;“#”表示ID,您要使用的是“.”,用于选择类:

$('#fieldwrapper')
应该是

$('.fieldwrapper')
另外,应该注意的是,没有结束表单标签:

</form>

意识到元素“fieldwrapper”也是在加载页面后插入的,因此事件委派失败。

我已经在这个提琴中列出了您需要解决的问题-

要解决的两个主要问题是

  • 错误的标记-您在多个位置使用了相同的ID,并且某些元素没有结束标记

  • 绑定-使用错误的选择器绑定到元素。即使修复了选择器,绑定发生时该元素也不存在。您需要绑定到父级

  • 复制下面的代码

    $("#add").click(function () {
        var intId = $("#buildyourform div").length + 1;
    
    
    
        var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + intId + "\"/><br>");
        // I am adding 2 new forms there:
    
        /** 
    FIX THIS - You use the same ID for the form. You need to make those unique. Possibly the name as well. Both forms
    **/
        var topic = $('<form action = "#" method = "POST" name="new_topic" id="new_topic">' + document.getElementById('csrf_token').value +
            '<textarea  name="name" maxlength="1000" cols="25" rows="6" id="new_form"></textarea>' +
            '<br><input type="submit" value="Submit" class="newMygt" /></form>');
    
        var summary = $('<form action = "#" method = "POST" name="new_summary" id="new_summary">' + document.getElementById('csrf_token').value +
            '<textarea  name="content" maxlength="1000" cols="25" rows="6" id="new_form"></textarea>' +
            '<br><input type="submit" value="Submit" class="newMygt" /></form>');
        /** 
    FIX THIS - Missing closing tags for both the forms
    **/
    
    
        (topic).appendTo(fieldWrapper).show('slow');
        (summary).appendTo(fieldWrapper).show('slow');
        $("#buildyourform").append(fieldWrapper);
    
    
    });
    
    // after clicking the '.newMygt' button the form subitms...
    /** 
    FIX THIS - You need to bind to an element that exists when the binding is done. You were binding to the form, which is incorrect. Bind to the container. 
    **/
    $('#buildyourform').on("click", ".newMygt", function (e) {
        e.preventDefault();
        a = JSON.stringify($('#new_topic, #new_summary').serialize()); //FIX THIS - The method is serizalize()
        alert(a)
    });
    
    $(“#添加”)。单击(函数(){
    var intId=$(“#buildyourform div”).length+1;
    var fieldWrapper=$(“
    ”); //我在那里添加了两个新表格: /** 修复此问题-您对表单使用相同的ID。您需要使这些ID唯一。可能还有名称。两个表单 **/ var topic=$(''+document.getElementById('csrf_标记')。值+ '' + “
    ”); var summary=$(''+document.getElementById('csrf_标记')。值+ '' + “
    ”); /** 修复此问题-两个表单都缺少结束标记 **/ (topic).appendTo(fieldWrapper.show('slow'); (摘要).appendTo(fieldWrapper.show('slow'); $(“#buildyourform”).append(fieldWrapper); }); //单击“.newMygt”按钮后,表单子项。。。 /** 修复此问题-您需要绑定到绑定完成时存在的元素。您绑定到表单,这是不正确的。绑定到容器上。 **/ $(“#buildyourform”)。在(“click”、“.newMygt”上,函数(e){ e、 预防默认值(); a=JSON.stringify($('#new_topic,#new_summary').serialize();//解决这个问题-方法是serizalize() 警报(a) });
    @Kye感谢您的快速回答!我现在已经编辑了代码,并在文本区域后添加了结束表单标记,但问题仍然存在。我尝试在按钮后添加关闭表单标签,但表单仍然提交。更新了上面的答案。问题是您正在“fieldwrapper”元素上添加一个尚未存在的事件侦听器。查看有关javascript事件委托的文章以获取参考。感谢您的更新和参考一些要阅读的材料,我当然需要阅读更多关于使用尚不存在的对象的内容,以理解js的“逻辑”。事件委派是JS中将事件分配给“未来”元素的常见技巧。再次感谢。我想,为了解决我在下面的JohnP评论下发布的问题,我需要阅读这些内容。@JohnP>感谢您提供了非常详细的答案。我已经修正了错误,数据现在会弹出,我会将你的答案标记为正确。但这里有一点需要注意:我正在使用一个自定义Javascript SerializeObject()代码段,将其转换为一个表单字段-表单值dict,然后通过json.stringify()将该dict转换为json。是否有任何方法可以使用以下代码段从动态添加的表单解析用户输入的数据:?现在我得到了{“名称”:“,”内容”:“}@Eimantas看看这把小提琴-。我修改了您的单击函数,以查看最接近的表单并将其序列化。这在一定程度上是可行的,但您需要修改表单添加代码,以便它自动为输入生成正确的ID/名称。否则serializeObject函数将继续覆盖以前的值,因为它们都具有相同的id/名称。谢谢!但不幸的是,serializeObject()函数现在返回一个空dict
    {}
    。我已将当前的问题分解为一个新问题,可以在那里找到:
    $(document).on("click", ".newMygt",function(e){
    
    $("#add").click(function () {
        var intId = $("#buildyourform div").length + 1;
    
    
    
        var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + intId + "\"/><br>");
        // I am adding 2 new forms there:
    
        /** 
    FIX THIS - You use the same ID for the form. You need to make those unique. Possibly the name as well. Both forms
    **/
        var topic = $('<form action = "#" method = "POST" name="new_topic" id="new_topic">' + document.getElementById('csrf_token').value +
            '<textarea  name="name" maxlength="1000" cols="25" rows="6" id="new_form"></textarea>' +
            '<br><input type="submit" value="Submit" class="newMygt" /></form>');
    
        var summary = $('<form action = "#" method = "POST" name="new_summary" id="new_summary">' + document.getElementById('csrf_token').value +
            '<textarea  name="content" maxlength="1000" cols="25" rows="6" id="new_form"></textarea>' +
            '<br><input type="submit" value="Submit" class="newMygt" /></form>');
        /** 
    FIX THIS - Missing closing tags for both the forms
    **/
    
    
        (topic).appendTo(fieldWrapper).show('slow');
        (summary).appendTo(fieldWrapper).show('slow');
        $("#buildyourform").append(fieldWrapper);
    
    
    });
    
    // after clicking the '.newMygt' button the form subitms...
    /** 
    FIX THIS - You need to bind to an element that exists when the binding is done. You were binding to the form, which is incorrect. Bind to the container. 
    **/
    $('#buildyourform').on("click", ".newMygt", function (e) {
        e.preventDefault();
        a = JSON.stringify($('#new_topic, #new_summary').serialize()); //FIX THIS - The method is serizalize()
        alert(a)
    });