【问题标题】:Form elements with a name attribute that is the same as a form-property, shadow/override the native form-property. Is there a workaround?具有与表单属性相同的名称属性的表单元素,隐藏/覆盖本机表单属性。有解决方法吗?
【发布时间】:2014-04-08 16:17:48
【问题描述】:

如果表单中的input 元素与表单的原生属性同名,则该元素将隐藏原生属性。

例如,考虑以下形式:

<form id = "test">
    <input name="tagName" type="text" />
    <input name="nodeName" type="text" />
</form>

form 元素的tagNamenodeName 通常都返回FORM。但在这种情况下,下面的代码:

var f = document.getElementById("test");

console.log(f.tagName);
console.log(f.nodeName);
console.log(f["tagName"]);
console.log(f["nodeName"]);

显示:

<input name=​"tagName" type=​"text">​ 
<input name=​"nodeName" type=​"text">​
<input name=​"tagName" type=​"text">​
<input name=​"nodeName" type=​"text">​

是否有解决方法(重命名字段除外)? getAttribute 适用于 nameactionmethod 等属性,但不适用于 nodeNametagName 等属性。

Fiddle here.

更有趣的事情:在this fiddle 我只是在记录表单本身。通常这会显示 HTML,但现在 Chrome 只记录 TypeError

【问题讨论】:

  • 嗯...f.getAttribute('nodeName') 工作正常吗?还是不支持跨浏览器(我在 Chrome 上测试过)?
  • 我想不出办法。
  • @Colandus 真的吗?在 chrome 中,它为我返回 null
  • jsfiddle.net/R8x3W/1 是的,它在 Chrome 上显示 10
  • @Colandus 哦,那不是我想要的。我希望它按原样返回FORM。我不是在谈论属性,我是在谈论表单对象上的属性。

标签: javascript html forms


【解决方案1】:

我想不出直接在&lt;form&gt; 元素上执行此操作的方法。我能想到的最好的方法是创建一个没有任何后代的元素的克隆并检查克隆的属性:

var clonedForm = f.cloneNode(false);
console.log(clonedForm.nodeName);

更新

正如 cmets 中所指出的,这具有相同的问题,因为 cloneNode 可以像 nodeName 一样被覆盖。由于表单的任何属性都可以被覆盖,因此这是一个难以克服的问题。

【讨论】:

  • 效果很好,蒂姆!太奇怪了,有这样的限制。即使您有与原生属性同名的表单元素,也应该有一种访问原生属性的方法。
  • @VivinPaliath:这可以追溯到 Netscape 2 和 3 的前 DOM 时代,那时表单元素几乎是唯一可以编写脚本的东西。浏览器开发人员在决定 JavaScript 如何访问事物时更加漫不经心,因此像这样的怪事和元素可以通过其 ID 作为全局变量的属性进行访问(我认为你可以感谢微软)。
  • 是的,我记得(在 IE6 的黑暗时期曾在网页上工作过)。我没有意识到它最终会遮蔽本机属性,我认为还有其他方法可以访问它。今天有人提醒我“通过他们的 ID 的全局变量”......我忘记了。
  • cloneNode 可以以与 nodeName 完全相同的方式被覆盖。此解决方案不适用于一般情况。
  • 注意:您可以检测到这种情况,但除了编写自定义解析器之外没有其他解决方法。请参阅 _isClobbered github.com/cure53/DOMPurify/blob/master/src/purify.js
【解决方案2】:

编辑:我更了解您想要什么。每个form 元素都有一个名为elements 的属性:

var f = document.getElementById("test");
f.elements.tagName
f.elements.nodeName

编辑 2:如果您希望 f.tagName 在这种情况下返回 "FORM",则不能。您已经覆盖了本机属性。如果您确实需要使用“tagName”作为名称,那么也许您可以使用括号或点符号:

HTML: <input type="text" name="element.tagName">
JS: f.elements["element.tagName"]

HTML: <input type="text" name="element[tagName]">
JS: f.elements["element[tagName]"]

编辑 3:一些浏览器有一个名为 localName 的 DOM 属性,只要您没有名称为“localName”的表单字段,它就可以工作。

基本上,不要使用原生 DOM 属性名称作为表单字段名称属性的值。

【讨论】:

  • 他要的是children属性!不形成自己
  • 这仅适用于methodaction 等属性。它不适用于 tagName 等原生属性;在这种情况下,它会返回 null
  • 我认为你有它倒退。 :) 当我访问f.tagName 时,我想返回FORM,而不是输入元素。执行f.elements.tagName 会返回相同的结果(input 元素)。
  • 谢谢格雷格。问题是我无法控制表单。这与我编写的库的代码有关。在某些情况下,我会检查元素的标记名以查看其类型,在这种情况下,我无法做到这一点。所以我想知道是否有解决方法。
  • 没有解决方法。您必须更改名称属性。
猜你喜欢
  • 2019-04-23
  • 1970-01-01
  • 2013-01-31
  • 2011-01-13
  • 2016-06-02
  • 2019-11-30
  • 2018-08-05
  • 2019-02-25
  • 2015-04-09
相关资源
最近更新 更多