【html word富文本编辑器 gemini3pro】

还有很多的bugs,能简单的用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网页版富文本编辑器 (类Word)</title>
    <!-- 引入 FontAwesome 图标库 (需要联网,为了界面美观) -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        :root {
            --primary-color: #2b579a; /* Word 蓝 */
            --hover-bg: #f0f0f0;
            --border-color: #ccc;
            --toolbar-bg: #f3f2f1;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #eef2f5;
            display: flex;
            flex-direction: column;
            height: 100vh;
        }

        /* --- 工具栏区域 --- */
        .toolbar-container {
            background-color: var(--toolbar-bg);
            border-bottom: 1px solid var(--border-color);
            padding: 8px 15px;
            display: flex;
            flex-wrap: wrap;
            gap: 5px;
            align-items: center;
            position: sticky;
            top: 0;
            z-index: 1000;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        }

        .tool-group {
            display: flex;
            align-items: center;
            border-right: 1px solid #ddd;
            padding-right: 10px;
            margin-right: 5px;
            gap: 2px;
        }
        .tool-group:last-child {
            border-right: none;
        }

        button {
            background: transparent;
            border: 1px solid transparent;
            cursor: pointer;
            padding: 6px 8px;
            border-radius: 3px;
            font-size: 14px;
            color: #333;
            transition: all 0.2s;
        }

        button:hover {
            background-color: #e1dfdd;
        }

        button.active {
            background-color: #cdaec7; /* 选中状态稍有不同 */
            background-color: #d1e0f3;
            color: var(--primary-color);
            border-color: #b3d7ff;
        }

        select {
            padding: 5px;
            border: 1px solid transparent;
            border-radius: 3px;
            background: transparent;
            cursor: pointer;
        }
        select:hover {
            background-color: #e1dfdd;
        }

        /* 颜色选择器特殊处理 */
        .color-wrapper {
            position: relative;
            display: flex;
            align-items: center;
        }
        input[type="color"] {
            width: 20px;
            height: 20px;
            border: none;
            padding: 0;
            background: transparent;
            cursor: pointer;
            margin-left: -25px; 
            opacity: 0; /* 隐藏原生控件,覆盖在图标上 */
            z-index: 2;
        }
        .color-icon {
            pointer-events: none;
        }

        /* --- 编辑区域 (模拟 A4 纸) --- */
        .editor-workspace {
            flex: 1;
            overflow-y: auto;
            padding: 30px 0;
            display: flex;
            justify-content: center;
        }

        #editor {
            background-color: white;
            width: 210mm; /* A4 宽度 */
            min-height: 297mm; /* A4 高度 */
            padding: 25mm; /* 页边距 */
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            outline: none;
            box-sizing: border-box;
            font-size: 16px;
            line-height: 1.6;
            color: #000;
        }

        /* 打印时的样式 */
        @media print {
            body {
                background: white;
                height: auto;
                display: block;
            }
            .toolbar-container {
                display: none;
            }
            .editor-workspace {
                padding: 0;
                display: block;
            }
            #editor {
                width: 100%;
                min-height: auto;
                box-shadow: none;
                padding: 0;
                margin: 0;
            }
        }

        /* 图片样式控制 */
        #editor img {
            max-width: 100%;
            height: auto;
            cursor: pointer;
        }
        #editor blockquote {
            border-left: 4px solid var(--primary-color);
            margin: 0;
            padding-left: 15px;
            color: #666;
            background: #f9f9f9;
            padding: 10px;
        }
        #editor hr {
            border: 0;
            border-top: 1px solid #ccc;
            margin: 20px 0;
        }
    </style>
</head>
<body>

    <!-- 工具栏 -->
    <div class="toolbar-container">
        <!-- 常用操作 -->
        <div class="tool-group">
            <button onclick="execCmd('undo')" title="撤销"><i class="fa-solid fa-rotate-left"></i></button>
            <button onclick="execCmd('redo')" title="重做"><i class="fa-solid fa-rotate-right"></i></button>
            <button onclick="execCmd('removeFormat')" title="清除格式"><i class="fa-solid fa-eraser"></i></button>
        </div>

        <!-- 字体设置 -->
        <div class="tool-group">
            <select onchange="execCmd('formatBlock', this.value)" title="标题格式">
                <option value="P">正文</option>
                <option value="H1">标题 1</option>
                <option value="H2">标题 2</option>
                <option value="H3">标题 3</option>
                <option value="BLOCKQUOTE">引用</option>
            </select>
            <select onchange="execCmd('fontName', this.value)" title="字体">
                <option value="Arial">Arial</option>
                <option value="'Microsoft YaHei', sans-serif">微软雅黑</option>
                <option value="'SimSun', serif">宋体</option>
                <option value="'Courier New', monospace">等宽字体</option>
            </select>
            <select onchange="execCmd('fontSize', this.value)" title="字号">
                <option value="3">正常</option>
                <option value="1">小号</option>
                <option value="4">中大</option>
                <option value="5">大号</option>
                <option value="6">特大</option>
                <option value="7">超大</option>
            </select>
        </div>

        <!-- 文本样式 -->
        <div class="tool-group">
            <button onclick="execCmd('bold')" title="加粗"><i class="fa-solid fa-bold"></i></button>
            <button onclick="execCmd('italic')" title="斜体"><i class="fa-solid fa-italic"></i></button>
            <button onclick="execCmd('underline')" title="下划线"><i class="fa-solid fa-underline"></i></button>
            <button onclick="execCmd('strikeThrough')" title="删除线"><i class="fa-solid fa-strikethrough"></i></button>
        </div>

        <!-- 颜色 -->
        <div class="tool-group">
            <div class="color-wrapper" title="字体颜色">
                <button class="color-icon"><i class="fa-solid fa-font" style="color:red; border-bottom: 3px solid red;"></i></button>
                <input type="color" onchange="execCmd('foreColor', this.value)">
            </div>
            <div class="color-wrapper" title="背景高亮">
                <button class="color-icon"><i class="fa-solid fa-highlighter" style="color:orange; border-bottom: 3px solid orange;"></i></button>
                <input type="color" onchange="execCmd('hiliteColor', this.value)" value="#ffff00">
            </div>
        </div>

        <!-- 对齐方式 -->
        <div class="tool-group">
            <button onclick="execCmd('justifyLeft')" title="左对齐"><i class="fa-solid fa-align-left"></i></button>
            <button onclick="execCmd('justifyCenter')" title="居中"><i class="fa-solid fa-align-center"></i></button>
            <button onclick="execCmd('justifyRight')" title="右对齐"><i class="fa-solid fa-align-right"></i></button>
            <button onclick="execCmd('justifyFull')" title="两端对齐"><i class="fa-solid fa-align-justify"></i></button>
        </div>

        <!-- 列表与缩进 -->
        <div class="tool-group">
            <button onclick="execCmd('insertUnorderedList')" title="无序列表"><i class="fa-solid fa-list-ul"></i></button>
            <button onclick="execCmd('insertOrderedList')" title="有序列表"><i class="fa-solid fa-list-ol"></i></button>
            <button onclick="execCmd('indent')" title="增加缩进"><i class="fa-solid fa-indent"></i></button>
            <button onclick="execCmd('outdent')" title="减少缩进"><i class="fa-solid fa-outdent"></i></button>
        </div>

        <!-- 插入元素 -->
        <div class="tool-group">
            <button onclick="insertLink()" title="插入链接"><i class="fa-solid fa-link"></i></button>
            <button onclick="triggerImageUpload()" title="插入图片"><i class="fa-regular fa-image"></i></button>
            <button onclick="execCmd('insertHorizontalRule')" title="插入分割线"><i class="fa-solid fa-minus"></i></button>
            <!-- 隐藏的文件上传 input -->
            <input type="file" id="imageInput" accept="image/*" style="display: none;" onchange="handleImageUpload(this)">
        </div>

        <!-- 文件操作 -->
        <div class="tool-group" style="margin-left: auto; border: none;">
            <button onclick="exportHTML()" title="导出为HTML"><i class="fa-solid fa-download"></i> 导出</button>
            <button onclick="window.print()" title="打印"><i class="fa-solid fa-print"></i></button>
        </div>
    </div>

    <!-- 编辑区域 -->
    <div class="editor-workspace" onclick="focusEditor()">
        <div id="editor" contenteditable="true">
            <h1>欢迎使用简易网页版文档编辑器</h1>
            <p>这是一个<b>类似 Word</b> 的富文本编辑区域。</p>
            <p>你可以直接在这里输入文字,或者使用上方的工具栏进行格式化。</p>
            <ul>
                <li>支持加粗、斜体、下划线</li>
                <li>支持插入图片(自动转为 Base64 编码,随文件保存)</li>
                <li>支持导出为 HTML 文件</li>
            </ul>
            <p>请试着编辑这段文字...</p>
        </div>
    </div>

    <script>
        // 核心命令执行函数
        function execCmd(command, value = null) {
            // 重新聚焦编辑器,确保命令执行在正确位置
            document.getElementById('editor').focus();
            // 执行浏览器内置的编辑命令
            document.execCommand(command, false, value);
            updateButtonStates();
        }

        // 插入链接
        function insertLink() {
            const url = prompt("请输入链接地址 (如 https://www.example.com):", "http://");
            if (url) {
                execCmd('createLink', url);
            }
        }

        // 触发图片上传
        function triggerImageUpload() {
            document.getElementById('imageInput').click();
        }

        // 处理图片上传 (转为 Base64 以便在一个文件中保存)
        function handleImageUpload(input) {
            if (input.files && input.files[0]) {
                const reader = new FileReader();
                reader.onload = function (e) {
                    // 插入图片到光标位置
                    execCmd('insertImage', e.target.result);
                };
                reader.readAsDataURL(input.files[0]);
            }
            // 清空 input 防止重复上传同一张图不触发 onchange
            input.value = '';
        }

        // 导出为 HTML 文件
        function exportHTML() {
            const content = document.getElementById('editor').innerHTML;
            const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>导出的文档</title>
<style>
    body { font-family: sans-serif; max-width: 800px; margin: 20px auto; padding: 20px; line-height: 1.6; }
    img { max-width: 100%; height: auto; }
    blockquote { border-left: 4px solid #ccc; margin: 0; padding-left: 15px; color: #666; }
</style>
</head>
<body>
${content}
</body>
</html>`;
            
            const blob = new Blob([html], { type: 'text/html' });
            const a = document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = 'document.html';
            a.click();
        }

        // 点击灰色背景聚焦到编辑器
        function focusEditor() {
            // 只有点击的不是编辑器本身时才聚焦
            if(event.target.classList.contains('editor-workspace')) {
               document.getElementById('editor').focus(); 
            }
        }

        // 更新按钮激活状态 (简单的 UX 优化)
        const editor = document.getElementById('editor');
        const buttons = document.querySelectorAll('button[onclick^="execCmd"]');

        function updateButtonStates() {
            // 这是一个简化的状态检测,document.queryCommandState 可以检测当前光标位置是否应用了某种样式
            buttons.forEach(btn => {
                const cmd = btn.getAttribute('onclick').match(/'([^']+)'/)[1];
                try {
                    if (document.queryCommandState(cmd)) {
                        btn.classList.add('active');
                    } else {
                        btn.classList.remove('active');
                    }
                } catch (e) {
                    // 某些命令不支持 queryCommandState,忽略
                }
            });
        }

        // 监听键盘和鼠标事件以更新工具栏状态
        editor.addEventListener('keyup', updateButtonStates);
        editor.addEventListener('mouseup', updateButtonStates);
        editor.addEventListener('click', updateButtonStates);
        
        // 初始化
        document.getElementById('editor').focus();
    </script>
</body>
</html>
相关推荐
xhxxx5 小时前
别再被 CSS 定位搞晕了!5 种 position 一图打尽 + 实战代码全公开
前端·css·html
wangbing11255 小时前
将swagger在线文档转为word
microsoft·c#·word
询问QQ688238866 小时前
基于偏最小二乘算法(PLS)的多输出数据回归预测
html
挫折常伴左右8 小时前
初见HTML
前端·html
kiki-bf21 小时前
使用python把图片转为word
开发语言·python·word
一水鉴天1 天前
整体设计 定稿 之24 dashboard.html 增加三层次动态记录体系仪表盘 之2 程序 (Q208 之1)
前端·html
一水鉴天1 天前
整体设计 定稿 之22 dashboard.html 增加三层次动态记录体系仪表盘 之1
前端·html
开开心心_Every1 天前
Word转PDF工具,免费生成图片型文档
网络·笔记·pdf·word·powerpoint·excel·azure
dlhto1 天前
Markdown转Word操作指南
linux·centos·word
沟通QQ8762239651 天前
有限元仿真模型仿真模型-基于COMSOL多物理场耦合仿真的变压器流固耦合及振动噪声分析 1、变...
html