How to javascript submit in the presence of an input id equal to 'submit'

a 夏天 提交于 2020-01-22 15:16:11

问题


I've been binding submit events to forms, and ensuring that they do not break the form, using jQuery like this:

jQuery('form').submit(function(e){
    var form = this;
    e.preventDefault(); 
    alert('1');
    setTimeout(function() {   
        alert('2');
        form.submit();
        }, 1000);

    });

This is all good and well, except, if for some reason a front end developer gave a child input of this form an id of ="submit", this breaks, as form.submit() throws a JavaScript error (In Chrome, 'Uncaught TypeError: Property 'submit' of object # is not a function').

You can see an example of that happening here: http://jsfiddle.net/q68ky/ (Here's the behavior if there's no <input id="submit">: http://jsfiddle.net/JpXzL/

Now, I know I can prevent this from binding on forms that have children with an id of 'submit' with jQuery('form').not(:has('#submit')).submit(), and the form will process just fine, but my binding will never fire for those forms.

So, the question: How can I safely bind this jQuery function to all forms, including those with <input id="submit">?

EDIT: Worth noting that this problem doesn't go away if I unbind the submit handler and then trigger a jQuery submit on jQuery(form).


回答1:


The only way I can think of:

(function () {
    var method;

    window.submit = function (theForm) {
        if (!method) {
            method = document.createElement("form").submit;
        }

        method.call(theForm);
    };
}());

Then call submit(theFormYouWantToSubmit).

You can see it in action here: http://jsfiddle.net/q68ky/2/

Edit: To provide some explanation as to what this does....

This method creates a new form element (document.createElement("form")), and stores a reference to the "submit" attribute of it (method = document.createElement("form").submit). Because this is a newly created form element, with no child nodes, we can guarantee that the "submit" attribute is actually the "submit" method we need, rather than a child node with an id/name of "submit".

We then use the call method (part of Function.prototype), which sets the context of the submit method to the form we want to submit, rather than the window object, which is what it would otherwise be on.

The rest of the gubbins in the snippet caches the submit method, so that all of this (albeit small) overhead does not take place every time you want to submit the form, and captures the cached method in a local scope, instead of holding it in the global scope and polluting the global namespace.




回答2:


As this is actually a non-jQuery problem, here is a non-jQuery solution:

HTMLFormElement.prototype.submit.call(form);

DEMO

Reference: HTMLFormElement

Update: Access to the DOM prototypes is only possible in IE8+. (and that is probably the reason why jQuery does not use it).

@Matt's answer instead should work in any browser




回答3:


In addition the problem I identified in my other answer, there is an open jQuery bug exacerbating the issue:

.SUBMIT() CAN FAIL IF SOMETHING HAS ID="SUBMIT"

If an element with an ID of submit exists in a form, .submit() can fail. It's important that this function (in particular) work correctly.

http://bugs.jquery.com/ticket/1414




回答4:


Instead of form.submit();, you need

$(form).submit();

This is because form is just the bare DOM element, while $(form) is the jQuery object. Calling form.submit() is trying to access the submit property of form. Since it doesn't have one, it's defaulting to the old-school behavior of getting the child element whose id is submit (hence the "is not a function" error).




回答5:


The error occurs if a form element's name or id is 'submit'. It looks like it's an issue with jQuery.



来源:https://stackoverflow.com/questions/4465028/how-to-javascript-submit-in-the-presence-of-an-input-id-equal-to-submit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!