基于HTML的悬窗可拖动记事本

基于HTML的悬窗可拖动记事本

这款记事本全部使用HTML+CSS+JS实现,可以在浏览器中实现悬浮可拖动的记事本,所有内容存储在浏览器中,清除缓存后将会丢失记事本内容

效果展示
实现代码
复制代码
<div id="draggableWindowNote" class="draggableNote">
    <div id="dragHeaderNote" class="drag-headerNote">
        <span>Note</span>
        <div id="addNote" style="font-size: 19px;
        cursor: pointer;
        position: absolute;
        right: 0;
margin-right: 10px;">+</div>
    </div>

    <div id="noteApp">
        <div class="note-header">
        </div>
        <div id="noteList"></div>

        <div id="noteModal" class="modal">
            <div class="modal-content">
                <div class="modal-header">
                    <span class="close" style="float: left;">&times;</span>
                    <div
                        style="position: absolute; right: 0; top: 0; height: 100%; width: 78px; background-color: transparent;">
                    </div>
                </div>
                <textarea id="noteEditor"></textarea>
                <button id="saveNote"
                    style="cursor: pointer;border: none;background: transparent;font-weight: 900;">保存</button>
                <button id="deleteNote" class="delete-btn"
                    style="cursor: pointer;border: none;background: transparent;font-weight: 900;">删除</button>
            </div>
        </div>


    </div>
</div>

<!-- 沂霖博客 https://nanwish.love -->

<script>
    // 拖动逻辑
    const draggableWindow = document.getElementById('draggableWindowNote');
    const dragHeader = document.getElementById('dragHeaderNote');
    let isDragging = false;
    let offsetX, offsetY;
    dragHeader.addEventListener('mousedown', (e) => {
        isDragging = true;
        offsetX = e.clientX - draggableWindow.offsetLeft;
        offsetY = e.clientY - draggableWindow.offsetTop;
    });
    document.addEventListener('mousemove', (e) => {
        if (isDragging) {
            draggableWindow.style.left = (e.clientX - offsetX) + 'px';
            draggableWindow.style.top = (e.clientY - offsetY) + 'px';
        }
    });
    document.addEventListener('mouseup', () => {
        isDragging = false;
    });



</script>


<style>
    body {
        margin: 0;
        padding: 0;
        font-family: Arial, sans-serif;
        background-color: #575757;
        color: #ffffff;
    }

    .draggableNote {
        position: absolute;
        width: 200px;
        background-color: #242424;
        border-radius: 4px;
        box-shadow: 0 2px 10px rgba(168, 168, 168, 0.1);
        z-index: 1000;

    }

    .drag-headerNote {
        background-color: #000000;
        border-bottom: 1px solid #1be409;
        cursor: move;

        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
    }

    .chinaImg {
        width: 100%;
        max-width: 100%;
        max-height: 128px;
    }

    #noteApp {
        max-width: 600px;
        margin: 0 auto;
    }

    .note-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }


    .note-item {
        padding: 3px;
        border-bottom: 1px solid #eee;
        cursor: pointer;
    }

    .note-item:hover {
        background-color: #f5f5f5;
    }

    .note-title {
        font-weight: bold;
    }

    .note-content {
        display: none;
        margin-top: 10px;
        padding: 10px;
        background-color: #f9f9f9;
        border-radius: 3px;
    }

    .modal {
        display: none;
        position: fixed;
        z-index: 1;
        left: 0;
        top: 0;
        width: 100%;
        height: 1px;
    }

    .modal-content {
        background-color: transparent;
        margin: 15% auto;
        width: 80%;
        max-width: 500px;
    }

    #noteEditor {
        width: 100%;
        height: 200px;
        margin-bottom: 10px;
        border-radius: 17px;
        border: none;
        padding: 8px;
    }

    .close {
        color: #aaa;
        float: right;
        font-size: 28px;
        font-weight: bold;
        cursor: pointer;
        position: relative;
        z-index: 9;
    }

    .close:hover {
        color: black;
    }

    .delete-btn {
        color: rgb(255, 0, 0);
    }

    .modal-header {
        padding: 10px;
        cursor: move;
        position: relative;
        display: flex;
        flex-direction: row-reverse;
        align-items: center;
        justify-content: flex-start;
    }
</style>
<script>
    let notes = JSON.parse(localStorage.getItem('notes')) || [];
    let currentNoteIndex = -1;
    const noteList = document.getElementById('noteList');
    const noteModal = document.getElementById('noteModal');
    const noteEditor = document.getElementById('noteEditor');
    const addNoteBtn = document.getElementById('addNote');
    const saveNoteBtn = document.getElementById('saveNote');
    const deleteNoteBtn = document.getElementById('deleteNote');
    const closeBtn = document.querySelector('.close');

    function renderNotes() {
        noteList.innerHTML = '';
        notes.forEach((note, index) => {
            const noteItem = document.createElement('div');
            noteItem.className = 'note-item';

            // 截取前10个字符作为标题
            const title = note.content.substring(0, 10);

            noteItem.innerHTML = `
                <div class="note-title">${title}...</div>
                <div class="note-content">${note.content}</div>
            `;


            noteItem.addEventListener('click', () => {
                currentNoteIndex = index;
                noteEditor.value = note.content;
                noteModal.style.display = 'block';
            });

            noteList.appendChild(noteItem);
        });
    }

    // 新增笔记
    addNoteBtn.addEventListener('click', () => {
        currentNoteIndex = -1;
        noteEditor.value = '';
        noteModal.style.display = 'block';
    });

    // 保存笔记
    saveNoteBtn.addEventListener('click', () => {
        const content = noteEditor.value.trim();
        if (content) {
            if (currentNoteIndex === -1) {
                // 新增
                notes.push({ content });
            } else {
                // 编辑
                notes[currentNoteIndex].content = content;
            }

            localStorage.setItem('notes', JSON.stringify(notes));
            renderNotes();
            noteModal.style.display = 'none';
        }
    });

    // 删除笔记
    deleteNoteBtn.addEventListener('click', () => {
        if (currentNoteIndex !== -1) {
            notes.splice(currentNoteIndex, 1);
            localStorage.setItem('notes', JSON.stringify(notes));
            renderNotes();
            noteModal.style.display = 'none';
        }
    });

    // 关闭模态框
    closeBtn.addEventListener('click', () => {
        noteModal.style.display = 'none';
    });
    // 初始化
    renderNotes();


    // 模态框拖动功能
    const modal = document.getElementById('noteModal');
    const modalHeader = document.querySelector('.modal-header');
    let isModalDragging = false;
    let modalOffsetX, modalOffsetY;
    modalHeader.addEventListener('mousedown', (e) => {
        isModalDragging = true;
        modalOffsetX = e.clientX - modal.offsetLeft;
        modalOffsetY = e.clientY - modal.offsetTop;
    });
    document.addEventListener('mousemove', (e) => {
        if (isModalDragging) {
            modal.style.left = (e.clientX - modalOffsetX) + 'px';
            modal.style.top = (e.clientY - modalOffsetY) + 'px';
        }
    });
    document.addEventListener('mouseup', () => {
        isModalDragging = false;
    });
</script>
相关推荐
kyriewen9 小时前
Anthropic 估值逼近万亿美元,Claude Sonnet 5 + Claude Science 一天两连发
前端·ai编程·claude
小徐_233311 小时前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
天蓝色的鱼鱼13 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷14 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花14 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷14 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜14 小时前
Spring Boot 核心知识点总结
前端
lichenyang45314 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕14 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js