2008年09月23日
[jQuery] IE 上的 clone 陷阱
前陣子在處理客戶更改版面的需求時,為了偷懶,結果發現了一個 jQuery 在 IE 上 clone 元素的問題。
先簡單說明一下例子:

如上圖所示,我希望在按下「複製」按鈕後,藍色區塊中的 checkbox 被勾選的項目會被複製到紅色區塊中:

這裡我簡單的使用 jQuery 的 clone 方法來完成它,原始程式如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>測試</title>
<script type="text/javascript" src="jquery/1.2.6.js"></script>
<script type="text/javascript">
$(function () {
$('#copy').click(function () {
$('#target').html('').append($('input.test:checked').clone());
});
});
</script>
</head>
<body>
<div id="source" style="border:1px solid #33F; padding: 20px; width: 200px;">
<input type="checkbox" name="test[]" class="test" value="1" />
<input type="checkbox" name="test[]" class="test" value="2" />
<input type="checkbox" name="test[]" class="test" value="3" />
<input type="checkbox" name="test[]" class="test" value="4" />
</div>
<br />
<div id="target" style="border:1px solid #F33; padding: 20px; width: 200px;">
</div>
<br />
<input type="button" value="複製" id="copy" />
</body>
</html>
在非 IE 的瀏覽器上, jQuery 的 clone 方法可以正確的把已勾選的 checkbox 的 checked 狀態複製下來,但在 IE 上卻不行,如下圖:

所以這裡只好針對 IE 再進行一次特別的處理:
$(function () {
$('#copy').click(function () {
var $checkedValues = $('input.test:checked').clone();
if ($.browser.msie) {
$checkedValues.attr('checked', true);
}
$('#target').html('').append($checkedValues);
});
});
原理很簡單,就是遇到 IE 時,再將複製下來的 checkbox 的 checked 屬性設為 true 即可。
補充:IE6 的逆襲
不過上述程式在 IE6 又會出現問題了,在 IE6 上執行時,會發現 checked 屬性無法正常被設為 true 。
雖然沒有深入去研究,但我猜想是 IE6 在處理 DOM 時的問題,因此我祭出了 setTimeout 大法:
$(function () {
$('#copy').click(function () {
var $checkedValues = $('input.test:checked').clone();
if ($.browser.msie) {
setTimeout(function () { $checkedValues.attr('checked', true); }, 0);
}
$('#target').html('').append($checkedValues);
setTimeout(function () {
// 其他可能會對處理到 checkbox 的動作
}, 0);
});
});
這裡 setTimeout 可以確保程式在 DOM 完全更新後,再執行下一步的動作。
