快捷输入

· · 科技·工程

一、前言

由于洛谷在聊天时插入图片太过麻烦,所以我制作了快捷输入脚本 , 效果如下:

二、安装步骤

Edge 浏览器安装

  1. 打开 Edge 浏览器,点击右上角的 三个点 ,在下拉菜单中选择 扩展 , 然后点击 管理扩展(或直接访问 edge://extensions/) 。
  2. 开启页面左侧的 开发人员模式 模式 。
  3. 点击底部的 获取 Microsoft Edge 扩展,搜索“Tampermonkey”,点击“获取” ,安装后浏览器右上角会显示油猴图标。

Google Chrome 浏览器安装

由于 Chrome 的应用商店无法直接访问,所以请参考第三方教程安装:谷歌浏览器 Tampermonkey 安装方式 。

安装快捷输入脚本

  1. 点击浏览器右上角 油猴图标,在弹出的选项中选择 添加新脚本
  2. 删除默认的内容,将下面的脚本复制进去:
// ==UserScript==
// @name         快捷输入(跨站跨浏览器版)
// @namespace    http://tampermonkey.net/
// @version      12.0
// @description  支持跨网站存储,可导出导入数据实现跨浏览器记忆
// @author       p1
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @resource     FONTAWESOME_CSS https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css
// @run-at       document-end
// ==/UserScript==
(function() {'use strict';
const CONSTANTS = Object.freeze({
    GRID_COLUMNS: 3, // 网格列数
    FIXED_ITEM_SIZE: 60, // 项目尺寸(px)
    MAX_WIDTH: 600, // 最大宽度(px)
    MIN_HEIGHT: 120, // 最小高度(px)
    INITIAL_HEIGHT: 150, // 初始高度(px)
    CONTENT_EXTRA_SPACE: 60, // 内容额外空间(px)
    MAX_EXTRA_SPACE: 20, // 最大额外空间(px)
    INPUT_LINE_HEIGHT: 1.6, // 输入框行高
    OPEN_SCALE: 1, // 打开时缩放比例
    ALLOW_HORIZONTAL_RESIZE: false, // 允许水平调整
    ALLOW_VERTICAL_RESIZE: true, // 允许垂直调整
    AUTO_RESIZE_ON_CONTENT_CHANGE: false, // 内容变化时自动调整
    INPUT_PLUS_CHAR: "+", // 输入框加号字符
    INPUT_PLUS_SIZE: "24px", // 加号大小
    INPUT_PLUS_COLOR: "#666", // 加号颜色
    INPUT_BACKGROUND: "#f8f9fa", // 输入框背景色
    INPUT_BORDER: "1px dashed #ccc", // 输入框边框
    INPUT_BORDER_RADIUS: "4px", // 输入框圆角
    INPUT_BOX_SHADOW: "0 2px 5px rgba(0,0,0,0.1)", // 输入框阴影
    DELETE_BUTTON_SIZE: 16, // 删除按钮大小(px)
    DELETE_BUTTON_X_SIZE: "9px", // 删除按钮X符号大小
    DELETE_BUTTON_X_OFFSET: "0px", // X符号偏移
    IMAGE_PLACEHOLDER_PREFIX: "![]", // 图片占位符前缀
    IMAGE_PLACEHOLDER_SUFFIX: "", // 图片占位符后缀
    STORAGE_KEY: "customQuickInputItems", // 存储键名
    EXPORT_FILE_NAME: "QuickInput_data.json" // 导出文件名
});
const MIN_WIDTH = CONSTANTS.GRID_COLUMNS * CONSTANTS.FIXED_ITEM_SIZE + (CONSTANTS.GRID_COLUMNS - 1) * 8 + 20;
let domCache = { list: null, input: null, overlay: null, activeInput: null };
const faCss = GM_getResourceText("FONTAWESOME_CSS");
GM_addStyle(faCss);
initStyles();
const StorageUtil = {
    getItem: () => { try { const value = GM_getValue(CONSTANTS.STORAGE_KEY, []); return Array.isArray(value) ? value : []; } catch (e) { console.error('获取存储失败:', e); return []; } },
    setItem: (value) => { try { if (Array.isArray(value)) GM_setValue(CONSTANTS.STORAGE_KEY, value); } catch (e) { console.error('设置存储失败:', e); } },
    exportData: () => {
        const data = StorageUtil.getItem();
        const jsonStr = JSON.stringify(data, null, 2);
        const blob = new Blob([jsonStr], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = CONSTANTS.EXPORT_FILE_NAME;
        document.body.appendChild(a);
        a.click();
        setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 0);
    },
    importData: (file) => {
        const reader = new FileReader();
        reader.onload = (e) => {
            try {
                const data = JSON.parse(e.target.result);
                if (Array.isArray(data)) {
                    StorageUtil.setItem(data);
                    if (domCache.list) renderListItems(domCache.list);
                    alert('导入成功!共导入 ' + data.length + ' 条数据');
                } else alert('导入失败:文件格式不正确');
            } catch (e) { console.error('导入解析失败:', e); alert('导入失败:文件格式错误'); }
        };
        reader.readAsText(file);
    }
};
GM_registerMenuCommand("导出快捷输入数据", StorageUtil.exportData);
GM_registerMenuCommand("导入快捷输入数据", () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    input.onchange = (e) => { const file = e.target.files[0]; if (file) StorageUtil.importData(file); };
    input.click();
});
const DomUtil = {
    createFragment: () => document.createDocumentFragment(),
    removeElement: (el) => { if (el && el.parentNode) el.parentNode.removeChild(el); },
    removeElements: (selector) => { document.querySelectorAll(selector).forEach(el => DomUtil.removeElement(el)); },
    debounce: (func, wait = 100) => { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); }; },
    triggerInputEvents: (element) => {
        element.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
        element.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
        element.dispatchEvent(new KeyboardEvent('keydown', { key: 'Insert', bubbles: true }));
        element.dispatchEvent(new KeyboardEvent('keyup', { key: 'Insert', bubbles: true }));
        if (element._valueTracker) element._valueTracker.setValue(element.value);
        if (element.isContentEditable) {
            element.dispatchEvent(new Event('DOMNodeInserted', { bubbles: true }));
            element.dispatchEvent(new Event('DOMSubtreeModified', { bubbles: true }));
            element.dispatchEvent(new Event('input', { bubbles: true, cancelable: true, composed: true }));
        }
    },
    completeImageUrl: (url) => {
        if (!url) return '';
        if (/^https?:\/\//i.test(url)) return url;
        if (url.startsWith('/')) return window.location.origin + url;
        return `${window.location.protocol}//${url.replace(/^\/\//, '')}`;
    },
    insertContent: (inputElement, content) => {
        if (isImageFormat(content)) {
            const imageUrl = extractImageUrl(content);
            const completedUrl = DomUtil.completeImageUrl(imageUrl);
            return DomUtil.insertImage(inputElement, completedUrl);
        } else return DomUtil.insertText(inputElement, content);
    },
    insertText: (inputElement, text) => {
        try {
            if (inputElement.isContentEditable) {
                const selection = window.getSelection();
                if (selection.rangeCount) {
                    const range = selection.getRangeAt(0);
                    range.deleteContents();
                    const textNode = document.createTextNode(text);
                    range.insertNode(textNode);
                    range.setStartAfter(textNode);
                    range.collapse(true);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    return true;
                }
            } else {
                const startPos = inputElement.selectionStart;
                const endPos = inputElement.selectionEnd;
                const currentValue = inputElement.value;
                inputElement.value = currentValue.substring(0, startPos) + text + currentValue.substring(endPos);
                const newCursorPos = startPos + text.length;
                inputElement.setSelectionRange(newCursorPos, newCursorPos);
                inputElement.focus();
                return true;
            }
        } catch (e) { console.error('插入文本失败:', e); return false; }
    },
    insertImage: (inputElement, url) => {
        try {
            if (inputElement.isContentEditable) {
                const selection = window.getSelection();
                if (selection.rangeCount) {
                    const range = selection.getRangeAt(0);
                    range.deleteContents();
                    const img = document.createElement('img');
                    img.src = url;
                    img.alt = '插入的图片';
                    img.style.maxWidth = '100%';
                    range.insertNode(img);
                    const spaceNode = document.createTextNode(' ');
                    range.setStartAfter(img);
                    range.insertNode(spaceNode);
                    range.setStartAfter(spaceNode);
                    range.collapse(true);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    return true;
                }
            } else {
                const markdownImg = `![图片](${url})`;
                return DomUtil.insertText(inputElement, markdownImg);
            }
        } catch (e) { console.error('插入图片失败:', e); return DomUtil.insertText(inputElement, url); }
    }
};
function initStyles() {
    GM_addStyle(`.custom-right-click-list{position:absolute;background:white;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 10px rgba(0,0,0,0.1);padding:10px;margin:0;list-style:none;z-index:99999;display:grid;grid-template-columns:repeat(${CONSTANTS.GRID_COLUMNS},1fr);gap:8px;opacity:0;transform-origin:top left;transition:all 0.2s ease-out;pointer-events:none;overflow:auto;box-sizing:border-box;justify-items:start;align-items:start;align-content:start;scrollbar-width:none;}.custom-right-click-list::-webkit-scrollbar{display:none;}.custom-right-click-list.visible{opacity:1;transform:scale(${CONSTANTS.OPEN_SCALE});pointer-events:auto;}.custom-right-click-list li{width:${CONSTANTS.FIXED_ITEM_SIZE}px;height:${CONSTANTS.FIXED_ITEM_SIZE}px;padding:8px;cursor:pointer;transition:all 0.2s;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;border:1px solid transparent;box-shadow:0 2px 5px rgba(0,0,0,0.08);-webkit-user-select:none;user-select:none;}.custom-right-click-list li:hover{background-color:#f0f0f0;border-color:#ddd;border-radius:3px;box-shadow:0 3px 8px rgba(0,0,0,0.12);}.custom-right-click-list li:active{background-color:#e0e0e0;transform:scale(0.95);transition:all 0.1s;box-shadow:0 1px 3px rgba(0,0,0,0.05);}.custom-right-click-active{box-shadow:0 0 0 2px rgba(52,152,219,0.3)!important;transition:box-shadow 0.2s;}.custom-item-input-container{width:${CONSTANTS.FIXED_ITEM_SIZE}px;height:${CONSTANTS.FIXED_ITEM_SIZE}px;padding:0;cursor:pointer;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;border-radius:${CONSTANTS.INPUT_BORDER_RADIUS};box-shadow:${CONSTANTS.INPUT_BOX_SHADOW};background-color:${CONSTANTS.INPUT_BACKGROUND};border:${CONSTANTS.INPUT_BORDER};}.custom-item-plus-char{font-size:${CONSTANTS.INPUT_PLUS_SIZE};color:${CONSTANTS.INPUT_PLUS_COLOR};font-weight:bold;-webkit-user-select:none;user-select:none;}.custom-item-input{display:none;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:80%;max-width:500px;padding:15px;border:1px solid #ccc;border-radius:6px;box-shadow:0 4px 20px rgba(0,0,0,0.15);background:white;z-index:100000;min-height:120px;font-size:16px;line-height:${CONSTANTS.INPUT_LINE_HEIGHT};resize:vertical;max-height:300px;}.custom-item-input.visible{display:block;}.input-overlay{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:99999;}.input-overlay.visible{display:block;}.delete-item-btn{position:absolute;right:2px;top:2px;color:#ff4444;opacity:0;visibility:hidden;transition:all 0.2s ease;font-size:${CONSTANTS.DELETE_BUTTON_X_SIZE};width:${CONSTANTS.DELETE_BUTTON_SIZE}px;height:${CONSTANTS.DELETE_BUTTON_SIZE}px;display:flex;align-items:center;justify-content:center;padding:0;background:rgba(255,255,255,0.8);border-radius:50%;z-index:1;cursor:pointer;-webkit-user-select:none;user-select:none;transform:scale(0.9);}.delete-item-btn::before{content:'×';display:inline-block;line-height:1;position:relative;top:${CONSTANTS.DELETE_BUTTON_X_OFFSET};left:${CONSTANTS.DELETE_BUTTON_X_OFFSET};}.custom-right-click-list li:hover .delete-item-btn{opacity:0.85;visibility:visible;transform:scale(1);}.delete-item-btn:hover{background-color:#ff4444;color:white;opacity:0.9;transform:scale(1.1);box-shadow:0 0 2px rgba(255,68,68,0.5);}.delete-item-btn:active{transform:scale(0.95);opacity:0.95;}.menu-image-preview{max-width:100%;max-height:100%;object-fit:contain;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,0.1);pointer-events:none;-webkit-user-select:none;user-select:none;}.item-text{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;max-height:100%;-webkit-user-select:none;user-select:none;}.image-item-indicator{position:absolute;bottom:2px;right:2px;font-size:8px;background:rgba(0,0,0,0.3);color:white;padding:1px 3px;border-radius:2px;}`);
}
function createList() {
    if (domCache.list) return domCache.list;
    DomUtil.removeElements('.custom-item-input, .input-overlay, #customRightClickList');
    const list = document.createElement('ul');
    list.className = 'custom-right-click-list';
    list.id = 'customRightClickList';
    list.style.width = `${MIN_WIDTH}px`;
    list.style.height = `${CONSTANTS.INITIAL_HEIGHT}px`;
    list.style.transform = `scale(${CONSTANTS.OPEN_SCALE})`;
    list.addEventListener('click', handleListClick);
    renderListItems(list);
    document.body.appendChild(list);
    domCache.list = list;
    return list;
}
function handleListClick(e) {
    e.stopPropagation();
    const addBtn = e.target.closest('.custom-item-input-container');
    if (addBtn) { showAddItemInput(domCache.list); return; }
    const li = e.target.closest('li');
    if (li && !li.classList.contains('custom-item-input-container')) {
        const text = li.dataset.content;
        if (text && domCache.activeInput) {
            domCache.activeInput.classList.add('custom-right-click-active');
            const success = DomUtil.insertContent(domCache.activeInput, text);
            DomUtil.triggerInputEvents(domCache.activeInput);
            setTimeout(() => { if (domCache.activeInput) domCache.activeInput.classList.remove('custom-right-click-active'); }, 300);
            hideList();
        }
    }
}
function handleDeleteClick(e, text) {
    e.stopPropagation();
    e.preventDefault();
    if (text) {
        const customItems = StorageUtil.getItem();
        const index = customItems.findIndex(item => item === text);
        if (index !== -1) {
            const li = e.target.closest('li');
            if (li) {
                li.style.transition = 'all 0.15s ease-out';
                li.style.transform = 'scale(0.9)';
                li.style.opacity = '0.3';
                setTimeout(() => {
                    customItems.splice(index, 1);
                    StorageUtil.setItem(customItems);
                    renderListItems(domCache.list);
                }, 150);
            }
        }
    }
}
function getListItemText(li) { return li.dataset.content || ''; }
function renderListItems(list) {
    while (list.firstChild) DomUtil.removeElement(list.firstChild);
    const fragment = DomUtil.createFragment();
    const customItems = StorageUtil.getItem();
    customItems.forEach(item => { fragment.appendChild(createItemElement(item)); });
    fragment.appendChild(createAddButton());
    list.appendChild(fragment);
    if (CONSTANTS.AUTO_RESIZE_ON_CONTENT_CHANGE) adjustHeightToContent(list);
}
function createItemElement(text) {
    const li = document.createElement('li');
    li.dataset.content = text;
    if (isImageFormat(text)) {
        const imageUrl = extractImageUrl(text);
        const completedUrl = DomUtil.completeImageUrl(imageUrl);
        const img = document.createElement('img');
        img.src = completedUrl;
        img.alt = '图片预览';
        img.className = 'menu-image-preview';
        const indicator = document.createElement('span');
        indicator.className = 'image-item-indicator';
        indicator.textContent = '图';
        li.appendChild(indicator);
        img.onerror = function() {
            this.alt = '图片加载失败';
            this.style.display = 'none';
            const errorText = document.createElement('span');
            errorText.textContent = '图片';
            errorText.style.color = '#666';
            li.appendChild(errorText);
        };
        li.appendChild(img);
    } else {
        const textSpan = document.createElement('span');
        textSpan.className = 'item-text';
        textSpan.textContent = text;
        li.appendChild(textSpan);
    }
    const deleteBtn = document.createElement('span');
    deleteBtn.className = 'delete-item-btn';
    deleteBtn.addEventListener('click', (e) => handleDeleteClick(e, text));
    li.appendChild(deleteBtn);
    return li;
}
function createAddButton() {
    const inputContainer = document.createElement('li');
    inputContainer.className = 'custom-item-input-container';
    inputContainer.title = "添加新内容";
    const plusChar = document.createElement('span');
    plusChar.className = 'custom-item-plus-char';
    plusChar.textContent = CONSTANTS.INPUT_PLUS_CHAR;
    inputContainer.appendChild(plusChar);
    return inputContainer;
}
function showAddItemInput(list) {
    DomUtil.removeElements('.custom-item-input, .input-overlay');
    const overlay = document.createElement('div');
    overlay.className = 'input-overlay visible';
    const input = document.createElement('textarea');
    input.className = 'custom-item-input visible';
    input.placeholder = `请输入文本或图片链接`;
    domCache.input = input;
    domCache.overlay = overlay;
    document.body.appendChild(overlay);
    document.body.appendChild(input);
    input.focus();
    const closeInput = (save = false) => {
        if (save && input.value.trim()) {
            const content = input.value.trim();
            const customItems = StorageUtil.getItem();
            if (isValidImageUrl(content) && !isImageFormat(content)) {
                const formattedContent = `![图片](${content})`;
                if (!customItems.includes(formattedContent)) {
                    customItems.push(formattedContent);
                    StorageUtil.setItem(customItems);
                }
            } else if (!customItems.includes(content)) {
                customItems.push(content);
                StorageUtil.setItem(customItems);
            }
            renderListItems(list);
        }
        domCache.input = null;
        domCache.overlay = null;
        DomUtil.removeElement(input);
        DomUtil.removeElement(overlay);
    };
    input.addEventListener('keydown', function(e) {
        if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); closeInput(true); }
        else if (e.key === 'Escape') closeInput(false);
    });
    overlay.addEventListener('click', () => closeInput(false));
    input.addEventListener('blur', () => closeInput(true));
}
function showList(inputElement) {
    const list = domCache.list || createList();
    list.classList.remove('visible');
    domCache.activeInput = inputElement;
    document.querySelectorAll('.custom-right-click-active').forEach(el => el.classList.remove('custom-right-click-active'));
    if (inputElement) inputElement.classList.add('custom-right-click-active');
    let newX, newY;
    if (inputElement) {
        const rect = inputElement.getBoundingClientRect();
        newX = rect.left + window.scrollX;
        newY = rect.bottom + window.scrollY + 5;
    } else {
        newX = window.innerWidth / 2 - MIN_WIDTH / 2 + window.scrollX;
        newY = window.innerHeight / 2 - CONSTANTS.INITIAL_HEIGHT / 2 + window.scrollY;
    }
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const listWidth = list.offsetWidth || MIN_WIDTH;
    const listHeight = list.offsetHeight || CONSTANTS.INITIAL_HEIGHT;
    if (newX + listWidth > viewportWidth + window.scrollX) newX = Math.max(0, viewportWidth + window.scrollX - listWidth - 10);
    if (newY + listHeight > viewportHeight + window.scrollY) newY = Math.max(0, (inputElement ? inputElement.getBoundingClientRect().top : newY) + window.scrollY - listHeight - 5);
    list.style.left = `${newX}px`;
    list.style.top = `${newY}px`;
    void list.offsetWidth;
    requestAnimationFrame(() => list.classList.add('visible'));
}
function hideList() {
    if (domCache.list) domCache.list.classList.remove('visible');
    if (domCache.activeInput) {
        domCache.activeInput.classList.remove('custom-right-click-active');
        domCache.activeInput = null;
    }
}
function isImageFormat(content) { return /^!\s*\[\s*(.*?)\s*\]\s*\(\s*(.*?)\s*\)\s*$/.test(content.trim()); }
function extractImageUrl(content) { const match = content.trim().match(/^!\s*\[\s*(.*?)\s*\]\s*\(\s*(.*?)\s*\)\s*$/); return match ? match[2] : null; }
function isValidImageUrl(url) { const trimmedUrl = url.trim(); return /^https?:\/\/.+\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i.test(trimmedUrl); }
function calculateContentHeight(list) {
    let totalHeight = 0;
    let child = list.firstChild;
    while (child) { if (child.nodeType === 1) totalHeight += child.offsetHeight + 8; child = child.nextSibling; }
    return totalHeight + 20;
}
function adjustHeightToContent(list) {
    const contentHeight = calculateContentHeight(list);
    const newHeight = Math.max(CONSTANTS.MIN_HEIGHT, Math.min(contentHeight + CONSTANTS.CONTENT_EXTRA_SPACE, contentHeight + CONSTANTS.MAX_EXTRA_SPACE));
    list.style.height = `${newHeight}px`;
}
function isInputElement(element) {
    const tagName = element.tagName.toLowerCase();
    return (tagName === 'input' && !['checkbox', 'radio', 'file', 'submit', 'reset', 'button'].includes(element.type)) || tagName === 'textarea' || element.isContentEditable;
}
function initEventListeners() {
    document.addEventListener('contextmenu', function(e) {
        if (isInputElement(e.target)) {
            e.preventDefault();
            const list = domCache.list;
            if (list && list.classList.contains('visible')) hideList();
            else showList(e.target);
        } else hideList();
    });
    document.addEventListener('click', function(e) {
        if (!e.target.closest('.custom-right-click-list') && !e.target.closest('.custom-item-input') && !e.target.closest('.input-overlay') && !isInputElement(e.target)) {
            hideList();
        }
    });
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') {
            if (domCache.input && domCache.overlay) {
                DomUtil.removeElement(domCache.input);
                DomUtil.removeElement(domCache.overlay);
                domCache.input = null;
                domCache.overlay = null;
            } else hideList();
        }
    });
    const handleScroll = DomUtil.debounce(function() {
        if (domCache.list && domCache.list.classList.contains('visible') && domCache.activeInput) {
            const rect = domCache.activeInput.getBoundingClientRect();
            domCache.list.style.left = `${rect.left + window.scrollX}px`;
            domCache.list.style.top = `${rect.bottom + window.scrollY + 5}px`;
        }
    }, 50);
    window.addEventListener('scroll', handleScroll);
    window.addEventListener('unload', function() {
        window.removeEventListener('scroll', handleScroll);
        if (domCache.list) domCache.list.removeEventListener('click', handleListClick);
    });
}
initEventListeners();
})();
  1. 点击左上角的 文件保存(或按 Ctrl+S),即可生效。

故障排除

若脚本安装后无法使用,请检查是否开启了 开发人员模式

三、使用方法

基础使用

  1. 点击任意输入框进入输入状态后按下右键,即可呼出菜单 。
  2. 点击菜单内的内容 。

添加新快捷内容

  1. 右键输入框呼出快捷菜单,点击菜单中的 “+”
  2. 在弹出的文本框中输入内容:
    • 文本:直接输入 。
    • 图片:以 Markdown 格式输入(![]()) 。

配置导入&导出

导出配置

  1. 点击浏览器右上角 油猴图标
  2. 在弹出菜单中选择 “导出快捷输入数据”
  3. 浏览器将自动下载名为 QuickInput_data.json 的文件 。

导入配置

  1. 点击浏览器右上角 油猴图标,选择 “导入快捷输入数据”
  2. 在文件选择窗口中,选择之前导出的 QuickInput_data.json 文件;
  3. 导入成功后,脚本会弹出提示(如“导入成功!共导入 114514 条数据”)。

样式调整

按照注释修改对应变量的内容即可 :

    GRID_COLUMNS: 3, // 网格列数
    FIXED_ITEM_SIZE: 60, // 项目尺寸(px)
    MAX_WIDTH: 600, // 最大宽度(px)
    MIN_HEIGHT: 120, // 最小高度(px)
    INITIAL_HEIGHT: 150, // 初始高度(px)
    CONTENT_EXTRA_SPACE: 60, // 内容额外空间(px)
    MAX_EXTRA_SPACE: 20, // 最大额外空间(px)
    INPUT_LINE_HEIGHT: 1.6, // 输入框行高
    OPEN_SCALE: 1, // 打开时缩放比例
    ALLOW_HORIZONTAL_RESIZE: false, // 允许水平调整
    ALLOW_VERTICAL_RESIZE: true, // 允许垂直调整
    AUTO_RESIZE_ON_CONTENT_CHANGE: false, // 内容变化时自动调整
    INPUT_PLUS_CHAR: "+", // 添加按钮字符
    INPUT_PLUS_SIZE: "24px", // 加号大小
    INPUT_PLUS_COLOR: "#666", // 加号颜色
    INPUT_BACKGROUND: "#f8f9fa", // 输入框背景色
    INPUT_BORDER: "1px dashed #ccc", // 输入框边框
    INPUT_BORDER_RADIUS: "4px", // 输入框圆角
    INPUT_BOX_SHADOW: "0 2px 5px rgba(0,0,0,0.1)", // 输入框阴影
    DELETE_BUTTON_SIZE: 16, // 删除按钮大小(px)
    DELETE_BUTTON_X_SIZE: "9px", // 删除按钮X符号大小
    DELETE_BUTTON_X_OFFSET: "0px", // X符号偏移
    IMAGE_PLACEHOLDER_PREFIX: "![]", // 图片占位符前缀
    IMAGE_PLACEHOLDER_SUFFIX: "", // 图片占位符后缀
    STORAGE_KEY: "customQuickInputItems", // 存储键名
    EXPORT_FILE_NAME: "QuickInput_data.json" // 导出文件名

四、注意事项

只能在支持 Markdown 格式的地方使用 。