/** * AKSRT Page Edit — 前台编辑增强 * * 提供前台编辑页面的增强功能: * - 自动保存草稿 * - 标签建议 * - 快捷键支持 * * @package AKSRT */ (function () { 'use strict'; var DRAFT_KEY_PREFIX = 'aksrt_draft_'; /** * 初始化页面编辑增强 * * @param {Object} options 配置项 */ function PageEdit(options) { this.options = Object.assign({ formSelector: 'form[data-aksrt-edit]', titleSelector: 'input[name="title"], input[name="topic_title"]', contentSelector: 'textarea[name="content"], textarea[name="topic_content"]', tagsSelector: 'input[name="tags"], input[name="topic_tags"]', autoSaveInterval: 30000, // 30秒 draftKey: '', }, options || {}); this.form = document.querySelector(this.options.formSelector); if (!this.form) return; this.autoSaveTimer = null; this.lastSavedContent = ''; this.init(); } PageEdit.prototype.init = function () { var self = this; this.titleInput = this.form.querySelector(this.options.titleSelector); this.contentTextarea = this.form.querySelector(this.options.contentSelector); this.tagsInput = this.form.querySelector(this.options.tagsSelector); // 自动保存草稿 this.initAutoSave(); // 快捷键 this.initShortcuts(); // 标签输入增强 this.initTagInput(); // 表单提交时清除草稿 this.form.addEventListener('submit', function () { self.clearDraft(); }); // 页面离开提醒 window.addEventListener('beforeunload', function (e) { if (self.hasUnsavedChanges()) { e.preventDefault(); e.returnValue = '您有未保存的修改,确定要离开吗?'; } }); }; PageEdit.prototype.initAutoSave = function () { var self = this; if (!this.options.draftKey) { // 从页面 URL 生成 draft key this.options.draftKey = DRAFT_KEY_PREFIX + (window.location.pathname.replace(/\//g, '_') || 'page'); } // 恢复草稿 this.restoreDraft(); // 定时自动保存 if (this.options.autoSaveInterval > 0) { this.autoSaveTimer = setInterval(function () { self.saveDraft(); }, this.options.autoSaveInterval); } }; PageEdit.prototype.saveDraft = function () { if (!this.form) return; var data = {}; if (this.titleInput) data.title = this.titleInput.value; if (this.contentTextarea) data.content = this.contentTextarea.value; if (this.tagsInput) data.tags = this.tagsInput.value; var content = JSON.stringify(data); if (content === this.lastSavedContent) return; try { localStorage.setItem(this.options.draftKey, content); this.lastSavedContent = content; // 显示保存提示 var toast = document.getElementById('aksrt-draft-toast'); if (!toast) { toast = document.createElement('div'); toast.id = 'aksrt-draft-toast'; toast.className = 'aksrt-page-edit__toast'; document.body.appendChild(toast); } toast.textContent = '草稿已自动保存'; toast.classList.add('aksrt-page-edit__toast--visible'); setTimeout(function () { toast.classList.remove('aksrt-page-edit__toast--visible'); }, 2000); } catch (e) { console.error('[AKSRT PageEdit] 保存草稿失败:', e); } }; PageEdit.prototype.restoreDraft = function () { try { var saved = localStorage.getItem(this.options.draftKey); if (!saved) return; var data = JSON.parse(saved); var hasContent = false; if (this.titleInput && data.title && !this.titleInput.value) { this.titleInput.value = data.title; hasContent = true; } if (this.contentTextarea && data.content && !this.contentTextarea.value) { this.contentTextarea.value = data.content; hasContent = true; } if (this.tagsInput && data.tags && !this.tagsInput.value) { this.tagsInput.value = data.tags; hasContent = true; } if (hasContent) { this.lastSavedContent = saved; } } catch (e) { console.error('[AKSRT PageEdit] 恢复草稿失败:', e); } }; PageEdit.prototype.clearDraft = function () { try { localStorage.removeItem(this.options.draftKey); } catch (e) {} }; PageEdit.prototype.hasUnsavedChanges = function () { if (!this.form) return false; var data = {}; if (this.titleInput) data.title = this.titleInput.value; if (this.contentTextarea) data.content = this.contentTextarea.value; if (this.tagsInput) data.tags = this.tagsInput.value; return JSON.stringify(data) !== this.lastSavedContent; }; PageEdit.prototype.initShortcuts = function () { var self = this; this.form.addEventListener('keydown', function (e) { // Ctrl+S / Cmd+S 保存草稿 if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); self.saveDraft(); } }); }; PageEdit.prototype.initTagInput = function () { if (!this.tagsInput) return; // 回车键添加标签 this.tagsInput.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); } }); }; // 自动初始化 function autoInit() { var form = document.querySelector('form[data-aksrt-edit]'); if (form) { new PageEdit(); } } jQuery(document).off('auto_fun.aksrt-page-edit').on('auto_fun.aksrt-page-edit', autoInit); window.AksrtPageEdit = PageEdit; })();