欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript實現(xiàn)富文本框選中對齊的思路與代碼

 更新時間:2022年03月24日 09:59:41   作者:jiayouliucui  
最近在項目中經(jīng)常遇到使用富文本框的情況,下面這篇文章主要給大家介紹了關(guān)于javascript實現(xiàn)富文本框選中對齊的思路與代碼,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

需求:

一個可編輯(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)文章

最新評論