为什么jQuery没有为Node的属性赋值?

时间:2014-07-07 17:04:41

标签: javascript jquery dom

给出以下HTML:

<form action="#" method="post">
    <fieldset>
        <legend>Text input:</legend>
        <label>Label for the <code>input</code> element:
            <input type="text" id="textDemo" value="..." />
        </label>
    </fieldset>
    <fieldset>
        <legend>Radio Inputs</legend>
        <label>Male
            <input type="radio" name="gender" id="genderM" />
        </label>
        <label>Female
            <input type="radio" name="gender" id="genderF" />
        </label>
    </fieldset>
</form>

为什么这个jQuery没有正确地分配或改变节点的属性:

// using 'css()' shows the correct element was selected, but the
// value is not being set:
$('#textDemo').css('color','red').value = 'The new jQuery-changed value';

console.log($('#textDemo').value); // >> undefined

JS Fiddle reproduction of this issue

同样,以下不起作用:

// finding the parent element, and setting its color to red
// verifies that we've started from the correct element
// ('end()' takes us back to the initial selector):
$('#genderF').parent().css('color','red').end().checked = true;

console.log($('#genderF').checked); // >> undefined

JS Fiddle reproduction of this issue

为什么jQuery无法正确访问/设置Node的属性(即使正确选择了相关节点)?

1 个答案:

答案 0 :(得分:0)

以下语法的问题:

$('#textDemo').css('color','red').value = 'The new jQuery-changed value';

当选择了正确的元素时,$('#textDemo')元素被包装在jQuery对象中,而.value包装的 DOM节点本身的属性,并且这两者不能连在一起,也不可互换。

为了实现上述代码的目的,我们可以使用jQuery方法:

$('#textDemo').val('The new jQuery-changed value');

JS Fiddle demo

或者:

// here we use 'prop()' to set the property of the elements contained
// within the jQuery object:
$('#textDemo').prop('value', 'The new jQuery-changed value');

JS Fiddle demo

或者,我们可以使用jQuery进行选择,然后“检索”&#39;来自jQuery对象的DOM节点:

// because a jQuery object (sort of) imitates an array, it's possible
// to retrieve a specific element from the collection(1), here we're
// retrieving the zeroeth element (which is the only element),
// effectively 'unwrapping'(2) it from the jQuery object. This 'unwrapped'
// element is the DOM node, and therefore has DOM properties (and methods):
$('#textDemo')[0].value = 'The new jQuery-to-DOM changed value';

JS Fiddle demo

或者:

// similar to the above approach, but here we use a jQuery method
// to retrieve the same, zeroeth, element; 'get()' returns the DOM node
// from the supplied index(1), and therefore has access to the properties
// of, well, itself:
$('#textDemo').get(0).value = 'The new jQuery-to-DOM changed value';

JS Fiddle demo

同样类型的方法也可以用于无线电<input>元素,除了checked是属性所以,要使用jQuery, only 选项是使用prop()(如上所述,但使用不同的属性名称和值):

// 'checked' is a Boolean attribute in HTML it's presence means that
// the relevant radio-input (also true of checkbox-inputs) will be checked
// (though it can become unchecked if another radio-input later in the
// same group is subsequently checked; and under XHTML it seems that the 'checked'
// attribute must have the value of 'checked' to be considered valid):
$('#genderF').prop('checked', true);

JS Fiddle demo

对于XHTML而言:

$('#genderF').prop('checked', 'checked');

JS Fiddle demo

这种方法也适用于HTML(但在HTML 任何 value下,包括没有值,可能同样有效(例如.prop('checked','fish fingers and custard'))。

当然,如上所述,我们也可以使用get()

$('#genderF').get(0).checked = true;

JS Fiddle demo

索引符号:

$('#genderF')[0].checked = true;

JS Fiddle demo

顺便提一下,对于布尔属性(checkedselecteddisabled和其他一些其他属性),使用适当命名的removeProp()删除该属性作为取消设置checked属性的方法:

$('#genderF').prop('checked', true); // setting
$('#genderF').removeProp('checked'); // removing
$('#genderF').prop('checked', true); // this depends on the version of jQuery

在jQuery的1.x分支(包括1.11版本)中,这不起作用,因为我们完全删除了checked属性JS Fiddle demo

然而,在2.x分支中,似乎已经修复,removeProp()不再阻止节点具有特定属性(3):JS Fiddle demo

无论这种明显的变化(至少在Chrome 35 / Windows 8.1中),文档(参见下面的参考资料)仍然明确指出:

  

注意:请勿使用此方法删除已选中,已禁用或已选中的本机属性。这将完全删除属性,一旦删除,就不能再次添加到元素。使用.prop()将这些属性设置为false。

考虑到这一点,对于原生布尔属性,最好再次使用prop()

$('#genderF').prop('checked', true); // setting
$('#genderF').prop('checked', false); // removing

JS Fiddle demo

顺便说一句,prop()是在jQuery 1.6中引入的,之前attr()可以以相同的方式使用(因为jQuery补偿了属性和属性之间的差异),例如:

$('#textDemo').attr('value', 'The new jQuery-changed value');

JS Fiddle demo

$('#genderF').attr('checked', true);

JS Fiddle demo

(注意使用jQuery 1.5.2,在之前的两个演示中)。

虽然文档确实注明:

在特定情况下,属性和属性之间的差异非常重要。 在jQuery 1.6 之前,.attr()方法在检索某些属性时有时会考虑属性值,这可能会导致行为不一致。 从jQuery 1.6 开始,.prop()方法提供了一种显式检索属性值的方法,而.attr()则检索属性。

最后,值得指出反面为真,DOM节点无法访问任何jQuery方法;甚至那些曾经在jQuery对象中的DOM节点也只是&#39; DOM节点。虽然我无法想到可以说明这一点的任何常见例子。

参考文献:


  1. 但是,您必须事先(通过某些方式超出此问题的范围)知道您想要检索的特定元素的索引&#39;
  2. 我知道我的......类比(?)相对比较糟糕。我只能道歉,对不起。
  3. 我非常非常,非常很高兴我决定检查一下,因为我不知道它在2.x以下不再是一件事。那时我看起来真的很蠢。