2

我以为我理解了整个 prop 与 attr 的关系,但我遇到了一个让我质疑这种理解的案例。

我正在为生成表格的主干视图编写测试,我的测试基本上执行了以下操作:

// assert that $table.find('input[value="foo"]').length == 2
$table.find('input[value="foo"]:first').val('bar');
// assert that $table.find('input[value="foo"]').length == 1

奇怪的是,第二个断言失败了。经过大量的头撞墙时间后,我终于尝试了:

// assert that $table.find('input[value="foo"]').length == 2
$table.find('input[value="foo"]:first').attr('value', 'bar');
// assert that $table.find('input[value="foo"]').length == 1

瞧,我的测试通过了。

现在,我希望我可以发布所有相关代码的小提琴,但是太多了(表 View 单独是 685 行),但我正在寻找一般理解类型的答案,而不是特定的“修复 X ​​in你的代码”。我想了解的是,为什么会有这样的情况:

$table.find('input[value="foo"]:first').val('bar');

什么都不做,同时:

$table.find('input[value="foo"]:first').attr('value', 'bar');

按预期工作?

PS我不应该说.val('bar')什么都没做;如果我.val()后来做了,它会显示值已经改变......但是如果我检查了实际元素,或者使用了新的选择器,或者类似的东西,很明显它val并没有真正改变任何东西。这只会让我更加困惑。

4

2 回答 2

5

一个简单的例子应该能说明一些事情。假设我们从这个 HTML 开始:

<input id="t1">
<input id="t2">

然后我们执行这个 JavaScript:

$('#t1').val('pancakes');
$('#t2').attr('value', 'pancakes');

从视觉上看,两个<input>s 看起来都一样,他们都会说pancakes. 但是,如果您查看底层 DOM 元素,您会看到:

<input id="t1">
<input id="t2" value="pancakes">

因此,使用val或多或少会模拟您使用鼠标和键盘摆弄表单元素;这些都不会改变底层元素。attr但是,调用会更改底层元素并#t2最终得到一个真正完整的value属性(如果您想知道原因,请参阅adeneo 的答案)。

为什么差异很重要?我注意到您正在使用属性选择器,因此值得快速浏览一下:

$('input[value=pancakes]').length

那将是1因为只有一个<input>s 甚至具有value属性,更不用说value具有我们正在寻找的值的 a 了。

问题不在于:

$table.find('input[value="foo"]:first').val('bar');

不做任何事情,问题是它不做任何属性选择器可以看到的事情,因为val根本没有对属性做任何事情。


上面的简单demo,打开你的控制台看看有趣的东西:http: //jsfiddle.net/ambiguous/PNtKk/

于 2013-03-20T02:10:21.777 回答
3

val()直接更改属性,它不会显示在控制台中,而attr()使用本机更改属性setAttribute()以便显示在控制台中。

val()将是设置元素值的正确方法。

于 2013-03-20T01:17:42.297 回答