小心Dom元素的name属性

对于一个用 JavaScript 获取到一个 DOM 节点的后,在说到属性的时候需要注意的是指 DOM 节点的属性还是 JavaScript 对象的属性(或说字段名)。一般来说,前者用 getAttribute/setAttribute 来访问/修改,后者用 object.field 来访问。然而,对于像 id、className 这些却属于 DOM 节点的 Attribute 范围。在说到 name 属性的时候,就更加复杂一点了,因为牵涉到 IE 的特殊处理。

当想用 setAttribute 给一个已有的(或动态创建的) DOM 元素设置 name 属性时,将会发现 IE6/7 跟 form 及相关表单元素合不来,根本就没有设置成功。

微软的文档,在 IE6/7 中,form 表单时的 name 属性是有些特殊的,用来标志提交的数据,跟平常的用途有些不一样。

When you submit a form, use the name property to bind the value of the control. The name is not the value displayed for the input type=button, input type=reset, and input type=submit input types. The internally stored value is submitted with the form, not the displayed value.

综合标准的做法,可以得到这样一个创建带 name 属性的 DOM 节点的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var createNamedElement = function (type, name) {
    var element = null;
    // Try the IE way; this fails on standards-compliant browsers
    try {
        element = document.createElement('<'+type+' name="'+name+'">');
    } catch (e) {
    }
    if (!element || element.nodeName != type.toUpperCase()) {
        // Non-IE browser; use canonical method to create named element
        element = document.createElement(type);
        element.name = name;
    }
    return element;
};

// create an input element with name
var aInput = createNamedElement('input', 'aInp');

如果只是需要创建一个节点而不需要后续引用继续修改的话,我会更加倾向于直接用 innerHTML 来创建,比如:

1
someNode.innerHTML = someNode.innerHTML + '<input type="button" name="aButton" value="This is a button" />';

需要注意的是,对于 name 属性,在表单类中 attribute 和 field 是相同的,但在非表单中, attribute 中的才是 HTML 代码中可见的 name 属性。

See more demo


References:

  1. Weird behaviour of iframe `name` attribute set by jQuery in IE
  2. NAME Attribute | name Property
  3. Setting the “name” attribute in Internet Explorer

《小心Dom元素的name属性》有5个想法

    1. @小年 ➡ 有时候有东西好写,但到了临写时,一减再减,最终就没东西好写了

评论已关闭。