需求:多個 `
<div class="radio-wrap"><input type="radio" name="group" value="1"><span>選項 1</span></div>
<div class="radio-wrap"><input type="radio" name="group" value="2"><span>選項 2</span></div>
<div class="radio-wrap"><input type="radio" name="group" value="3"><span>選項 3</span></div>
.radio-wrap input[type="radio"] { display: none; }
.radio-wrap { cursor: pointer; padding: 10px; border: 1px solid #ddd; margin: 5px; display: inline-block; }
.radio-wrap.selected { border-color: #007bff; background: #e7f1ff; }
.radio-wrap::before { content: ""; display: inline-block; width: 16px; height: 16px; border: 2px solid #999; border-radius: 50%; margin-right: 8px; vertical-align: middle; }
.radio-wrap.selected::before { background: #007bff; border-color: #007bff; box-shadow: inset 0 0 0 3px white; }
document.addEventListener('click', e => {
const wrap = e.target.closest('.radio-wrap');
if (!wrap) return;
const radio = wrap.querySelector('input[type="radio"]');
if (!radio) return;
// 同 name 群組只能單選
const name = radio.name;
document.querySelectorAll(`input[type="radio"][name="${name}"]`).forEach(r => {
r.checked = (r === radio);
r.closest('.radio-wrap').classList.toggle('selected', r === radio);
});
});
name 自動互斥,無需手動取消其他。.selected` 控制自訂圖案,JS 僅切換類別。$('.radio-wrap').click(function() {
const $radio = $(this).find('input[type="radio"]');
$radio.prop('checked', true).trigger('change'); // 觸發 change 事件
});
$('input[type="radio"]').change(function() {
$('.radio-wrap').removeClass('selected')
.has('input[type="radio"]:checked').addClass('selected');
});
核心心法:讓瀏覽器原生 radio 處理互斥邏輯,JS 只負責同步視覺狀態,代碼最少、相容性最好、無障礙合規。