有勇气的牛排博客

HTML 前端实现 contenteditable 可编辑元素及事件监听与基础属性教程

有勇气的牛排 992 前端 2024-11-25 21:02:18

html前端contenteditable实现元素可编辑

1 前言

1.1 定义

contenteditable="true" 是 HTML 中的一个属性,用于指定元素是否可被用户直接编辑。这个属性可以赋值为 "true""false" 或者省略(默认为 false)。

1.2 适用的 HTML 标签

  • <div>
  • <span>
  • <p>
  • <td>

1.3 应用场景

常用于文本编辑器、表单增强等场景。

2 属性说明

  1. true
    • 元素内容可编辑。
    • 可以通过键盘输入、鼠标操作、剪切板等方式修改内容。
  2. false
    • 元素内容不可编辑。
    • 即使父级元素为可编辑状态,设置 false 的子元素仍不可编辑。
  3. 省略值
    • 如果省略该属性,元素内容不可编辑(等同于 contenteditable="false")。

3 事件支持

事件说明和触发方式

事件 说明 触发方式
input 内容变化时触发(例如输入、删除内容)。 在可编辑区域输入或删除文本。
keydown 键盘按下时触发。 按下键盘任意按键。
keyup 键盘释放时触发。 松开按下的键盘按键。
focus 元素获得焦点时触发。 点击元素或使用 Tab 键聚焦到元素。
blur 元素失去焦点时触发。 点击页面其他位置或按 Tab 离开焦点。
paste 用户粘贴内容时触发。 使用快捷键 Ctrl+V 或右键选择粘贴。
copy 用户复制内容时触发。 使用快捷键 Ctrl+C 或右键选择复制。
cut 用户剪切内容时触发。 使用快捷键 Ctrl+X 或右键选择剪切。
mousedown 鼠标点击(按下)时触发。 按下鼠标左键、右键或中键。
mouseup 鼠标释放(抬起)时触发。 松开鼠标左键、右键或中键。
mousemove 鼠标在元素内移动时触发。 鼠标在可编辑区域内移动。
dragstart 拖拽操作开始时触发。 选中文本并拖动开始拖拽。
drop 放置拖拽的内容时触发。 将外部内容拖放到可编辑区域。

3.1 input 监听内容变化

<div id="edit_content" contenteditable="true" style="width: 500px; height:60px;line-height: 30px; border: 1px solid #ccc; border-radius: 5px;outline: none; " > 有勇氣的牛排contenteditable編輯屬性測試 </div> <script> const editContent = document.getElementById('edit_content'); // 1. 监听 `input` 事件 editContent.addEventListener('input', () => { console.log("=== 内容发生变化===") console.log('原生html:', editContent.innerHTML); console.log('原生文本:', editContent.innerText); }); </script>

image.png

image.png

3.2 keydown 键盘 按下

捕获键盘操作

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>keydown 事件</title> </head> <body> <div id="editable" contenteditable="true" style="border: 1px solid #ccc; padding: 10px; min-height: 50px;"> 有勇氣的牛排輸入測試: </div> <p><strong>事件日志:</strong></p> <ul id="log"></ul> <script> // 获取元素和日志显示区域 const editableDiv = document.getElementById('editable'); const logList = document.getElementById('log'); // 工具函数:记录事件日志 function logEvent(eventType, additionalInfo = '') { const listItem = document.createElement('li'); listItem.textContent = `${eventType} ${additionalInfo}`.trim(); logList.appendChild(listItem); } // 2. 监听 `keydown` 事件 editableDiv.addEventListener('keydown', (e) => { logEvent('Keydown 事件', `按下键:${e.key}`); }); // 限制日志长度,防止过多 function trimLog() { if (logList.children.length > 20) { logList.removeChild(logList.firstChild); } } setInterval(trimLog, 500); </script> </body> </html>

image.png

3.3 keyup 键盘松开

// 3. 监听 keyup 事件 editableDiv.addEventListener('keyup', (e) => { logEvent('Keyup 事件', `松开键:${e.key}`); });

image.png

3.4 focus 获取焦点

// 4. 监听 `focus` 事件 editableDiv.addEventListener('focus', () => { logEvent('Focus 事件', '元素获得焦点'); });

image20241126113639165.png

3.5 blur 失去焦点

// 5. 监听 `blur` 事件 editableDiv.addEventListener('blur', () => { logEvent('Blur 事件', '元素失去焦点'); });

image.png

3.6 paste 粘贴

// 6. 监听 paste 事件(粘贴内容) editableDiv.addEventListener('paste', (e) => { logEvent('Paste 事件', '用户粘贴了内容'); });

image.png

3.7 copy 复制内容

editableDiv.addEventListener('copy', (event) => { // 阻止默认行为以确保自定义逻辑可以生效 event.preventDefault(); // 获取复制的内容 const copiedText = window.getSelection().toString(); // 用户选中的文本 logEvent('Copy 事件', `复制的内容:${copiedText}`); // 可选:将内容写入剪贴板 if (event.clipboardData) { event.clipboardData.setData('text/plain', copiedText); } });

image.png

3.8 cut 剪切

// 8. 监听 `cut` 事件(剪切内容) editableDiv.addEventListener('cut', (event) => { // 阻止默认剪切行为 event.preventDefault(); // 获取用户选中的内容 const selectedText = window.getSelection().toString(); // 如果没有选中内容,则直接返回 if (!selectedText) { return; } // 自定义剪切内容(示例:添加前缀) const customText = `${selectedText}`; // 将内容写入剪贴板 if (event.clipboardData) { event.clipboardData.setData('text/plain', customText); } // 删除选中的内容 const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); // 获取选区范围 range.deleteContents(); // 从 DOM 中移除选区内容 } // 记录日志 logEvent('Cut 事件', `剪切的内容:${customText}`); });

image.png

3.9 mousedown 鼠标点击事件

// 监听 mousedown 事件 editableDiv.addEventListener('mousedown', (e) => { const buttonType = e.button === 0 ? '左键' : e.button === 1 ? '中键' : '右键'; const { clientX, clientY } = e; // 点击的坐标 const clickedContent = e.target.innerText.trim(); // 点击时的内容 const selectedText = window.getSelection().toString(); // 当前选中的文本 // 记录事件信息 logEvent('Mousedown 事件', `按钮:${buttonType}, 坐标:(${clientX}, ${clientY}), 内容:${clickedContent}, 选中文本:${selectedText || '无'}`); });

image.png

3.10 mouseup 鼠标释放

// 10. 监听 mouseup 事件(鼠标释放) editableDiv.addEventListener('mouseup', (e) => { logEvent('Mouseup 事件', `鼠标释放,按钮:${e.button}`); });

3.11 mousemove 鼠标移动

// 11. 监听 mousemove 事件(鼠标移动) editableDiv.addEventListener('mousemove', () => { logEvent('Mousemove 事件', '鼠标正在移动'); });

案例

// 监听 mousemove 事件 let startX = null; // 起点 X 坐标 let startY = null; // 起点 Y 坐标 editableDiv.addEventListener('mousemove', (e) => { const {clientX, clientY} = e; // 当前坐标 if (startX === null || startY === null) { startX = clientX; startY = clientY; // 初始化起点 } const distanceX = clientX - startX; // X 方向移动距离 const distanceY = clientY - startY; // Y 方向移动距离 logEvent( 'Mousemove 事件', `起点:(${startX}, ${startY}), 当前坐标:(${clientX}, ${clientY}), 移动距离:(${distanceX}, ${distanceY})` ); }); // 监听 mouseup 事件,重置起点坐标 editableDiv.addEventListener('mouseup', () => { logEvent('Mouseup 事件', `结束坐标:(${startX}, ${startY})`); startX = null; startY = null; });

image.png

3.12 dragstart 开始拖拽

// 12. 监听 `dragstart` 事件(开始拖拽) editableDiv.addEventListener('dragstart', () => { logEvent('Dragstart 事件', '拖拽开始'); });

3.13 监听 drop 事件(拖拽放置)

// 13. 监听 `drop` 事件(拖拽放置) editableDiv.addEventListener('drop', () => { logEvent('Drop 事件', '放置拖拽的内容'); });

留言

专栏
文章
加入群聊