javascript實現(xiàn)富文本框選中對齊的思路與代碼
需求:
一個可編輯(contenteditable=true)的div,對齊選中內(nèi)容,左、中,右 ,其實質(zhì)是:對選中的末梢節(jié)點,找到塊屬性的父元素,設(shè)置text-algin:center:
MDN:text-align CSS屬性定義行內(nèi)內(nèi)容(例如文字)如何相對它的塊父元素對齊。text-align 并不控制塊元素自己的對齊,只控制它的行內(nèi)內(nèi)容的對齊。
分析需求:
我們來分解一下這個需求的三個關(guān)鍵問題: ”選中部分“,”塊元素“,"末梢元素"
1如何獲取選中的部分 *
這里涉及到的Web API Document.getSelection().getRangeAt(0) 這里只處理一個選取的情況
注意:光標(biāo)所在位置,光標(biāo)所在節(jié)點 視為選中區(qū)域
2什么是塊元素
MDN:
display:block
這個值會生成一個塊級元素盒子,同時在該元素之前和之后打斷(換行)。簡單來說就是,這個值會將該元素變成塊級元素。
除非特殊指定,諸如標(biāo)題(<h1>等)和段落(<p>)默認(rèn)情況下都是塊級的盒子。
用做鏈接的 <a> 元素、 <span>、 <em> 以及 <strong> 都是默認(rèn)處于 inline 狀態(tài)的。
3末梢元素(沒有子節(jié)點的元素)
我們操作對齊,實質(zhì)是操作盒模型中的內(nèi)容的對齊方式,也就是對:圖片,文字 等設(shè)置對齊樣式,在這里我稱其為末梢節(jié)點
實現(xiàn)思路:
1、獲取選區(qū)內(nèi)的所有末梢元素(遞歸)
2、找到這些末梢元素的父塊元素,設(shè)置其text-align:'left|center|right'
代碼實現(xiàn):
前端頁面:一個div contenteditable="true";三個按鈕:觸發(fā)對齊(左,中,右)
document.querySelector("#btn_alignl").addEventListener("click", () => { Align.call(this, 'left') }) document.querySelector("#btn_alignc").addEventListener("click", () => { Align.call(this, 'center') }) document.querySelector("#btn_alignr").addEventListener("click", () => { Align('right') })
js 代碼:
1、一個公共的Align方法,參數(shù)為:left|center|right
/** * 1 通過getBoundaryEndNodes獲取所有末梢元素 * 2 遍歷末梢節(jié)點,通過getBlockParent獲取每一個末梢節(jié)點的父級block元素 * 3 設(shè)置endnode 的 blockparent.style.textAlign=left|center|right * @param alignStr left|center|right **/ function Align(alignStr) { const rng = document.getSelection().getRangeAt(0) const commonAncestor = rng.commonAncestorContainer //獲取開始節(jié)點,到結(jié)尾節(jié)點之間的所有末梢節(jié)點 let getBoundaryEndNodes = function (pNode) { if (pNode == boundaries.start) { boundaries.isStart = true } if (pNode == boundaries.end) { boundaries.isEnd = true resultNodes.push(pNode) console.log(pNode) } if (boundaries.isStart == true && boundaries.isEnd == false && pNode.hasChildNodes() == false) { resultNodes.push(pNode); console.log(pNode) } if (pNode.hasChildNodes() && boundaries.isEnd == false) { pNode.childNodes.forEach(node => { getBoundaryEndNodes(node) }); } } //獲取所有末梢節(jié)點 let getEndNodes = function (node, nodes=[]) { if (node.hasChildNodes()) { node.childNodes.forEach(node => { getEndNodes(node, nodes) }); } else { nodes.push(node) } return nodes } const startBoundaryNode = getEndNodes(rng.startContainer)[0] const endBoundaryNode = getEndNodes(rng.endContainer).pop() let resultNodes = [] //存放開始節(jié)點,到結(jié)尾節(jié)點之間的所有末梢節(jié)點 let boundaries = { start: startBoundaryNode, end: endBoundaryNode, isStart: false, isEnd: false } getBoundaryEndNodes.call(this, commonAncestor) //遍歷所有末梢節(jié)點,找到其塊父元素 設(shè)置對齊樣式 resultNodes.forEach(node => { const blockparent = getBlockParent(node) if (!!blockparent && blockparent.style.textAlign != alignStr) { blockparent.style.textAlign = alignStr } }) }
getBlockParent的實現(xiàn)--獲取選中末梢節(jié)點的塊父節(jié)點的實現(xiàn)
let blockTags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'ul', 'ol', 'li', 'div', 'body', 'td', 'th'] // let inlineTags = ['img', 'font', 'b', 'strong', 'span', 'a'] let blockTagSet = new Map() blockTags.forEach((v) => { blockTagSet.set(v, true) }); const source = document.querySelector('div.source'); function getBlockParent(ele) { let result = undefined if (ele === source) { console.log('已找到editor的根,并沒有找父級block元素'); result = undefined } else { switch (ele.nodeType) { //element: 判斷ele是否是塊級元素,判斷依據(jù)1 display:block 2 默認(rèn)的塊級元素 case 1: { const disPro = ele.style.display; if (disPro && disPro.toLowerCase().indexOf('block') > -1) { result = ele; } else if (blockTagSet.get(ele.tagName.toLowerCase())) { result = ele } else { result = getBlockParent(ele.parentElement) } break; } case 3: {//textNode if (!!ele.nodeValue.trim()) result = getBlockParent(ele.parentElement) else result = undefined break; } default: { break; } } //end switch }//end if return result }
總結(jié)
到此這篇關(guān)于javascript實現(xiàn)富文本框選中對齊的思路與代碼的文章就介紹到這了,更多相關(guān)js富文本框選中對齊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
快速查找數(shù)組中的某個元素并返回下標(biāo)示例
最近在寫jquery的combobox插件時遇到效率問題,再加上jquery選擇器的類帥選,導(dǎo)致效率很慢,采用以下方式二,可以輕松解決此問題2013-09-09JS獲得選取checkbox整行數(shù)據(jù)的方法
這篇文章主要介紹了JS獲得選取checkbox整行數(shù)據(jù)的方法,涉及使用js對DOM節(jié)點的操作技巧,非常具有實用價值,需要的朋友可以參考下2015-01-01