wangEditor 自定義字號(hào)fontSize插件 突破最多7個(gè)字號(hào)的限制

原理就是根據(jù)文檔當(dāng)前選區(qū) 獲取所有選區(qū)內(nèi)的節(jié)點(diǎn) 然后對(duì)節(jié)點(diǎn)設(shè)置字體大小

不支持IE IE沒(méi)有Selection.containsNode方法

如果想支持IE 可以根據(jù)選擇范圍自己去獲取所有的選中節(jié)點(diǎn) 目前未找到官方的方法去獲取 只能根據(jù)選區(qū)Range 自己處理

此方法還有個(gè)問(wèn)題 就是非styleWithCss模式或firefox瀏覽器中 會(huì)把內(nèi)容拆的很碎 默認(rèn)的document.execCommand('fontSize') 方法, 會(huì)自動(dòng)拆分合并內(nèi)容, 但是font標(biāo)簽上一旦加上style, 會(huì)導(dǎo)致無(wú)法合并內(nèi)容, 對(duì)同一段內(nèi)容多次設(shè)置字體的時(shí)候, 會(huì)生成很多<font>標(biāo)簽

import wangEditor from 'wangeditor'
class FontSizeList {
  constructor(list) {
    this.itemList = []
    for (let key in list) {
      const item = list[key]
      this.itemList.push({
        $elem: wangEditor.$(`<p style="font-size:${key}">${item.name}</p>`),
        value: item.value
      })
    }
  }
  getItemList() {
    return this.itemList
  }
}

const removeChildFontSize = (dom) => {
  if (dom && dom.children) {
    let children = dom.children
    for (let child of children) {
      child.style.fontSize = ''
      removeChildFontSize(child)
    }
  }
}

export default class FontSizeMenu extends wangEditor.DropListMenu {
  constructor(editor) {
    // data-title屬性表示當(dāng)鼠標(biāo)懸停在該按鈕上時(shí)提示該按鈕的功能簡(jiǎn)述
    const $elem = wangEditor.$(
      `<div class="w-e-menu" data-title="字號(hào)"><i class="w-e-icon-text-heigh"></i></div>`
    )
    let fontStyleList = new FontSizeList(editor.config.fontSize)
    const fontListConf = {
      width: 160,
      title: '設(shè)置字號(hào)',
      type: 'list',
      list: fontStyleList.getItemList(),
      clickHandler: (value) => {
        this.command(value)
      }
    }
    super($elem, editor, fontListConf)
  }

  /**
   * 執(zhí)行命令
   * @param value value
   */
  command(value) {
    const editor = this.editor
    const isEmptySelection = editor.selection.isSelectionEmpty()

    let selectionElem = editor.selection.getSelectionContainerElem()?.elems[0]

    if (selectionElem == null) return

    const isFont = selectionElem?.nodeName.toLowerCase() !== 'p'
    const isSameSize = selectionElem?.getAttribute('size') === value
    if (isEmptySelection) {
      if (isFont && !isSameSize) {
        const $elems = editor.selection.getSelectionRangeTopNodes()
        const focusElem = $elems[0].elems[0]
        editor.selection.createRangeByElem($elems[0])
        editor.selection.moveCursor(focusElem)
        selectionElem = focusElem
      }
      editor.selection.setRangeToElem(selectionElem)
      // 插入空白選區(qū)
      editor.selection.createEmptyRange()
    }
    // 給定一個(gè)默認(rèn)的值
    editor.cmd.do('fontSize', 5)
    // 獲取包含完整選區(qū)的元素
    let current = document.getSelection().getRangeAt(0).commonAncestorContainer
    if (current.nodeType !== 1) {
      current = current.parentNode
    }
    let nodes = []
    // 獲取當(dāng)前文檔內(nèi)的選區(qū)
    let selection = document.getSelection()
    // 獲取選區(qū)內(nèi)的所有節(jié)點(diǎn)
    function find(el) {
      for (let c of el.childNodes) {
        if (selection.containsNode(c, false)) {
          if (c.nodeType !== 1) {
            let p = c.parentNode
            if (!nodes.includes(p)) {
              nodes.push(p)
            }
          } else {
            if (!nodes.includes(c)) {
              nodes.push(c)
            }
          }
        }
        find(c)
      }
    }
    find(current)
    // 設(shè)置選擇的元素的字號(hào) 移除size屬性 否則下次無(wú)法更改字號(hào) 添加自身的字號(hào)
    nodes.forEach((n) => {
      n.removeAttribute('size')
      n.style.fontSize = value
    })
    if (isEmptySelection) {
      // 需要將選區(qū)范圍折疊起來(lái)
      editor.selection.collapseRange()
      editor.selection.restoreSelection()
    }
  }

  tryChangeActive() {}
}

// 系統(tǒng)自帶的是fontSizes 這里使用fontSize 避免沖突 兩者可以同時(shí)使用
editor.config.fontSize = {
        '10px': { name: '10px', value: '10px' },
        '12px': { name: '12px', value: '12px' },
        '14px': { name: '14px', value: '14px' },
        '16px': { name: '16px', value: '16px' },
        '18px': { name: '18px', value: '18px' },
        '20px': { name: '20px', value: '20px' },
        '24px': { name: '24px', value: '24px' },
        '28px': { name: '28px', value: '28px' },
        '32px': { name: '32px', value: '32px' },
        '36px': { name: '36px', value: '36px' },
        '40px': { name: '40px', value: '40px' },
        '44px': { name: '44px', value: '44px' },
        '48px': { name: '48px', value: '48px' },
        '56px': { name: '56px', value: '56px' },
        '64px': { name: '64px', value: '64px' },
        '72px': { name: '72px', value: '72px' }
      }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容