手写富文本编辑器(Vanilla简单实现)

一般写文章都是用一些md编辑器,例如typora,notion等等 有时候记不住快捷键就得选中需要格式化的内容格式化

索性手写一个文本编辑器demo ,直接上效果, 最后附完整代码 

Img

引用图标库

使用方法就是搜索需要的图标然后复制样式就行

Img

 

Img

html结构

结构非常简单

设置div属性contenteditable="true", 成为一个可编辑的富文本区域,可以在其中输入文本、执行编辑命令等

<div class="container">
    <div class="options">
        <button id="bold" class="option-button format">
            <i class="fa-solid fa-bold"></i>
        </button>
        <select id="fontSize" class="adv-option-button"></select>
        <div class="input-wrapper">
            <input type="color" id="foreColor" class="adv-option-button" />
            <label for="foreColor">字体颜色</label>
        </div>
        <!-- 其他options -->
    </div>
    <div id="text-input"  contenteditable="true"></div>
</div>

主要css样式

样式也很简单

  • width: 90vmin; viewport minimum 元素的宽度将占据视口宽度和高度中较小的那个的90%
  • position: absolute; 定义left top transform 实现绝对定位居中
  • flex-wrap: wrap; flex容器可换行
  • input[type='color']::-webkit-color-swatch 定义颜色选择器的style,为了兼容还可再定义 ::-moz-color-swatch
.container {
	background-color: #fff;
	width: 90vmin;
	padding: 50px 30px;
	position: absolute;
	transform: translate(-50%, -50%);
	left: 50%;
	top: 50%;
	border-radius: 10px;
	box-shadow: 0 25px 50px rgba(7, 20, 35, 0.2);
}
.options {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 15px;
}
input[type='color']::-webkit-color-swatch {
	border-radius: 15px;
	box-shadow: 0 0 0 2px #fff, 0 0 0 3px #020929;
}

js部分

标记图标高亮 highlighter
  • className 是包含按钮类名的数组,needsRemoval 表示是否需要删除高亮;按钮被点击时添加或移除相应的类名,从而实现按钮的高亮效果
  • 如果 needsRemovaltrue,则在添加新的高亮类名之前调用highlighterRemover移除其他按钮上的高亮类名,确保每次只有一个按钮被高亮 如果按钮没有active样式,就添加它;如果有,就移除它
  • 如果 needsRemovalfalse,则按钮的高亮状态将会切换
const highlighter = (className, needsRemoval) => {
	className.forEach(button => {
		button.addEventListener('click', () => {
			if (needsRemoval) {
				highlighterRemover(className)
				button.classList.toggle('active', !button.classList.contains('active'))
			} else {
				button.classList.toggle('active')
			}
		})
	})
}
const highlighterRemover = className => {
	className.forEach(button => {
		button.classList.remove('active')
	})
}
intializer
  • 相同类名的button调用highlighter
  • fontListfontSizeRef添加option
let alignButtons = document.querySelectorAll(".align");
let spacingButtons = document.querySelectorAll(".spacing");
let formatButtons = document.querySelectorAll(".format");
let scriptButtons = document.querySelectorAll(".script");
let fontName = document.getElementById("fontName");
let fontSizeRef = document.getElementById("fontSize");
const fontList = [ "Arial", "Verdana",  "Times New Roman", "Garamond", "Georgia", "Courier New", "Cursive"];
const intializer = () => {
    highlighter(formatButtons, false);
    highlighter(alignButtons, true);
    highlighter(spacingButtons, true);
    highlighter(scriptButtons, true);
    fontList.map((value) => {
        let fontStyleOption = document.createElement("option");
        fontStyleOption.value = value;
        fontStyleOption.innerHTML = value;
        fontName.appendChild(fontStyleOption);
    });
    for (let i = 1; i <= 7; i++) {
        let fontSizeOption = document.createElement("option");
        fontSizeOption.value = i;
        fontSizeOption.innerHTML = i;
        fontSizeRef.appendChild(fontSizeOption);
    }
    fontSizeRef.value = 3; // 默认值为3
};
监听button事件
  • document.execCommand有三个参数 :commandId 表示要执行的编辑命令的id标识符,defaultUi 是一个布尔值,表示是否显示用户界面,value 是可选的参数,表示执行命令时可能需要的值
  • 分别给 optionsButtons advancedOptionButton linkButton 监听click或change事件
  • /^https?:\/\//i.test(link) 匹配link是否以http://或者https://
const modifyText = (commandId, defaultUi, value) => {
	document.execCommand(commandId, defaultUi, value)
}
optionsButtons.forEach(button => {
	button.addEventListener('click', () => {
		modifyText(button.id, false, null)
	})
})
advancedOptionButton.forEach(button => {
	button.addEventListener('change', () => {
		modifyText(button.id, false, button.value)
	})
})
linkButton.addEventListener('click', () => {
	let link = prompt('输入链接')
	if (link) {
		if (!/^https?:\/\//i.test(link)) {
			link = 'http://' + link
		}
		console.log(link)
		modifyText(linkButton.id, false, link)
	}
})

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值