【问题标题】:Submit a function programmatically even if a field is named "submit"以编程方式提交函数,即使字段名为“提交”
【发布时间】:2014-04-10 01:56:23
【问题描述】:

我需要编写 总是 提交表单的 Javascript 代码。我必须提交的第一个表单如下所示:

<form action="http://www.example.com/test">
  <input type="text" name="name">
  <input type="submit" value="Send data" name="submit">
</form>

(假设formNodedocument.getElementsByTagName('form')[0]

所以,formNode.submit() 不起作用,因为“提交”基本上是由“发送数据”按钮 (!) 完成的。

然后我认为我应该使用表单的操作(有人也可以使用action 作为名称!)。

然后我考虑专注于我能找到的第一个输入字段,并模拟 ENTER 按键。但是,我最初的测试没有奏效,并决定在做我通常做的事情之前在这里问一下(把头撞在墙上几个小时)。

那么:什么是提交任何表单无论是如何制作的,不管字段名称是什么脑残名称等,有什么好的、可靠的方法?

或者,也许:我如何可靠地获取表单的 submit() 函数,而不考虑给定相同名称的字段,以便我可以提交东西?

【问题讨论】:

  • 我无法控制字段的名称。
  • 它可以检查 form.submit 属性以及它是否是一个元素(比如有一个 tagName 属性和一个 submit 的 name 属性) ,创建表单的浅表克隆并复制所有控件并将 submit 控件重命名为其他名称,然后再将其附加到新表单。还将所有控制值设置为其原始值的当前值,然后提交该表单。这可能不是一个通用的解决方案,但在某些情况下可能有效。
  • @RobG 哎哟,这很痛!我刚刚找到了一个可能的方式:form.__proto__.submit.call( form );。是的,它只适用于带有 proto 的浏览器,但它看起来可靠吗?
  • 嗯,这可能是“可靠的”,除了 __proto__ 属性不是标准的,不是所有正在使用的浏览器都支持,也不是所有浏览器都使用原型继承模型,所以没有 Form.prototype来参考。此外,宿主对象可能不一定支持这样的内置方法。我已经发布了一个可能有更好解决方案的答案。
  • — 似乎通过原型调用 submit 不会发送提交事件,至少在 IE 9 中,因此不会调用任何提交侦听器(例如表单验证)。

标签: javascript html forms submit


【解决方案1】:

一种方法是首先测试 form.submit 是否是提交按钮,如果是,则以编程方式单击它:

// Probably need better testing for whether it's a button or input or whatever
// this is just a proof of concept
if (form.submit && typeof form.submit.tagName == 'string' && form.submit.click) {
  form.submit.click();

} else {
  form.submit();
}

这似乎至少在 IE 中有效,但是您需要进行广泛的测试以确定是否支持其他浏览器。您可能需要在按钮上调度 click 事件(使用 IE 和 W3C 模型来调度事件),或者对不支持 click 方法的那些使用其他方法。

另一种方法是添加提交按钮并单击它:

<form id="f0">
  <input name="foo" value="foo">
  <input type="submit" name="submit">
</form>

<button onclick="
  var form = document.forms.f0;
  var button = document.createElement('input');
  button.type = 'submit';
  button.value = 'submit button';
  form.appendChild(button);
  button.click();
">Add submit button and click it</button>

用户应该永远不会看到按钮,因为浏览器通常不会在功能完成之前更新 UI。到那时应该已经提交了表单,所以再次没有 UI 更新。

这也应该会导致发送提交事件,因此应该调用提交侦听器。最好为按钮提供 display:none 样式,以防提交被取消——您不希望按钮出现。

如果已经添加了额外的按钮,还需要检查它。

【讨论】:

    【解决方案2】:

    不要使用name="submit"。因为这只会覆盖表单的.submit() 方法,因为您可以通过名称引用表单的字段(DOM 元素)。这是你的问题的原因。如果您需要命名提交按钮,请使用除Object.getOwnPropertyNames(document.forms[0]) 列表下的名称之外的其他名称(这些名称均已使用/保留)。

    如果您的示例采用以下形式:

    <form action="http://www.example.com/test">
        <input type="text" name="inputname">
        <input type="submit" value="Send data" name="submitbutton">
    </form>
    

    然后您可以按预期使用formNode.submit() 提交您的表单。您可以分别使用formNode.inputnameformNode.submitbutton 引用文本框并提交按钮的DOM 元素。检查您的控制台日志以查看此内容。 :)

    【讨论】:

    • 我无法控制表单的内容。那就是问题所在。我需要总是有效的东西——即使有一个具有该名称的属性也可以访问提交方法。
    • 我指的是实际使用的名称。如果你把它命名为别的。然后使用document.getElementsByTagName('form')[0].submit() 将按原计划提交该表单。
    • 如果您尝试从表单的 POST 请求中捕获值“发送数据”,那么您将看到 submit="Send data" 已经在接收端,而没有将 name 归因于提交按钮.
    • 我真的,真的,真的无法控制&lt;input type="submit" value="Send data" name="submit"&gt;。我真的,真的不能改变表格本身。
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2018-06-13
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多