为什么javascript函数不会在首次运行时更新DOM

时间:2014-08-26 14:10:26

标签: javascript jquery forms dynamic

我有一个动态表单,用户可以通过单击按钮添加输入。这很好用。但是,单击以删除输入时,第一次单击不会删除输入。按预期删除输入后的每次单击。我可以看到它在第一次单击时运行该功能以删除但在DOM中没有任何更新,因此该字段保持不变。这是我的HTML:

<button onclick="AddFileField()">Add File</button>
<br />
<br />
<form action="" method="post" enctype="multipart/form-data">
    <div id="fileFields"></div>
    <br />
    <input type="submit" value="Upload" />
</form>

相关的javascript:

function removeField() {
    $('.removeclass').click(function () {
        $(this).parent().remove();
    });
    return false;
}

var FieldCount = 1; //to keep track of text box added
function AddFileField() {
    var MaxInputs = 10; //maximum input boxes allowed
    var InputsWrapper = $("#fileFields"); //Input boxes wrapper ID
    var x = $("#fileFields > div").length + 1; //current text box count

    if (x <= MaxInputs) //max input box allowed
    {
        $(InputsWrapper).append('<div class="fileInp"><label for="file' + FieldCount + '">File:</label><input type="file" name="files" class="inpinl" id="file' + FieldCount + '" /><a href="#" class="removeclass" onclick="removeField()">&times;</a></div>');
        FieldCount++;
    }
    return false;
}

fiddle显示问题。要复制添加几个字段,然后单击一个x。第一次单击不执行任何操作,然后单击继续单击删除字段。如何才能获得第一次点击以删除该字段?

5 个答案:

答案 0 :(得分:3)

这是因为您在另一个事件处理程序中注册了事件处理程序。

http://jsfiddle.net/3e1ajtvo/11/

我删除了您的事件处理程序,现在,您将单击的元素elem传递给函数本身。

事实上,你甚至不需要这个功能,只要暴露出jquery(就在你的情况下)。

http://jsfiddle.net/3e1ajtvo/12/

答案 1 :(得分:1)

工作小提琴是here

问题在于功能:

function removeField() {
    $('.removeclass').click(function () {
        $(this).parent().remove();
    });
    return false;
}

当您点击X时,会调用此函数,该函数会向click添加X事件处理程序以将其删除;但是,直到下次单击它时才会调用此事件处理程序。 (这就是点击X两次工作的原因。)

在更新的小提琴中,您只需将this传递给removeField:

//HTML
<a href="#" class="removeclass" onclick="removeField(this)">&times;</a></div>

//JS
function removeField(me) {
    $(me).parent().remove();
    return false;
}

答案 2 :(得分:1)

原因是您正在使用onclick="removeField()"

让我们来看看你的功能。单击“删除”按钮时,将运行以下脚本。然后,此脚本 创建 一个点击处理程序,该处理程序将在下一次点击时激活,因为当您第一次点击删除时,处理程序未创建

function removeField() {
    $('.removeclass').click(function () {
        $(this).parent().remove();
    });
    return false;
}

所以你需要更换这是另一个功能。由于您使用的是jQuery,因此您可以学习使用.on()来动态生成元素。

$(document).on('click', '.removeclass', function () {
    $(this).parent().remove();
});

http://jsfiddle.net/Spokey/3e1ajtvo/16/

答案 3 :(得分:1)

我使您的代码更加模块化,并将其更改为使用jQuery比您更多。这只是另一种方法,其他答案也是有效的。

http://jsfiddle.net/3e1ajtvo/19/

var fields = {
    btnAdd: $('#addField'),
    inputWrapper: $('#fileFields'),
    maxInputs: 10,
    fieldCount: 1,    
    init: function(){
        this.inputWrapper.on('click', '.removeclass', this.removeInput);
        this.btnAdd.on('click', this.appendField);
    },
    removeInput: function(){
        //this will refer to the html element you clicked on
        $(this).parent().remove();
    },
    appendField: function(){
        //this will refer to the html element you clicked on
        if ( fields.inputWrapper.children('div').length <= fields.maxInputs ){
            fields.inputWrapper.append('<div class="fileInp"><label for="file' + fields.fieldCount + '">File:</label><input type="file" name="files" class="inpinl" id="file' + fields.fieldCount + '" /><a href="#" class="removeclass">&times;</a></div>');
            fields.fieldCount++;
        }
    }

};

fields.init();

答案 4 :(得分:0)

您没有执行代码以在第一次单击时删除行,您只是将单击处理程序添加到链接。之后它会起作用,因为$('。removeclass')。click(...然后按预期触发。