Skip to content

Commit 9affc29

Browse files
committed
🔧 Fix Chrome file dialog opening issue
- Remove setTimeout delays that Chrome blocks - Add direct click handlers for better Chrome compatibility - Use pointer-events: auto on file input - Add mousedown/mouseup handler chain for Chrome - Make upload-content clickable as fallback - Add tabindex for accessibility - Update cache-busting to v=8
1 parent f6a2831 commit 9affc29

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed

docs/assets/app.js

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ class App {
191191
this.fileInput.style.cursor = 'pointer';
192192
this.fileInput.style.zIndex = '10';
193193
this.fileInput.style.fontSize = '0';
194+
this.fileInput.style.pointerEvents = 'auto'; // Chrome compatibility
195+
this.fileInput.setAttribute('tabindex', '-1'); // Make it focusable but not in tab order
194196

195197
// Ensure upload area has overflow hidden
196198
this.uploadArea.style.overflow = 'hidden';
@@ -203,43 +205,76 @@ class App {
203205
}
204206

205207
setupEventListeners() {
206-
// File input is positioned absolutely over upload area, so clicking anywhere opens it
207-
// Also handle direct clicks on upload area as fallback
208+
// Chrome requires direct user interaction - make file input directly clickable
209+
// Ensure file input accepts clicks directly
210+
this.fileInput.addEventListener('click', (e) => {
211+
// Allow normal file input behavior
212+
e.stopPropagation();
213+
});
214+
215+
// Handle clicks on upload area - Chrome compatibility
208216
this.uploadArea.addEventListener('click', (e) => {
209217
// Don't trigger if clicking on remove button or other interactive elements
210218
if (e.target.closest('.remove-file') || e.target.closest('.btn')) {
211219
return;
212220
}
213-
// If click is not on file input itself, trigger it
214-
if (this.fileInput && e.target !== this.fileInput && !e.target.closest('input[type="file"]')) {
215-
// Use setTimeout for better compatibility
216-
setTimeout(() => {
217-
try {
218-
this.fileInput.click();
219-
} catch (err) {
220-
console.error('Error opening file dialog:', err);
221-
}
222-
}, 10);
221+
222+
// If click is directly on file input, allow it
223+
if (e.target === this.fileInput || e.target.closest('input[type="file"]')) {
224+
return;
225+
}
226+
227+
// For Chrome: use direct click without setTimeout
228+
if (this.fileInput) {
229+
// Try direct click first (works in most browsers)
230+
try {
231+
this.fileInput.click();
232+
} catch (err) {
233+
// Fallback: trigger click event
234+
const clickEvent = new MouseEvent('click', {
235+
bubbles: true,
236+
cancelable: true,
237+
view: window
238+
});
239+
this.fileInput.dispatchEvent(clickEvent);
240+
}
223241
}
224242
});
225243

226-
// Also handle mousedown for better compatibility
244+
// Also handle mousedown for Chrome - Chrome sometimes needs mousedown
227245
this.uploadArea.addEventListener('mousedown', (e) => {
228246
if (e.target.closest('.remove-file') || e.target.closest('.btn')) {
229247
return;
230248
}
231-
if (this.fileInput && e.target !== this.fileInput && !e.target.closest('input[type="file"]')) {
232-
// Prevent default to avoid conflicts
233-
e.preventDefault();
234-
setTimeout(() => {
249+
if (e.target === this.fileInput || e.target.closest('input[type="file"]')) {
250+
return;
251+
}
252+
253+
// For Chrome: trigger click on mouseup (more reliable)
254+
const handleMouseUp = () => {
255+
if (this.fileInput) {
235256
try {
257+
this.fileInput.focus();
236258
this.fileInput.click();
237259
} catch (err) {
238260
console.error('Error opening file dialog:', err);
239261
}
240-
}, 10);
241-
}
262+
}
263+
document.removeEventListener('mouseup', handleMouseUp);
264+
};
265+
document.addEventListener('mouseup', handleMouseUp);
242266
});
267+
268+
// Make upload-content clickable too (removes pointer-events: none issue)
269+
const uploadContent = this.uploadArea.querySelector('.upload-content');
270+
if (uploadContent) {
271+
uploadContent.addEventListener('click', (e) => {
272+
e.stopPropagation();
273+
if (this.fileInput) {
274+
this.fileInput.click();
275+
}
276+
});
277+
}
243278

244279
// Drag and drop
245280
this.uploadArea.addEventListener('dragover', (e) => {

docs/assets/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ body {
187187
cursor: pointer;
188188
z-index: 10;
189189
font-size: 0;
190+
/* Chrome compatibility: ensure input is clickable */
191+
pointer-events: auto;
192+
-webkit-appearance: none;
193+
appearance: none;
190194
}
191195

192196
.upload-icon {

0 commit comments

Comments
 (0)