@@ -37,7 +37,7 @@ document.addEventListener("DOMContentLoaded", async () => {
3737 const restrictedMode = restrictedModeCheckbox . checked ;
3838 const groqApiKey = groqApiKeyInput . value . trim ( ) ;
3939 const enableAudioTranscription = enableAudioTranscriptionCheckbox . checked ;
40- const enableGroqProxy = enableAudioTranscription && enableGroqProxyCheckbox ? enableGroqProxyCheckbox . checked : false ;
40+ const enableGroqProxy = enableAudioTranscription && enableGroqProxyCheckbox ? enableGroqProxyCheckbox . checked : false ;
4141
4242 // 基本验证
4343 if ( ! apiUrl ) {
@@ -70,16 +70,67 @@ document.addEventListener("DOMContentLoaded", async () => {
7070 }
7171 }
7272
73- // 页面卸载时自动保存
73+ // ========== 统一的事件绑定:所有输入框和复选框变化时立即保存 ==========
74+
75+ // 所有复选框 - change 事件立即保存
76+ const allCheckboxes = [
77+ enableExtensionCheckbox ,
78+ autoSkipAdCheckbox ,
79+ restrictedModeCheckbox ,
80+ localOllamaCheckbox ,
81+ enableAudioTranscriptionCheckbox ,
82+ enableGroqProxyCheckbox
83+ ] . filter ( Boolean ) ; // 过滤掉可能不存在的元素
84+
85+ allCheckboxes . forEach ( checkbox => {
86+ checkbox . addEventListener ( 'change' , ( ) => {
87+ autoSaveSettings ( ) ;
88+ } ) ;
89+ } ) ;
90+
91+ // 所有文本输入框 - input 事件实时保存 + blur 事件兜底保存
92+ const allTextInputs = [
93+ apiUrlInput ,
94+ apiKeyInput ,
95+ modelInput ,
96+ groqApiKeyInput
97+ ] . filter ( Boolean ) ;
98+
99+ allTextInputs . forEach ( input => {
100+ // 输入时实时保存(带防抖)
101+ let debounceTimer : number | null = null ;
102+ input . addEventListener ( 'input' , ( ) => {
103+ if ( debounceTimer ) {
104+ clearTimeout ( debounceTimer ) ;
105+ }
106+ debounceTimer = window . setTimeout ( ( ) => {
107+ autoSaveSettings ( ) ;
108+ } , 500 ) ; // 500ms 防抖
109+ } ) ;
110+
111+ // 失去焦点时立即保存(兜底)
112+ input . addEventListener ( 'blur' , ( ) => {
113+ if ( debounceTimer ) {
114+ clearTimeout ( debounceTimer ) ;
115+ debounceTimer = null ;
116+ }
117+ autoSaveSettings ( ) ;
118+ } ) ;
119+ } ) ;
120+
121+ // 页面卸载时自动保存(兜底)
74122 window . addEventListener ( 'beforeunload' , autoSaveSettings ) ;
75123
76- // 页面隐藏时自动保存(用户切换标签页或关闭popup)
124+ // 页面隐藏时自动保存(用户切换标签页或关闭popup,兜底 )
77125 document . addEventListener ( 'visibilitychange' , ( ) => {
78126 if ( document . hidden ) {
79127 autoSaveSettings ( ) ;
80128 }
81129 } ) ;
82130
131+ // 窗口失去焦点时保存(额外兜底,针对 Mac 等平台)
132+ window . addEventListener ( 'blur' , autoSaveSettings ) ;
133+
83134 // API URL 下拉框功能
84135 function initApiUrlDropdown ( ) {
85136 // 切换下拉菜单显示/隐藏
@@ -134,34 +185,16 @@ document.addEventListener("DOMContentLoaded", async () => {
134185 } ) ;
135186 }
136187
137- // 启用插件复选框变化时立即保存
138- enableExtensionCheckbox . addEventListener ( 'change' , ( ) => {
139- autoSaveSettings ( ) ;
140- } ) ;
141-
142- // 自动跳过广告复选框变化时立即保存
143- autoSkipAdCheckbox . addEventListener ( 'change' , ( ) => {
144- autoSaveSettings ( ) ;
145- } ) ;
146-
147- // 限制模式复选框变化时立即保存
148- restrictedModeCheckbox . addEventListener ( 'change' , ( ) => {
149- autoSaveSettings ( ) ;
150- } ) ;
151-
152- localOllamaCheckbox . addEventListener ( 'change' , toggleOllamaField ) ;
153- function toggleOllamaField ( e : Event ) {
188+ // Ollama 复选框的额外逻辑:切换 CSS 类
189+ localOllamaCheckbox . addEventListener ( 'change' , ( e : Event ) => {
154190 const target = e . target as HTMLInputElement ;
155-
156191 // 使用CSS类来控制显示/隐藏,而不是直接修改display属性
157192 if ( target . checked ) {
158193 document . body . classList . add ( 'ollama-enabled' ) ;
159194 } else {
160195 document . body . classList . remove ( 'ollama-enabled' ) ;
161196 }
162- // 保存设置
163- autoSaveSettings ( ) ;
164- }
197+ } ) ;
165198
166199 // 添加Groq API密钥切换功能
167200 if ( toggleGroqPasswordBtn && groqApiKeyInput ) {
@@ -178,18 +211,12 @@ document.addEventListener("DOMContentLoaded", async () => {
178211 }
179212 }
180213
214+ // 音频转录复选框的额外逻辑:更新 CSS 类
181215 enableAudioTranscriptionCheckbox . addEventListener ( 'change' , ( ) => {
182216 const enabled = enableAudioTranscriptionCheckbox . checked ;
183217 updateAudioTranscriptionState ( enabled ) ;
184- autoSaveSettings ( ) ;
185218 } ) ;
186219
187- if ( enableGroqProxyCheckbox ) {
188- enableGroqProxyCheckbox . addEventListener ( 'change' , ( ) => {
189- autoSaveSettings ( ) ;
190- } ) ;
191- }
192-
193220 // 加载已保存的设置
194221 const settings = await chrome . storage . local . get ( [
195222 "apiUrl" ,
0 commit comments