
?前言
大家好,我是yma16,本文分享關(guān)于前端 富文本編輯器原理——從javascript、html、css開始。
富文本編輯器
富文本編輯器是指具有格式化文本和圖像編輯功能的文本編輯器
參考文檔:https://w3c.github.io/selection-api/#abstract
?html的contenteditable屬性
全局屬性 contenteditable 是一個(gè)枚舉屬性,表示元素是否可被用戶編輯。如果可以,瀏覽器會(huì)修改元素的組件以允許編輯。
- contenteditable boolean (false | true) 默認(rèn)false
簡(jiǎn)單理解,加上contenteditable ,html可以編輯具有input 輸入的基本功能,所見即所得。
例:
html demo 標(biāo)簽配置contenteditable
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>富文本編輯器</title>
</head>
<style>
blockquote {
background: #eee;
border-radius: 5px;
margin: 16px 0;
}
blockquote p {
padding: 15px;
}
cite {
margin: 16px 32px;
font-weight: bold;
}
blockquote p::before {
content: '\201C';
}
blockquote p::after {
content: '\201D';
}
[contenteditable='true'] {
caret-color: red;
}
</style>
<body>
<blockquote contenteditable="true">
<p>Edit this content to add your own quote</p>
</blockquote>
<cite contenteditable="true">-- Write your own name here</cite>
</body>
</html>
效果如下,可以輸入編輯html元素:
?? 輸入的光標(biāo)位置(瀏覽器獲取selection)
getSelection() method
GetSelection ()方法返回一個(gè) Selection 對(duì)象,該對(duì)象表示用戶選擇的文本范圍或插入符號(hào)的當(dāng)前位置。
?使用Selection.toString () 返回指定的文本
例:
<body>
<blockquote contenteditable="true">
<p>Edit this content to add your own quote</p>
</blockquote>
<cite contenteditable="true">-- Write your own name here</cite>
<button onclick="printSelection()">console.log(getSelection)</button>
</body>
<script type="text/javascript">
const printSelection=()=>{
const selection=window.getSelection()
console.log('selection',selection)
console.log('selection.toString()',selection.toString())
}
</script>
效果如下:
?getRangeAt 獲取指定索引范圍
函數(shù)接受一個(gè)索引值
返回,其中
結(jié)束的索引值,endOffset
開始的索引值,startOffset
效果如下圖:
?? 修改光標(biāo)位置
調(diào)用 setStart() 和 setEnd() 方法,來(lái)修改一個(gè)光標(biāo)的位置或拖藍(lán)范圍
Range.setStart()
Range.setStart() 方法用于設(shè)置 Range的開始位置。
如果起始節(jié)點(diǎn)類型是 Text、Comment 或 CDATASection之一,那么 startOffset 指的是從起始節(jié)點(diǎn)算起字符的偏移量。對(duì)于其他 Node 類型節(jié)點(diǎn),startOffset 是指從起始結(jié)點(diǎn)開始算起子節(jié)點(diǎn)的偏移量。
如果設(shè)置的起始位點(diǎn)在結(jié)束點(diǎn)之下(在文檔中的位置),將會(huì)導(dǎo)致選區(qū)折疊,起始點(diǎn)和結(jié)束點(diǎn)都會(huì)被設(shè)置為指定的起始位置。
startNode
startNode 用于設(shè)定 Range的起始位置。
startOffset
必須為不小于 0 的整數(shù)。表示從startNode的開始位置算起的偏移量。
Range.setEnd()
Range.setEnd()
方法用于設(shè)置 Range的結(jié)束位置。
如果結(jié)束節(jié)點(diǎn)類型是 Text、Comment 或 CDATASection之一,那么 endOffset 指的是從結(jié)束節(jié)點(diǎn)算起字符的偏移量。對(duì)于其他 Node 類型節(jié)點(diǎn),endOffset 是指從結(jié)束結(jié)點(diǎn)開始算起子節(jié)點(diǎn)的偏移量。
如果設(shè)置的結(jié)束點(diǎn)在起始點(diǎn)之上(在文檔中的位置),將會(huì)導(dǎo)致選區(qū)折疊,起始點(diǎn)和結(jié)束點(diǎn)都會(huì)被設(shè)置為指定的結(jié)束位置。
endNode
endNode用于設(shè)定 Range的結(jié)束位置。
endOffset
必須為不小于 0 的整數(shù)。表示從endNode的結(jié)束位置算起的偏移量。
語(yǔ)法
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);
例:
點(diǎn)擊不失去焦點(diǎn)跳轉(zhuǎn)開始和結(jié)束,避免失去焦點(diǎn)使用preventDefault
<body>
<blockquote contenteditable="true">
<p>Edit this content to add your own quote</p>
</blockquote>
<cite contenteditable="true">-- Write your own name here</cite>
<button onclick="printSelection()">console.log(getSelection)</button>
<button id='start-id'>jumpt start</button>
<button id='end-id'>jumpt end</button>
</body>
<script type="text/javascript">
function printSelection() {
const selection = window.getSelection()
console.log('selection', selection)
console.log('selection.toString()', selection.toString())
console.log('selection.getRangeAt(0)', selection.getRangeAt(0))
}
function jumpStart() {
let range = window.getSelection().getRangeAt(0);
let textEle = range.commonAncestorContainer;
range.setStart(range.startContainer, 0);
range.setEnd(range.startContainer, 0);
}
function jumpEnd() {
let range = window.getSelection().getRangeAt(0);
let textEle = range.commonAncestorContainer;
range.setStart(range.startContainer, textEle.length);
range.setEnd(range.endContainer, textEle.length);
}
window.onload = function() {
document.getElementById('start-id').addEventListener('click', function(e) {
jumpStart()
})
document.getElementById('start-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
document.getElementById('end-id').addEventListener('click', function(e) {
jumpEnd()
})
document.getElementById('end-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
}
</script>
效果如下圖:
?? 設(shè)置選取range
Selection.addRange()
概述
向選區(qū)(Selection)中添加一個(gè)區(qū)域(Range)。
語(yǔ)法
sel.addRange(range)
例子:
失去焦點(diǎn)之后恢復(fù)選區(qū)
<body>
<blockquote contenteditable="true">
<p>Edit this content to add your own quote</p>
<b>yma16</b>
</blockquote>
<cite contenteditable="true">-- Write your own name here</cite>
<br>
<button id='print-id'>console.log(getSelection)</button>
<br>
<br>
<button id='start-id'>jump start</button>
<button id='end-id'>jump end</button>
<button id='focus-id'>focus content</button>
</body>
<script type="text/javascript">
const config = {
selection: null
}
function printSelection() {
const selection = window.getSelection()
range = document.getSelection().getRangeAt(0).cloneRange();
config.cloneRange = range;
console.log('selection', selection)
// console.log('selection.toString()', selection.toString())
// console.log('selection.getRangeAt(0)', selection.getRangeAt(0))
}
function jumpStart() {
let range = window.getSelection().getRangeAt(0);
let textEle = range.commonAncestorContainer;
range.setStart(range.startContainer, 0);
range.setEnd(range.startContainer, 0);
range = document.getSelection().getRangeAt(0).cloneRange();
config.cloneRange = range;
}
function jumpEnd() {
let range = window.getSelection().getRangeAt(0);
let textEle = range.commonAncestorContainer;
range.setStart(range.startContainer, textEle.length);
range.setEnd(range.endContainer, textEle.length);
range = document.getSelection().getRangeAt(textEle.length).cloneRange();
config.cloneRange = range;
}
function focusContent() {
document.getSelection().removeAllRanges(); //把沒用的Ranges刪除
console.log('config.cloneRange',config.cloneRange)
document.getSelection().addRange(config.cloneRange); //恢復(fù)Range
}
window.onload = function() {
document.getElementById('print-id').addEventListener('click', function(e) {
printSelection()
})
document.getElementById('print-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
document.getElementById('start-id').addEventListener('click', function(e) {
jumpStart()
})
document.getElementById('start-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
document.getElementById('end-id').addEventListener('click', function(e) {
jumpEnd()
})
document.getElementById('end-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
document.getElementById('focus-id').addEventListener('click', function(e) {
focusContent()
})
document.getElementById('focus-id').addEventListener('mousedown', function(e) {
e.preventDefault()
})
}
</script>
效果如下:
?總結(jié)
Contenteditable屬性
Contenteditable是一種HTML屬性,用于指定頁(yè)面中的元素是否可以編輯。以下是Contenteditable的總結(jié):
-
Contenteditable屬性可以應(yīng)用于HTML元素上,如div、span、p、h1等等。
-
當(dāng)Contenteditable屬性設(shè)置為true時(shí),用戶可以編輯元素內(nèi)的文本、圖像等內(nèi)容。
-
Contenteditable屬性的取值包括true和false,分別表示可編輯和不可編輯。
-
Contenteditable屬性可以通過JavaScript來(lái)動(dòng)態(tài)修改。
-
Contenteditable屬性的兼容性很好,支持大多數(shù)現(xiàn)代瀏覽器。
-
雖然Contenteditable屬性很方便,但也存在一些潛在的安全問題,因此應(yīng)該謹(jǐn)慎使用。
富文本編輯器
富文本編輯器是一種允許用戶編輯帶有樣式和格式的文本的編輯器。它與普通文本編輯器的區(qū)別在于,它允許用戶使用各種字體、顏色、大小、加粗、斜體、下劃線、超鏈接、圖片等來(lái)設(shè)計(jì)和呈現(xiàn)文本內(nèi)容。其原理主要包括以下幾個(gè)方面:
-
DOM操作:富文本編輯器通過操作DOM樹來(lái)實(shí)現(xiàn)文本樣式和格式的改變。當(dāng)用戶在編輯器中輸入或選擇文本時(shí),編輯器會(huì)將文本轉(zhuǎn)換為DOM節(jié)點(diǎn),并將節(jié)點(diǎn)添加到DOM樹中。通過對(duì)DOM節(jié)點(diǎn)的增刪改查,實(shí)現(xiàn)對(duì)文本樣式和格式的修改操作。
-
事件監(jiān)聽:通常情況下,富文本編輯器會(huì)監(jiān)聽用戶的輸入事件、鼠標(biāo)點(diǎn)擊事件和鍵盤事件等,以便及時(shí)捕捉用戶的操作并做出相應(yīng)的反應(yīng)。
-
樣式和格式化:富文本編輯器通常內(nèi)置了樣式和格式化工具,比如字體、顏色、大小、加粗、斜體、下劃線、超鏈接等,可以通過這些工具來(lái)控制文本的樣式和格式。
-
插件和組件:富文本編輯器可以通過插件和組件來(lái)擴(kuò)展其功能,比如圖片上傳組件、表格插件、代碼高亮插件等,可以讓編輯器滿足更多的需求。
?結(jié)束
本文分享到這結(jié)束,如有錯(cuò)誤或者不足之處歡迎指出!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-712938.html
?? 點(diǎn)贊,是我創(chuàng)作的動(dòng)力!
?? 收藏,是我努力的方向!
?? 評(píng)論,是我進(jìn)步的財(cái)富!
?? 感謝你的閱讀!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-712938.html
到了這里,關(guān)于前端 富文本編輯器原理——從javascript、html、css開始入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!