wangeditor富文本编辑器拓展菜单——格式刷

 参考快速扩展一个菜单 · wangEditor 用户文档

继承 按钮 菜单样式自定义拓展 格式刷功能菜单按钮

const _this = this
const { $, BtnMenu } = E

// 自定义 格式刷 菜单继F承 BtnMenu class
class FormatPainter extends BtnMenu {
  constructor(editor) {
    // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
    const $elem = E.$(
      `<div class="w-e-menu" data-title="格式刷">
        <i class="el-icon-s-open"></i>
      </div>`
    )
    super($elem, editor)
  }
  // 菜单点击事件,获取点击格式刷后的下一次点击文本
  clickHandler() {
    let nodeArray = []
    //获取当前选中元素所有父样式
    function getAllStyle(dom) {
      if (!dom) return
      const tagName = dom.tagName.toLowerCase()
      if (tagName === 'p') {
        nodeArray.push({
          tagName: 'span',
          attributes: Array.from(dom.attributes).map((i) => {
            return {
              name: i.name,
              value: i.value,
            }
          }),
        })
        return nodeArray
      } else {
        nodeArray.push({
          tagName: tagName,
          attributes: Array.from(dom.attributes).map((i) => {
            return {
              name: i.name,
              value: i.value,
            }
          }),
        })
        getAllStyle(dom.parentNode)
      }
      return nodeArray
    }
    //获取鼠标位置的节点
    let containerEle = this.editor.selection.getSelectionStartElem()
      .elems[0]
    let brushStyle = getAllStyle(containerEle)
    if (!!brushStyle) {
      //有复制到的格式就开启格式刷
      _this.ifBrushed = !_this.ifBrushed //格式刷开启
      _this.brushStyle = brushStyle //格式刷样式存储
    }
  }
  // 菜单是否被激活(如果不需要,这个函数可以空着)
  tryChangeActive() {}
}

E.registerMenu('FormatPainter', FormatPainter)

//监听鼠标抬起事件
this.$refs['editor'].addEventListener('mouseup', () => {
  //延时调用确保富文本编辑器中的选中文本已经该改变
  setTimeout(() => {
    this.containerEleChange()
  })
})
/**
 * @description: 监听文本点击事件
 * @return void
 */
containerEleChange() {
  let containerEle = this.editor.selection.getSelectionContainerElem()
    .elems[0] //选区所在的 DOM 节点
  let containerEleStart = this.editor.selection.getSelectionStartElem()
    .elems[0] //选区开始的 DOM 节点
  let containerEleEnd = this.editor.selection.getSelectionEndElem().elems[0] //选区结束的 DOM 节点
  let ifEmpty = this.editor.selection.isSelectionEmpty() //判断选区是否为“空”(即没有选中任何文字)
  let containerText = this.editor.selection.getSelectionText() //选中的文字
  //复制style到选中的文本
  function addStyle(text, nodeArray) {
    let currentNode = null
    nodeArray.forEach((ele, index) => {
      let node = document.createElement(ele.tagName)
      for (const attr of ele.attributes) {
        node.setAttribute(attr.name, attr.value)
      }
      if (index === 0) {
        node.innerText = text
        currentNode = node
      } else {
        node.appendChild(currentNode)
        currentNode = node
      }
    })
    return currentNode
  }

  if (this.ifBrushed) {
    // 格式刷开启则开始复制style
    let containerEleNew
    let containerEleText
    if (ifEmpty) {
      //判断选区是否为“空”(即没有选中任何文字)
      containerEleText = containerEle.innerText
      containerEleNew = addStyle(containerEle.innerText, this.brushStyle) //新的样式
    } else {
      //选中一段文字
      containerEleText = containerText
      containerEleNew = addStyle(containerText, this.brushStyle) //新的样式
    }
    if (containerEleStart === containerEleEnd) {
      //选区前后相等,选中的区域中间不夹杂其他标签
      let innerText = containerEle.innerText
      if (ifEmpty) {
        // 没有选中的文本直接全部替换掉
        containerEle.innerHTML = containerEleNew.innerHTML
      } else {
        //有选中的文本则替换选中的文本
        containerEle.innerHTML = innerText.replace(
          containerEleText,
          containerEleNew.innerHTML
        )
      }
    } else {
      //选区前后不相等,选中的区域中间夹杂其他标签,操作和选区为“空”一样
      containerEleNew = addStyle(containerEle.innerText, this.brushStyle) //新的样式
      containerEle.innerHTML = containerEleNew.innerHTML
    }
  }
  this.ifBrushed = false
},
//清除监听
beforeDestroy() {
  this.$refs['editor'].removeEventListener('click', this.containerEleChange)
},

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值