Greasy Fork is available in English.

网页内记事本(In-page notepad)

在网页中添加一个记事本功能

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         网页内记事本(In-page notepad)
// @namespace    http://your.namespace/
// @version      1.0
// @description  在网页中添加一个记事本功能
// @author       雷明闪(melonTMD)
// @license      MIT
// @match        http://*/*
// @match        https://*/*
// @grant        GM_download
// @grant        GM_setClipboard
// ==/UserScript==

(function() {
    'use strict';

    let isResizing = false;
    let isDragging = false;
    let prevX;
    let prevY;

    // 创建记事本容器
    const noteContainer = document.createElement('div');
    noteContainer.id = 'note-container';
    noteContainer.style.position = 'fixed';
    noteContainer.style.top = '50px'; // 初始位置
    noteContainer.style.left = '50px'; // 初始位置
    noteContainer.style.width = '300px'; // 初始宽度
    noteContainer.style.height = '300px'; // 初始高度
    noteContainer.style.border = '1px solid #ccc';
    noteContainer.style.backgroundColor = '#fff';
    noteContainer.style.zIndex = '9999';
    noteContainer.style.overflow = 'hidden';
    noteContainer.style.resize = 'both'; // 启用调整大小
    noteContainer.style.cursor = 'default';
    noteContainer.style.display = 'none'; // 初始隐藏

    // 创建记事本文本框
    const noteTextarea = document.createElement('textarea');
    noteTextarea.id = 'note';
    noteTextarea.placeholder = '在这里写下你的笔记...';
    noteTextarea.style.width = '100%';
    noteTextarea.style.height = 'calc(100% - 30px)';
    noteTextarea.style.border = 'none';
    noteTextarea.style.padding = '10px';
    noteTextarea.style.resize = 'none';
    noteTextarea.style.overflow = 'auto';

    // 创建标题栏
    const titleBar = document.createElement('div');
    titleBar.style.width = '100%';
    titleBar.style.height = '30px';
    titleBar.style.backgroundColor = '#ccc';
    titleBar.style.cursor = 'move';
    titleBar.style.userSelect = 'none';

    // 添加标题栏到记事本容器
    noteContainer.appendChild(titleBar);
    // 添加记事本文本框到记事本容器
    noteContainer.appendChild(noteTextarea);
    // 添加记事本容器到页面
    document.body.appendChild(noteContainer);

    // 当点击标题栏时开始拖动
    titleBar.addEventListener('mousedown', function(e) {
        isDragging = true;
        prevX = e.clientX;
        prevY = e.clientY;
    });

    // 当调整记事本大小时
    noteContainer.addEventListener('mousedown', function(e) {
        if (e.target === noteContainer) {
            isResizing = true;
            prevX = e.clientX;
            prevY = e.clientY;
        }
    });

    // 当鼠标移动时进行拖动和调整大小
    document.addEventListener('mousemove', function(e) {
        if (isDragging) {
            const newX = noteContainer.offsetLeft + e.clientX - prevX;
            const newY = noteContainer.offsetTop + e.clientY - prevY;
            noteContainer.style.left = newX + 'px';
            noteContainer.style.top = newY + 'px';
            prevX = e.clientX;
            prevY = e.clientY;
        } else if (isResizing) {
            const newWidth = noteContainer.offsetWidth + e.clientX - prevX;
            const newHeight = noteContainer.offsetHeight + e.clientY - prevY;
            noteContainer.style.width = newWidth + 'px';
            noteContainer.style.height = newHeight + 'px';
            prevX = e.clientX;
            prevY = e.clientY;
        }
    });

    // 当鼠标释放时停止拖动和调整大小
    document.addEventListener('mouseup', function() {
        isDragging = false;
        isResizing = false;
    });

    // 检查本地存储中是否已经保存了笔记
    if (localStorage.getItem('note')) {
        noteTextarea.value = localStorage.getItem('note');
    }

    // 当点击保存按钮时
    function saveNote() {
        // 获取文本框中的内容
        const note = noteTextarea.value;
        // 将内容保存到本地存储中
        localStorage.setItem('note', note);
        // 提示用户保存成功
        alert('笔记已保存!');
    }

    // 创建文件按钮
    const fileButton = document.createElement('button');
    fileButton.innerHTML = '文件';
    fileButton.style.position = 'absolute';
    fileButton.style.top = '5px';
    fileButton.style.left = '5px';
    fileButton.style.padding = '5px';
    fileButton.style.backgroundColor = '#f0f0f0';
    fileButton.style.border = 'none';
    fileButton.style.cursor = 'pointer';

    // 创建文件下拉菜单
    const fileMenu = document.createElement('div');
    fileMenu.style.position = 'absolute';
    fileMenu.style.top = '30px';
    fileMenu.style.left = '0';
    fileMenu.style.width = '100px';
    fileMenu.style.backgroundColor = '#fff';
    fileMenu.style.border = '1px solid #ccc';
    fileMenu.style.display = 'none'; // 初始隐藏

    // 创建文件菜单选项
    const clearOption = document.createElement('div');
    clearOption.textContent = '清除窗口内容';
    clearOption.style.padding = '5px';
    clearOption.style.cursor = 'pointer';
    const saveOption = document.createElement('div');
    saveOption.textContent = '保存';
    saveOption.style.padding = '5px';
    saveOption.style.cursor = 'pointer';
    const saveAsTxtOption = document.createElement('div');
    saveAsTxtOption.textContent = '保存为txt文件';
    saveAsTxtOption.style.padding = '5px';
    saveAsTxtOption.style.cursor = 'pointer';

    // 将文件菜单选项添加到文件下拉菜单
    fileMenu.appendChild(clearOption);
    fileMenu.appendChild(saveOption);
    fileMenu.appendChild(saveAsTxtOption);

    // 将文件按钮和文件下拉菜单添加到记事本容器
    noteContainer.appendChild(fileButton);
    noteContainer.appendChild(fileMenu);

    // 当鼠标悬停在文件按钮上时改变颜色
    fileButton.addEventListener('mouseenter', function() {
        fileButton.style.backgroundColor = '#e0e0e0';
    });

    // 当鼠标移出文件按钮时恢复颜色
    fileButton.addEventListener('mouseleave', function() {
        fileButton.style.backgroundColor = '#f0f0f0';
    });

    // 当点击文件按钮时显示或隐藏文件下拉菜单
    fileButton.addEventListener('click', function() {
        if (fileMenu.style.display === 'none') {
            fileMenu.style.display = 'block';
        } else {
            fileMenu.style.display = 'none';
        }
    });

// 当选择文件菜单中的选项时
fileMenu.addEventListener('click', function(event) {
    const selectedOption = event.target.textContent;
    if (selectedOption === '清除窗口内容') {
        noteTextarea.value = '';
    } else if (selectedOption === '保存') {
        saveNote();
    } else if (selectedOption === '保存为txt文件') {
        const note = noteTextarea.value;
        const noteWithNewLines = note.replace(/\n/g, '\r\n'); // 将换行符 \n 替换为 \r\n
        const blob = new Blob([noteWithNewLines], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        GM_download({
            url: url,
            name: 'note.txt'
        });
    }
    // 隐藏文件下拉菜单
    fileMenu.style.display = 'none';
});

    // 创建关闭按钮
    const closeButton = document.createElement('button');
    closeButton.innerHTML = '✖';
    closeButton.style.position = 'absolute';
    closeButton.style.top = '1px';
    closeButton.style.right = '1px';
    closeButton.style.padding = '5px 10px';
    closeButton.style.backgroundColor = '#f44336';
    closeButton.style.color = 'white';
    closeButton.style.border = 'none';
    closeButton.style.cursor = 'pointer';

    // 添加关闭按钮到记事本容器
    noteContainer.appendChild(closeButton);

    // 当点击关闭按钮时
    closeButton.addEventListener('click', function() {
        noteContainer.style.display = 'none';
    });

    // 监听键盘事件
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.altKey && event.key === 'n') {
            if (noteContainer.style.display === 'none') {
                noteContainer.style.display = 'block';
            } else {
                noteContainer.style.display = 'none';
            }
        }
    });

})();