jQuery 1.6+ 版本:操作 `checked`、`selected`、`disabled`、`readonly` 等**布爾屬性**必須用 `.prop()`,禁用 `.attr()`。**
| 版本 | .attr('checked', ...) 行為 | .prop('checked', ...) 行為 | 建議 |
|---|---|---|---|
| 1.5- | 修改 DOM 屬性 (initial state),視覺勾選但 `elem.checked` 可能為 false | 不存在 | 僅用 attr |
| 1.6 - 1.8 | 修改屬性,**不同步 property**,導致視覺/邏輯不一致 | 修改 property (實時狀態),正確 | **遷移到 prop** |
| 1.9+ | 僅修改屬性 (HTML attribute),**不影響 property**,勾選狀態不變 | 修改 property,**唯一正確方式** | **強制用 prop** |
`.attr()` 操作 Attribute,`.prop()` 操作 Property。**用戶交互只改變 Property**,所以必須用 `.prop()` 同步狀態。
// ✅ 正確
$('input[name="items"]').prop('checked', true); // 全選
$('input[name="items"]').prop('checked', false); // 全不選
// ❌ 錯誤 (jQuery 1.9+ 完全無效)
$('input[name="items"]').attr('checked', 'checked');
$('input[name="items"]').attr('checked', true);
$('input[name="items"]').removeAttr('checked'); // 1.9+ 可用,但語義不清
// ✅ 正確
var isChecked = $('#chk').prop('checked'); // true/false
var isChecked = $('#chk').is(':checked'); // 同義,鏈式調用友好
// ❌ 不推薦
var isChecked = $('#chk').attr('checked'); // 返回 "checked" 或 undefined,非布爾
$('#checkAll').on('change', function() {
// this 是原生 DOM,this.checked 是 property
$('input[name="items"]').prop('checked', this.checked);
});
$('#getValues').on('click', function() {
var vals = $('input[name="items"]:checked').map(function() {
return this.value; // 原生 DOM value
}).get(); // 轉為原生數組
console.log(vals); // ["val1", "val3"]
});
| 場景 | 錯誤寫法 | 正確寫法 |
|---|---|---|
| 動態生成 checkbox 後預選 | `$('')` 或 `.attr('checked', true)` | `$('').prop('checked', true)` |
| 判斷是否勾選做業務邏輯 | `if ($('#chk').attr('checked'))` | `if ($('#chk').prop('checked'))` 或 `$('#chk').is(':checked')` |
| 表單序列化提交 | 手動拼接 | `$('#form').serialize()` 自動包含勾選的 checkbox value |
| Zepto.js | 無 `.prop()` (早期版本) | Zepto 1.2+ 已支持 `.prop()`,或用 `.attr('checked', 'checked')` 兼容 |
**`checked` 是 Property,不是 Attribute**。jQuery 1.6+ 引入 `.prop()` 正是為了解決這一語義混淆。**養成習慣:布爾屬性 (`checked`/`selected`/`disabled`/`readonly`/`hidden`) 全程用 `.prop()`**,代碼才在所有版本穩定、語義清晰、邏輯正確。