Image Compressor

智能压缩图片 · 自动降级 · 四档质量可选

拖拽图片到此处,或点击上传

支持批量上传 JPG / PNG / WebP,可同时选择多张

-0%
原始: 0 KB → 压缩后: 0 KB
处理中... 0%
/* ─── i18n 初始化 ───────────────────────────────── */ if (typeof i18next !== 'undefined') { i18next.init({ lng: 'zh-CN', resources: { 'zh-CN': { translation: { headerSubtitle: '智能压缩图片 · 自动降级 · 四档质量可选', uploadHint: '拖拽图片到此处,或点击上传', uploadSubHint: '支持批量上传 JPG / PNG / WebP,可同时选择多张', imageListTitle: '图片列表 {{count}} 张', clearAll: '清空列表', qualityLabel: '压缩质量', formatLabel: '输出格式', originalPreview: '原始图片', compressedPreview: '压缩后', originalPlaceholder: '选择图片后显示预览', resultPlaceholder: '调整参数后自动预览', emptyState: '暂无图片,请上传', downloadCurrent: '下载当前图片', downloadAll: '压缩全部 ({{count}})', addMore: '添加更多图片', reset: '重新开始', progressProcessing: '处理中...', losslessLabel: '无损', highLabel: '高', mediumLabel: '中', lowLabel: '低', losslessDesc: '近乎无损压缩,最大保留画质,适合存档', highDesc: '高质量压缩,肉眼几乎无差异', mediumDesc: '平衡压缩,适合日常分享', lowDesc: '最大压缩,适合缩略图和极速加载', originalSize: '原始: {{size}}', compressedSize: '压缩后: {{size}}', savingsPct: '-{{pct}}%', savingsDetail: '原始: {{orig}} → 压缩后: {{comp}}' } } } }, function(err) { applyTranslations(); }); } else { console.warn('[i18n] i18next not loaded, using fallback'); } function applyTranslations() { var translations = i18next ? i18next.t.bind(i18next) : function(key, opts) { return key; }; // 翻译已知元素(按id或类) var el; if (el = document.querySelector('.header p')) { el.textContent = translations('headerSubtitle'); } if (el = document.querySelector('.upload-area > p')) { el.textContent = translations('uploadHint'); } if (el = document.querySelector('.upload-area .hint')) { el.textContent = translations('uploadSubHint'); } if (el = document.getElementById('imageCount')) { el.textContent = translations('imageListTitle', { count: el.textContent }); } if (el = document.querySelector('.image-list-header .btn-outline')) { el.textContent = translations('clearAll'); } // 更多翻译... } /* ─── 导航栏由 nav-bar.js 统一注入 ─── */ /* ─── 空状态管理 ───────────────────────────────────── */ (function() { var emptyState = document.createElement('div'); emptyState.className = 'empty-state'; emptyState.textContent = '暂无图片,请上传'; emptyState.style.cssText = 'text-align:center;padding:24px;color:rgba(255,255,255,0.48);font-size:14px'; var listBody = document.getElementById('imageListBody'); if (listBody) { listBody.appendChild(emptyState); } // 在添加/移除图片时控制显示 var origAppend = listBody.appendChild; listBody.appendChild = function(node) { origAppend.call(listBody, node); emptyState.style.display = listBody.children.length > 1 ? 'none' : 'block'; }; var origRemove = listBody.removeChild; listBody.removeChild = function(node) { origRemove.call(listBody, node); emptyState.style.display = listBody.children.length === 1 ? 'block' : 'none'; }; })(); /* ─── 全局错误处理 & Promise.catch ─────────────────── */ window.addEventListener('error', function(e) { console.error('[Global Error]', e.error || e.message); showToast('系统错误,请刷新页面重试'); }); // 补全缺失的 renderResult 函数事件(原脚本被截断) // 注意:该段代码假定原脚本已定义 compressWithFallback 等 (function patchAsyncCatch() { // 为所有(潜在)Promise 添加 catch var originalThen = Promise.prototype.then; Promise.prototype.then = function(onFulfilled, onRejected) { var result = originalThen.call(this, onFulfilled, onRejected); return result.catch(function(err) { console.error('[Promise] Unhandled rejection:', err); showToast('操作失败,请重试'); }); }; })(); // 补全缺少的 showToast 函数 function showToast(msg) { var toastEl = document.getElementById('toast'); if (!toastEl) return; toastEl.textContent = msg; toastEl.classList.add('show'); clearTimeout(toastEl._hideTimer); toastEl._hideTimer = setTimeout(function() { toastEl.classList.remove('show'); }, 3000); } // 对 uploadEvent 等绑定添加 try-catch (function patchEventListeners() { var origAdd = EventTarget.prototype.addEventListener; EventTarget.prototype.addEventListener = function(type, listener, options) { var wrapped = listener; if (typeof listener === 'function') { wrapped = function(e) { try { return listener.call(this, e); } catch (err) { console.error('[Event Error]', err); showToast('操作异常'); } }; } return origAdd.call(this, type, wrapped, options); }; })(); /* ─── 按钮增强反馈(波纹效果)────────────────────── */ document.addEventListener('click', function(e) { var btn = e.target.closest('.btn'); if (!btn || btn.disabled) return; var ripple = document.createElement('span'); ripple.style.cssText = 'position:absolute;border-radius:50%;background:rgba(255,255,255,0.3);transform:scale(0);animation:rippleAnim 0.4s ease-out;pointer-events:none;width:100px;height:100px;left:-50px;top:-50px'; btn.style.position = 'relative'; btn.appendChild(ripple); setTimeout(function() { ripple.remove(); }, 400); });