IE 中的 InnerHTML/outerHTML 不反映复选框状态,除非在 quirks 模式下
Posted
技术标签:
【中文标题】IE 中的 InnerHTML/outerHTML 不反映复选框状态,除非在 quirks 模式下【英文标题】:InnerHTML/outerHTML in IE doesn't reflect checkbox state except in quirks mode 【发布时间】:2011-03-07 01:10:25 【问题描述】:我目前正在与一个 IE javascript/DOM 错误作斗争(真有趣),它确实让我感到难过。有问题的代码将一些复选框复制到表单中,并且需要保持其选中状态。问题是,IE(特别是 IE8,虽然我猜其他人也是如此)不想这样做。
我已将错误本身缩小到一个非常小的测试用例。基本上,页面上没有 DOCTYPE 的情况下可以正常工作,但是当存在 DOCTYPE 时它们会被破坏。我本来预计会适得其反,但谁知道 IE。
以下是最简单的测试用例。对于它们中的每一个:在 IE 中打开页面,切换复选框,然后单击“测试”。
不产生错误:
<input type="checkbox" id="broken">
<button id="break">TEST</button>
<script>
document.getElementById('break').onclick = function()
alert(document.getElementById('broken').outerhtml);
;
</script>
Link
产生错误:
<!DOCTYPE html>
<input type="checkbox" id="broken">
<button id="break">TEST</button>
<script>
document.getElementById('break').onclick = function()
alert(document.getElementById('broken').outerHTML);
;
</script>
Link
该错误发生在有效页面上(<html>
、<head>
、<body>
等)以及输入是否在表单内。在“损坏”的情况下,outerHTML 总是反映页面加载时出现的内容(如果我默认检查了输入,那么即使我先取消选中它,它也总是用 CHECKED 警告代码)。如果我包装输入并使用innerHTML,事情会以同样的方式发生。在实际站点上,我使用 jQuery 的 .clone() 方法进行复制; .clone() 在内部使用 .outerHTML,这就是我缩小范围的方式。
我的问题是:有没有办法绕过自己手动构建新的 HTML?有没有人知道为什么会发生这种情况(除了“IE SUX LOLZ”)?
【问题讨论】:
两个版本,无论复选框是否被选中,在Firefox 3.6.3中输出undefined
。在 Chromium 5.0.375.70 和 Opera 10.10 中,这两个版本都会提醒 <input type="checkbox" id="broken">
(所有在 Linux 中运行的浏览器)。
可能相关? -- ***.com/questions/1388893
@blow, @Marcel:Firefox 不支持 .outerHTML。我实际上使用的是 jQuery 的 .clone() 方法,它在 Firefox 中使用 .cloneNode(),所以这不是问题。这是一个专门的 IE 问题。
【参考方案1】:
有problems in general 和innerHTML
和表单属性。不只是在 IE 中((在 FF 中更糟,它永远不会更新 innerHTML 中的已检查属性))...
您可以尝试解决链接问题中的问题:
document.getElementById('break').onclick = function()
var broken = document.getElementById('broken');
if (broken.checked) broken.setAttribute('checked','checked');
else broken.removeAttribute('checked');
alert(broken.outerHTML);
;
【讨论】:
我的测试使用 outerHTML 的唯一原因是 jQuery 在.clone() 中将它用于 IE。由于FF和朋友支持cloneNode(),所以改用它,就没有这个问题了。不过,您的解决方法似乎可以解决问题;我会接受它,除非有人很快发布更简单的东西。谢谢! @Matt – 那是 clone() 中的一个错误(不错的源代码查看器,顺便说一句)。还有一个问题:你为什么需要这个功能?你想用它来达到什么目的? @Marcel:我有一个表单,它有一个“子表单”,它出现在叠加层中。用户正在创建一个事件;基本表单设置事件属性,覆盖层允许邀请用户参加事件。用户完成子表单后,其复选框被复制回基本表单(并隐藏),以便服务器在提交后知道要邀请谁。我不一定需要使用 .clone(),但它在其他任何地方都可以使用,而且非常简单,所以如果它也可以在 IE 中使用就更好了。【参考方案2】:我最终基于gnarf's answer 为 .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);
;
它不是很通用(例如,如果您尝试克隆包含输入的元素,它将不起作用),但对于这种情况,它似乎可以解决问题。
【讨论】:
【参考方案3】:使用复选框http://www.javascriptkit.com/jsref/checkbox.shtml的DOM等效对象
将它添加到您的 DOM 表单中,不要使用 HTML 和这种肮脏的方式。
为了清楚起见:
var domCheckBox=document.getElementById('mycheckboxID');
var domForm=document.getElementById('myformID');
domForm.appendChild(domCheckBox);
这会将您的复选框添加到您的表单并保留选中状态(和其他)。
【讨论】:
这将移动原来的复选框。我需要复制/克隆它。 使用 domCheckBox.cloneNode() 怎么样? jQuery's .clone() method 中的 cmets 对此有这样的说法:“IE 在使用 cloneNode 时复制通过 attachEvent 绑定的事件。在克隆上调用 detachEvent 也会从原始事件中删除事件。为了得到围绕这一点,我们使用 innerHTML。不幸的是,这意味着对 IE 中实际上仅存储为属性的属性的一些修改将不会被复制(例如输入上的 name 属性)。" detachEvent -> cloneNode -> attachEvent 如果该方法有效并且没有 jQuery 的 cmets 中提到的缺点,那么 .clone() 可能应该使用它。我现在没有时间想出一整套测试,但如果有人这样做,应该是submitted in a patch or ticket to jQuery。以上是关于IE 中的 InnerHTML/outerHTML 不反映复选框状态,除非在 quirks 模式下的主要内容,如果未能解决你的问题,请参考以下文章
JS中innerHTMLouterHTMLinnerText outerTextvalue的区别与联系?jQuery中的text()html()和val() ?
JS中innerHTMLouterHTMLinnerText outerTextvalue的区别与联系? jQuery中的text()html()和val()
JS中innerHTMLouterHTMLinnerText outerTextvalue的区别与联系?jQuery中的text()html()和val()