简易版编辑器的实现

256 阅读2分钟

简易版编辑器的实现

通过使用浏览器原生的ContentEditable编辑模式来实现。目前绝大数现有的富文本编辑器都是使用该方式

contenteditable="true"

contenteditable="true"是 HTML 中的一个属性。它可以应用于 HTML 元素,使得该元素的内容变成可编辑状态。这为在网页上创建可编辑区域提供了一种简单直接的方法,而不需要复杂的 JavaScript 库或插件;

浏览器兼容性:contenteditable属性在现代主流浏览器(如 Chrome、Firefox、Safari、Edge)中都有很好的支持。不过,在一些旧版本的浏览器中可能会存在一些差异或不兼容的情况。在开发过程中,如果需要支持较旧的浏览器,可能需要进行额外的测试和兼容性处理。例如,在某些旧版本的 IE 浏览器中,对contenteditable元素的样式和事件处理可能会有一些特殊要求。

应用场景

  • 网页内文本编辑:例如,在一个在线文档编辑网页中,可以将<div><p>等元素设置为contenteditable="true",这样用户就能够直接在网页上修改这些元素中的文本内容,就像在使用一个简单的文本编辑器。
  • 富文本编辑基础构建块:它是构建简单富文本编辑器的基础。虽然它本身提供的只是基本的文本编辑功能,但可以通过结合 CSS 样式和 JavaScript 事件来扩展其功能,比如添加格式设置(如加粗、斜体)、插入图片等功能。

使用案例--掘金沸点

通过控制台,可以看到掘金沸点的代码,在代码中可以看到掘金的实现方式contenteditable="true" contenteditable属性可以指定元素内容是否可编辑。 image.png

与Javascript配合使用

  • 可以通过事件监听contenteditable元素
  • 可以获取contenteditable元素中的内容,对内容进行操作
  • 可以修改contenteditable元素的样式
let edit = document.getElementById('edit'); 
// 用户在可编辑元素中输入内容时,会触发input事件
edit.addEventListener('input', function() { 
    console.log('内容变化了');
});

console.log(edit.textContent); // 获取元素中的内容

实现简易版的编辑器

<script setup lang="ts">
const format = (type) => {
    const selection = window.getSelection(); // 光标
    console.log(selection,'selection');
    const range = selection.getRangeAt(0); //获取选区的内容
    console.log(range,'range');

    const dom = range.extractContents(); // 将选区的内容提取出来
    console.log(dom,'dom');
    let wrapper;
    switch(type){
        case 'bold':
            wrapper = document.createElement('b');
            break;
        case 'italic':
            wrapper = document.createElement('i');
            break;
        case 'underline':
            wrapper = document.createElement('u');  
            break; 
        case 'h1':
            wrapper = document.createElement('h1');  
            break;  
        case 'h2':
            wrapper = document.createElement('h2');
            break;
        case 'h3':
            wrapper = document.createElement('h3');  
            break;
        case 'text':
            wrapper = document.createElement('p');  
            break;  
        
    }

    wrapper.appendChild(dom);
    range.insertNode(wrapper);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);

}
</script>

<template>
    <button @click="format('bold')">加粗</button>
    <button @click="format('italic')">斜体</button>
    <button @click="format('underline')">下划线</button>
    <select @change="format($event.target.value)" class="select">
        <option disabled selected value="">请选择</option>
        <option value="text">P</option>
        <option value="h1">H1</option>
        <option value="h2">H2</option>
        <option value="h3">H3</option>
    </select>
    <div class="editor-wrapper" contenteditable="true"> </div>
</template>

<style scoped>
.editor-wrapper{
    width: 100%;
    height: 300px;
    border: 1px solid black;
    color:black
}
.select{
    border-radius: 8px;
    padding: 0.6em 1.2em;
    font-size: 1em;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.25s;
}
</style>

image.png