|
611 | 611 | // read initial state from store |
612 | 612 | let active = store.get(options.storeKey, 0) === 1; |
613 | 613 | btn.style.borderStyle = active ? 'inset' : 'outset'; |
| 614 | + |
| 615 | + // 如果是开关,且初始为开启状态,尝试更新按钮文本 |
| 616 | + // 注意:这里我们假设 label 格式为 "开XX",开启后变为 "关XX" |
| 617 | + // 或者更通用的做法是,handler 内部会根据 store 状态更新文本, |
| 618 | + // 但这里是初始化,handler 还没执行。 |
| 619 | + // 实际上,makeToggle 生成的 handler 已经处理了点击后的文本更新。 |
| 620 | + // 问题的关键在于:页面刷新加载时,按钮文本是初始传入的 label(通常是"开XX"), |
| 621 | + // 但如果 store 里状态是 1(已开启),按钮应该是"关XX"。 |
| 622 | + |
| 623 | + if (active && label.startsWith('开')) { |
| 624 | + btn.textContent = label.replace('开', '关'); |
| 625 | + } |
| 626 | + |
614 | 627 | // click toggles state, calls handler with (active, btn) |
615 | 628 | btn.addEventListener('click', (e) => { |
616 | 629 | e.stopPropagation(); |
617 | | - active = !active; |
618 | | - btn.style.borderStyle = active ? 'inset' : 'outset'; |
| 630 | + // 注意:这里的 active 变量是闭包内的局部变量, |
| 631 | + // 但 makeToggle 内部也会读取 store。 |
| 632 | + // 为了避免状态不一致,最好重新从 store 读取,或者让 handler 负责更新状态。 |
| 633 | + // 现在的逻辑是:点击 -> active取反 -> 更新样式 -> 调用handler -> handler更新store |
| 634 | + |
| 635 | + // 修正:点击时,active 应该是取反后的值 |
| 636 | + // 但 makeToggle 的逻辑是:读取 store -> 取反 -> 保存 store -> 更新 UI |
| 637 | + // 所以这里我们只需要调用 handler 即可,handler 会处理一切 |
| 638 | + // 不过 handler 需要知道当前按钮元素,以便更新文本 |
| 639 | + |
619 | 640 | try { |
620 | | - handler(active, btn); |
| 641 | + // 传递 btn 给 handler,handler (makeToggle返回的函数) 会处理状态切换和UI更新 |
| 642 | + handler(btn); |
| 643 | + |
| 644 | + // 更新闭包内的 active 状态,以便下次点击逻辑正确(虽然 makeToggle 内部主要依赖 store) |
| 645 | + // 重新读取 store 以确保同步 |
| 646 | + active = store.get(options.storeKey, 0) === 1; |
| 647 | + btn.style.borderStyle = active ? 'inset' : 'outset'; |
621 | 648 | } catch (err) { |
622 | 649 | console.error(err); |
623 | 650 | } |
|
5058 | 5085 | */ |
5059 | 5086 | function makeToggle(id, openLabel, closeLabel, storeKey, onChange) { |
5060 | 5087 | return (activeOrBtn, maybeBtn) => { |
5061 | | - // 兼容两种调用方式: |
5062 | | - // 1) group popup calls handler(active, btn) -> active is boolean, maybeBtn is btn |
5063 | | - // 2) column button calls handler(btn) -> activeOrBtn is btn |
| 5088 | + let btn = null; |
| 5089 | + let isActive = false; |
| 5090 | + |
5064 | 5091 | if (typeof activeOrBtn === 'boolean') { |
5065 | | - const active = activeOrBtn; |
5066 | | - const btn = maybeBtn; |
5067 | | - // save to store |
5068 | | - store.set(storeKey, active ? 1 : 0); |
5069 | | - // update text if btn provided |
5070 | | - if (btn) btn.innerText = active ? closeLabel : openLabel; |
5071 | | - |
5072 | | - if (onChange) { |
5073 | | - onChange(active); |
5074 | | - } else { |
5075 | | - console.log(`[${openLabel}] 状态:${active ? '已开启' : '已关闭'}`); |
5076 | | - } |
| 5092 | + isActive = activeOrBtn; |
| 5093 | + btn = maybeBtn; |
5077 | 5094 | } else { |
5078 | | - // called as handler(btn) from column (rare for these toggles) - just toggle state |
5079 | | - const btn = activeOrBtn; |
5080 | | - const cur = store.get(storeKey, 0) === 1; |
5081 | | - const will = !cur; |
5082 | | - store.set(storeKey, will ? 1 : 0); |
5083 | | - if (btn) { |
5084 | | - btn.innerText = will ? closeLabel : openLabel; |
5085 | | - btn.style.borderStyle = will ? 'inset' : 'outset'; |
5086 | | - } |
| 5095 | + btn = activeOrBtn; |
| 5096 | + // 修正:这里不再反转状态! |
| 5097 | + // 因为 GroupPopup 的 click handler 并没有改变 store, |
| 5098 | + // 它只是把 btn 传给了我们。 |
| 5099 | + // 我们的职责是:读取当前 store -> 取反 -> 保存 -> 更新 UI。 |
5087 | 5100 |
|
5088 | | - if (onChange) { |
5089 | | - onChange(will); |
5090 | | - } else { |
5091 | | - console.log(`[${openLabel}] 状态:${will ? '已开启' : '已关闭'}`); |
5092 | | - } |
| 5101 | + // 但是!如果我们在 GroupPopup 初始化时,已经根据 store 设置了 active 样式, |
| 5102 | + // 此时点击,我们确实应该取反。 |
| 5103 | + |
| 5104 | + const current = store.get(storeKey, 0) === 1; |
| 5105 | + isActive = !current; |
| 5106 | + } |
| 5107 | + |
| 5108 | + // 保存新状态 |
| 5109 | + store.set(storeKey, isActive ? 1 : 0); |
| 5110 | + |
| 5111 | + // 更新按钮 UI |
| 5112 | + if (btn) { |
| 5113 | + btn.innerText = isActive ? closeLabel : openLabel; |
| 5114 | + btn.style.borderStyle = isActive ? 'inset' : 'outset'; |
| 5115 | + } |
| 5116 | + |
| 5117 | + // 触发回调 |
| 5118 | + if (onChange) { |
| 5119 | + onChange(isActive); |
| 5120 | + } else { |
| 5121 | + console.log(`[${openLabel}] 状态:${isActive ? '已开启' : '已关闭'}`); |
5093 | 5122 | } |
5094 | 5123 | }; |
5095 | 5124 | } |
|
0 commit comments