jquery.html()与表单的奇怪行为

时间:2013-01-21 13:57:17

标签: javascript jquery html

我有以下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"的值不会被返回。

5 个答案:

答案 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设置为新值。

  
     

[“默认/开启”和“文件名”模式]

发现差异?现在,我们来看看statestype attribute。实际上,如果我们查看簿记详细信息部分,我们可以注意到hidden state

  

value IDL属性适用于此元素并处于模式默认

- 在所有其他(文本)状态下,模式为“值”。


TL; DR:

(仅)在<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");