我有以下html:
<div class="copy_me_text">
<div>
<input type="text" name="name" />
<input type="hidden" name="id" />
</div>
</div>
<div class="copy_me_hidden">
<div>
<input type="hidden" name="name" />
<input type="hidden" name="id" />
</div>
</div>
关注js代码:
var $cloned_text = $('.copy_me_text').clone();
$cloned_text.find('input[name="name"]').val("SOMETHING");
$cloned_text.find('input[name="id"]').val("SOMETHING");
console.log($cloned_text.html());
var $cloned_hidden = $('.copy_me_hidden').clone();
$cloned_hidden.find('input[name="name"]').val("SOMETHING");
$cloned_hidden.find('input[name="id"]').val("SOMETHING");
console.log($cloned_hidden.html());
输出对我来说很奇怪:
<div>
<input name="name" type="text">
<input value="SOMETHING" name="id" type="hidden">
</div>
<div>
<input value="SOMETHING" name="name" type="hidden">
<input value="SOMETHING" name="id" type="hidden">
</div>
我也创建了jsFiddle example。
这是正确的行为吗?我不明白,为什么在.html()
函数中,input type="text"
的值不会被返回。
答案 0 :(得分:8)
这不是一个奇怪的jQuery行为,它是一个奇怪的DOM效果。 jQuery.val()
除了设置value
元素的<input>
属性之外别无其他。 “属性”是指DOM 属性,而不是节点属性 - 请参阅.prop() vs .attr()了解差异。
返回DOM的.html()
序列化的innerHTML
方法应该只显示元素的属性 - 它们的属性是无关紧要的。这是默认行为,当您希望序列化输入值时,您需要将它们显式设置为属性 - $input.attr("value", $input.prop("value"))
。
那么为什么简单的val()
能够处理隐藏的输入元素呢?原因是HTML规范。有reflecting IDL attributes,其中DOM属性与节点属性耦合,但value
属性不是那些。然而,value IDL attribute具有特殊模式,其中它的反应不同。引用规范:
该属性处于以下模式之一,用于定义其行为:
<强>值强>
获取时,必须返回元素的current value。在设置时,必须将element's value设置为新值,设置元素的脏值[...并执行许多其他操作]。
默认强>
获取时,如果元素具有value attribute,则必须返回该属性的值;否则,它必须返回空字符串。在设置时,必须将元素的value attribute设置为新值。
[“默认/开启”和“文件名”模式]
发现差异?现在,我们来看看states的type attribute。实际上,如果我们查看簿记详细信息部分,我们可以注意到hidden
state,
value
IDL属性适用于此元素并处于模式默认
- 在所有其他(文本)状态下,模式为“值”。
(仅)在<input type="hidden">
个元素上,设置value
DOM属性(input.value = …
,$input.val(…)
,$input.prop("value", …)
)也会设置value
属性并使其可序列化为innerHTML
/ .html()
。
答案 1 :(得分:6)
这肯定看起来像jQuery中的一个错误。您可以使用attr()
函数强制它返回:
$cloned_text.find('input[name="name"]').attr('value', "SOMETHING");
查看更新后的Fiddle
答案 2 :(得分:3)
html()
函数将html赋值返回给元素。在您的情况下,您要为输入文本字段分配值。
试试这个
$cloned_text.find('input[name="name"]').attr('value', "SOMETHING");
答案 3 :(得分:2)
这不是一个jQuery错误。
正如您在jQuery source code for the val
method中看到的那样,他们只是设置value
元素的input
,这与向元素添加新属性不同(在最后,导致value
属性更改。
jQuery源(hooks
在此上下文中为null):
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
this.value = val;
}
所以,为了得到你的东西,你必须使用
为元素添加一个新的val
属性
.attr('value', "SOMETHING");
正如其他人所说。
通过使用.attr
,新属性将添加到元素中,.html
将返回该字符串。
答案 4 :(得分:1)
此问题的一个很好的解决方法是使用attr()
函数而不是val()
。
所以,而不是
$cloned_text.find('input[name="name"]').val("SOMETHING");
写
$cloned_text.find('input[name="name"]').attr("value", "SOMETHING");