除了在怪癖模式下,IE中的InnerHTML / outerHTML不反映复选框状态

我目前正在与一个IE JavaScript / DOM bug(很有趣)进行斗争,这真的让我很难过。 有问题的代码将一些复选框复制到一个表单中,需要保持其检查状态。 问题是,IE(特别是IE8,虽然我也猜测其他人)不想这样做。

我已经将bug本身缩小到一个非常小的测试用例。 基本上,在页面上没有DOCTYPE的情况下工作正常但是当DOCTYPE存在时它们会被破坏。 我本来期待相反的,但谁知道IE。


以下是最简单的测试用例。 对于每个人:在IE中打开页面,切换复选框,然后单击“测试”。

不会产生错误:

   document.getElementById('break').onclick = function() { alert(document.getElementById('broken').outerHTML); };  

链接

产生错误:

     document.getElementById('break').onclick = function() { alert(document.getElementById('broken').outerHTML); };  

链接

错误发生在有效页面上(使用等)以及输入是否在表单内。 在“破碎”的情况下,outerHTML总是反映页面加载时出现的内容(如果我默认选中了输入,那么它总是使用CHECKED警告代码,即使我先取消选中它)。 如果我包装输入并使用innerHTML,事情就会以同样的方式发生。 在实际的网站上我使用jQuery的.clone()方法进行复制; .clone()在内部使用.outerHTML,这就是我缩小范围的方法。


我的问题是:有没有办法自己手动构建新的HTML? 有没有人知道为什么会出现这种情况(除了“IE SUX LOLZ”之外)?

innerHTML和表单属性通常存在问题 。 不只是在IE中((在FF中更糟糕,它永远不会更新innerHTML中的checked属性))…

您可以尝试这个来解决链接问题中的问题:

 document.getElementById('break').onclick = function() { var broken = document.getElementById('broken'); if (broken.checked) broken.setAttribute('checked','checked'); else broken.removeAttribute('checked'); alert(broken.outerHTML); }; 

我最终根据gnarf的答案为.clone()编写了一个包装器:

 $.fn.inputClone = function(events) { this.each(function() { this.attr('value', this.value); if(this.checked) this.setAttribute('checked', 'checked'); else this.removeAttribute('checked'); if(this.selected) this.setAttribute('selected', 'selected'); else this.removeAttribute('selected'); }); return this.clone(events); }; 

它不是非常通用的(例如,如果你试图克隆包含输入的元素它将无法工作),但在这种情况下它似乎可以解决问题。

使用复选框http://www.javascriptkit.com/jsref/checkbox.shtml的DOM等效对象

将它添加到您的DOM表单,不要使用HTML和这种脏的方式。

为清楚起见:

 var domCheckBox=document.getElementById('mycheckboxID'); var domForm=document.getElementById('myformID'); domForm.appendChild(domCheckBox); 

这会将您的复选框添加到表单并保留选中状态(和其他)。