【问题标题】:IE is not submitting dynamically added form elementsIE 未提交动态添加的表单元素
【发布时间】:2023-04-09 18:08:01
【问题描述】:

我编写了一些 JavaScript 来允许编辑 HTML 表单中的项目列表,包括添加和删除项目。让它在 Firefox 中工作。在 Internet Explorer 中尝试时,我发现任何添加的项目都没有与表单一起提交。

长话短说...大量的简化、调试,找出了触发 IE 忽略新表单输入的行。这样行为问题就解决了。

但现在我必须问:为什么?这是 IE 的错误吗?

这里是简化的代码:

<html>
<head>
    <title>Test</title>
    <script type="text/javascript">
        function add() {
            div = document.getElementById("mylist");

            // *** Adding text here works perfectly fine. ***
            div.innerHTML += " ";

            e = document.createElement("input");
            e.setAttribute("type", "text");
            e.setAttribute("name", "field3");
            e.setAttribute("value", "--NEWVALUE--");
            div.appendChild(e);

            // *** Adding text here works perfectly fine in Firefox, but for
            //     Internet Explorer it causes field3 to not be submitted. ***
            //div.innerHTML += " ";
        }
    </script>
</head>
<body>
    <form action="" method="get">
        <div id="mylist">
            <input type="text" name="field1" value="value1" />
            <input type="text" name="field2" value="value2" />
        </div>
        <a href="javascript:" onclick="add()" />Add</a>
        <input type="submit" value="Submit" />
    </form>
</body>
</html>

要试一试,显而易见:在 IE 中加载,单击添加,单击提交,查看地址栏中的内容。如果你取消注释add() 中的最后一行,IE 会突然停止报告field3。它在 Firefox 中都可以正常工作。

有什么想法吗?好奇的心想知道。 (如果需要,我将如何以便携的方式在其中添加文本,让 IE 很高兴?)

【问题讨论】:

    标签: javascript internet-explorer webforms dhtml


    【解决方案1】:

    IE 对在运行时更改某些内置属性非常挑剔。例如,输入元素的名称在设置时不能更改。

    如果我是你,我会尝试两件事:

    1. 尝试显式设置name、type 和value 属性,而不是使用value:

      e.name = "text";

    2. 如果这不起作用,您可能必须将所有这些属性包含在 document.createElement() 调用中:

      var e = document.createElement("&lt;input type='text' name='field'&gt;");

      这实际上可能会在某些浏览器中引发异常。所以最好的跨浏览器方式是:

    .

    var e;
      try {
        e = document.createElement("<input type='text' name='field'>");
      } catch (ex) {
        e = document.createElement("input");
        e.type = 'text';
        e.name = 'field';
      }
      e.value = 'value';
    

    【讨论】:

    • +1 避免 setAttribute。 -1 在 createElement-with-markup 调用上,这是一个非常丑陋的 IE-only hack。
    • 我同意这是一个 hack - 这就是为什么我建议发帖者先尝试设置属性。如果这不起作用,我看不出有其他方法可以实现他想要的。
    【解决方案2】:

    这是一个 IE 错误吗?

    好像是这样。当您通过 DOM 方法创建 元素时,IE 并没有完全选择“name”属性。元素确实提交了,但如果你尝试获取元素的“innerHTML”表示,它就会神秘地消失。如果您通过直接写入 innerHTML 来创建元素,则不会发生这种情况。

    此外,如果您使用 DOM 0 级表单导航方法,例如“myform.elements.x.value”,则通过“元素”数组访问可能无法正常工作(类似于某些人错误使用的直接“myform.x”访问) .无论如何,这些天你可能更喜欢 getElementById()。

    所以要么使用innerHTML 要么使用DOM方法;创建表单域时最好不要混合它们。

    这是documented (see ‘Remarks’),终于在IE8中修复了。

    无论如何,永远不要这样做:

    div.innerHTML+= '...';

    这只是语法糖:

    div.innerHTML= div.innerHTML+'...';

    换句话说,它必须序列化元素的整个子 HTML 内容,然后进行字符串连接,然后将新字符串重新解析回元素,丢弃所有原始内容。这意味着您会丢失任何无法序列化的内容:以及 IE 的虚假半创建“名称”属性,这也意味着您附加到每个子元素的任何 JavaScript 事件处理程序、DOM 侦听器或其他自定义属性。此外,不必要的序列化/解析周期很慢。

    【讨论】:

      【解决方案3】:

      感谢 bobince 和 levik 的回答。使用这些以及更多的实验,这是我的结论:

      1. 是的,这是一个 IE 错误。

      2. IE 8 根据Microsoft 修复了该错误:“Internet Explorer 8 及更高版本可以在运行时对使用 createElement 方法动态创建的元素设置 NAME 属性。”

      3. 错误是这样的:仅调用e.setAttribute("name", "field3") kind-of 设置名称。如果元素没有发生任何其他事情,它将起作用,但如果请求序列化,则不会序列化名称。所以当我说innerHTML += " " 强制进行序列化时,它丢失了名称,因此在反序列化时没有恢复。没有名字,没有包含在表单提交中。

      4. 解决方法 #1:e = document.createElement("&lt;input name='field3' /&gt;") 可以工作,即使面对序列化也是如此。

      5. 解决方法 #2:我可以像这样附加一个文本元素,而不是使用 innerHTML += 添加文本:div.appendChild(document.createTextNode(" "));。我想一定有更好的添加文本的方法,现在我知道了:-)。

      干杯,
      --jsf

      【讨论】:

      • 我正在通过 document.createElement 添加多个元素,每个元素都有多个属性。一个属性是 ID。我在同一页面上还有一个 javascipt 函数,它通过 document.getElementById(ID) 和 innerHTML 获取 ID。我将如何根据动态创建的元素的 ID 引用或获取正确的元素?我在 Firefox 中使用 IE 8..works :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多