简体   繁体   English

在表单提交时未调用Javascript闭包函数

[英]Javascript closure function not called on form submit

This has me perplexed. 这令我感到困惑。 I have a textbox. 我有一个文本框。 You type something in, and press enter. 输入内容,然后按Enter键。 Javascript creates a read-only input element in separate form. Javascript以单独的形式创建只读输入元素。 Along side the text input boxes are buttons to remove them. 文本输入框旁边是用于删除它们的按钮。 There is also a submit button at the bottom of that form to submit all of the read-only text inputs. 该表单底部还有一个提交按钮,用于提交所有只读文本输入。

Since clicking a button inside of a form would submit the form (and I just want to remove the parent div that contains both the button and its corresponding text input), a function is called when the form submits. 由于单击表单内的按钮将提交表单(我只想删除包含按钮及其相应文本输入的父div),因此在表单提交时会调用一个函数。 This function determines which type of button (remove or submit) was pressed and acts accordingly. 此功能确定按下了哪种类型的按钮(删除或提交)并采取相应措施。

Here comes the problem. 这就是问题所在。 When a remove button is pressed, the function destinations.enter is never called. 按下删除按钮时,永远不会调用函数destinations.enter What I did to solve this was to create a global function called submitDestinations that replicates the functionality of destinations.enter . 我所做的解决,这是创建一个名为全局函数submitDestinations可复制的功能destinations.enter If this function is called instead, everything goes off without a hitch. 如果调用此函数,一切都会顺利进行。

Does anyone have an idea as to why destinations.enter will not run on submit, but submitDestinations will? 有没有人知道为什么destinations.enter不会在提交时运行,但submitDestinations会? I want to believe that it has something to do with closures, because the function scope appears to be the only difference between the two functions. 我想相信它与闭包有关,因为函数作用域似乎是两个函数之间的唯一区别。 However, this is my first time using closures, and I have only a limited understanding of them. 但是,这是我第一次使用闭包,我对它们的了解有限。

Javascript: 使用Javascript:

var destinations = (function(){
    var max_destinations = 7;
    var counter = 0;

    function increment(){
        counter += 1;
        if(counter > max_destinations){
            throw 'Too many destinations. (Max 7)'
        }
    }
    function decrement(){
        counter += 0;
        if(counter < 0){
            alert('Cannot have less than 0 destinations..')
            throw 'Too few destinations. Get out of the console!'
        }
    }
    return {
        add : function(form){
            try{
                var formInput = form.elements[0];
                var destination = formInput.value;
                // Dont do anything if the input is empty
                if(destination == ""){
                    return false;
                }else{
                    // increment the destinations counter
                    increment();
                }
            }catch(err){
                alert(err);
                return false;
            }
            // add the text value to a visual element
            var elem = document.createElement('div');
            elem.setAttribute('class','destination');
            // create the input
            var input = document.createElement('input');
            input.setAttribute('id','dest'+String(counter));
            input.setAttribute('class','destinationText');
            input.setAttribute('style','border: none');
            input.setAttribute('name','destinations');
            input.setAttribute('readonly','readonly');
            input.setAttribute('value',destination);
            // create the remove button
            var button = document.createElement('button');
            button.setAttribute('onclick','this.form.submitted=this;');//'return destinations.remove(this);');
            button.setAttribute('class','removeButton')
            button.setAttribute('id','but'+String(counter))
            var buttonText = document.createTextNode('Remove');
            button.appendChild(buttonText);
            // add the elements to the div
            elem.appendChild(input);
            elem.appendChild(button);

            var parent = document.getElementById('destinationsDiv');
            parent.appendChild(elem);
            // clear the input box
            formInput.value = '';
            return false;
        },
        enter : function(form){
            alert('hi')
            var button = form.submitted;
            if(button.id != 'submitBtn'){
                return remove(button);
            }else{
                return true;
            }
            return false;
        },
        remove : function(button){
            try{
                decrement();
            }catch(err){
                // do not allow less than 0 counter
                alert(err);
                return false;
            }
            // remove the button's parent div altogether
            var toDelete = button.parentNode;
            toDelete.parentNode.removeChild(toDelete);
            return false;
        }

    }
})();

And the html: 和HTML:

        <div>
            <form id='hi' onsubmit="return destinations.add(this);">
                <input type="text" value="" />
            </form>
            <!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);"-->
            <form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);">
                <div id='destinationsDiv'>
                    <div>
                        <input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \>
                        <button onclick="this.form.submitted=this;" class="removeButton" id="but1" \></button>
                    </div>
                    <div>
                        <input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \>
                        <button onclick="this.form.submitted=this;" class="removeButton" id="but2" \></button>
                    </div>
                </div>
                <input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/>
            </form>
        </div>

Everything works fine if I add the following javascript function to the global scope and call it instead. 如果我将以下javascript函数添加到全局范围并调用它,一切正常。 This does the exact same thing as destinations.enter 这与destinations.enter完全相同

function submitDestinations(form){
    var button = form.submitted;
    if(button.id != 'submitBtn'){
        return destinations.remove(button);
    }else{
        return true;
    }
}

All I change in the html is the method that is called on submit: 我在html中更改的是在提交时调用的方法:

        <div>
            <form id='hi' onsubmit="return destinations.add(this);">
                <input type="text" value="" />
            </form>
            <form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);">
            <!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);"-->
                <div id='destinationsDiv'>
                    <div>
                        <input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \>
                        <button onclick="this.form.submitted=this;" class="removeButton" id="but1" \></button>
                    </div>
                    <div>
                        <input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \>
                        <button onclick="this.form.submitted=this;" class="removeButton" id="but2" \></button>
                    </div>
                </div>
                <input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/>
            </form>
        </div>

It turns out there was a naming conflict. 事实证明存在命名冲突。 The name attribute of the text inputs I was creating were set to "destinations", the same name as the javascript object I was calling on submit. 我正在创建的文本输入的name属性设置为“destinations”,与我在调用提交的javascript对象的名称相同。 The javascript in "onsubmit" was therefore trying to reference the DOM element and call enter on it instead of referencing my javascript function. 因此,“onsubmit”中的javascript尝试引用DOM元素并在其上调用enter而不是引用我的javascript函数。

There is an error in the implementation of destinations.enter(). destination.enter()的实现存在错误。 It calls remove() to remove the button, but the name 'remove' is not bound in the scope where destinations.enter() is defined. 它调用remove()来删除按钮,但名称'remove'未绑定在定义targets.enter()的范围内。

It looks as though destinations.remove() is never called elsewhere, so the easiest fix is just to move it up to being a private function in the destinations constructor, rather than making it a method on the destinations object. 看起来好像不会在其他地方调用destinations.remove(),因此最简单的修复只是将其移动到目标构造函数中的私有函数,而不是将其作为目标对象上的方法。

The modified version works because you have changed the body of submitDestinations() to call destinations.remove(), which is bound in that scope. 修改后的版本之所以有效,是因为您已将submitDestinations()的主体更改为调用目标.remove(),该范围绑定在该范围内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM