quill富文本编辑器自定义工具栏全屏

背景

最近在做一个quill富文本编辑器自定义的全屏的需求效果,并不单指富文本编辑器编写文本的全屏效果

核心思路:自定义工具栏按钮,给按钮绑定相应的事件

只考虑了逻辑方面,对于样式问题需要自己根据自己的实际情况调整

准备工作

在vue中安装富文本编辑器,其他类似quill富文本编辑器都行

js 复制代码
npm install vue-quill-editor -S
HTML 复制代码
<!-- app.vue -->
<template>
  <div id="app-main">
    <div class="main-container">
      <nav>
        <router-link to="/">Home</router-link> |
        <router-link to="/about">About</router-link>
      </nav>
      <router-view/>
    </div>
    <!-- 富文本全屏区域 -->
    <div class="full-screen-container">
      <div class="full-screen-header"></div>
      <div class="full-screen-body"></div>
    </div>
  </div>
</template>

封装富文本编辑器组件

HTML 复制代码
<!-- quill-editor.vue -->
<template>
	<quill-editor ref="quill" class="ql-editor" v-model="content" :options="editorOption">
  </quill-editor>
</template>

<script>
import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

export default {
  components: { quillEditor },
  props: {
    detail: { // 父组件传入的值
      type: String,
      default: ''
    },
    // 用于需要全屏功能的富文本编辑器
    // 全屏包含的目标节点的class
    fullScreenTargetClass: String,
    // 全屏时的开头保留的文字
    fullScreenHeaderText: String
  },
  data () {
    return {
      content: '',
      placeholder: '',
      // 点击全屏展开相关参数
      prevInsertParentNode: null, // 插入到全屏容器之前的原父节点
      insertTarget: null, // 插入到全屏区域的目标元素
      cloneTarget: null // 克隆占位元素
    }
  },
  computed: {
    edit () {
      return this.$refs.quill?.quill
    },
    editorOption () {
      const {
        placeholder = ''
      } = this
      const baseToolbarContainer = [
        'bold', 'italic', 'underline', 'strike', // 加粗 斜体 下划线 删除线
        'blockquote', 'code-block' // 引用  代码块
      ]
      let resultToolbarContainer = baseToolbarContainer
      const baseModules = {
        toolbar: {
          container: resultToolbarContainer,
          handlers: {
            }
          }
        }
      }
      return {
        placeholder,
        modules: baseModules
      }
    }
  }
}
  
</script>

可通过handlers来修改工具栏原来的点击触发的事件,比如我修改bold原来的触发事件

js 复制代码
handlers: {
  bold: () => {
    console.log('修改了')
  }
}

自定义全屏也是运用该方式

一.添加自定义工具栏按钮

js 复制代码
// 判断是否要给富文本编辑器添加全屏功能
// 根据情况自行修改
if (this.fullScreenHeaderText || this.fullScreenTargetClass) {
  resultToolbarContainer = [...resultToolbarContainer, 'fullScreen']
}

1.在富文本编辑器文件中添加图标样式

js 复制代码
import { Quill, quillEditor } from 'vue-quill-editor'

const icons = Quill.import('ui/icons')
icons.fullScreen = '<svg t="1697787486376" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8290" width="10" height="10"><path d="M145.066667 85.333333h153.6c25.6 0 42.666667-17.066667 42.666666-42.666666S324.266667 0 298.666667 0H34.133333C25.6 0 17.066667 8.533333 8.533333 17.066667 0 25.6 0 34.133333 0 42.666667v256c0 25.6 17.066667 42.666667 42.666667 42.666666s42.666667-17.066667 42.666666-42.666666V145.066667l230.4 230.4c17.066667 17.066667 42.666667 17.066667 59.733334 0 17.066667-17.066667 17.066667-42.666667 0-59.733334L145.066667 85.333333z m170.666666 563.2L162.133333 802.133333l-76.8 76.8V725.333333C85.333333 699.733333 68.266667 682.666667 42.666667 682.666667s-42.666667 17.066667-42.666667 42.666666v256c0 25.6 17.066667 42.666667 42.666667 42.666667h256c25.6 0 42.666667-17.066667 42.666666-42.666667s-17.066667-42.666667-42.666666-42.666666H145.066667l76.8-76.8 153.6-153.6c17.066667-17.066667 17.066667-42.666667 0-59.733334-17.066667-17.066667-42.666667-17.066667-59.733334 0z m665.6 34.133334c-25.6 0-42.666667 17.066667-42.666666 42.666666v153.6l-76.8-76.8-153.6-153.6c-17.066667-17.066667-42.666667-17.066667-59.733334 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l153.6 153.6 76.8 76.8H725.333333c-25.6 0-42.666667 17.066667-42.666666 42.666666s17.066667 42.666667 42.666666 42.666667h256c25.6 0 42.666667-17.066667 42.666667-42.666667v-256c0-25.6-17.066667-42.666667-42.666667-42.666666z m0-682.666667h-256c-25.6 0-42.666667 17.066667-42.666666 42.666667s17.066667 42.666667 42.666666 42.666666h153.6l-76.8 76.8-153.6 153.6c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733334 0l153.6-153.6 76.8-76.8v153.6c0 25.6 17.066667 42.666667 42.666666 42.666666s42.666667-17.066667 42.666667-42.666666v-256c0-25.6-17.066667-42.666667-42.666667-42.666667z" fill="" p-id="8291" stroke="black" stroke-width="30"></path></svg>'
// svg图标的加粗可以通过stroke="black" stroke-width="30"来设置

2.在mounted中添加图标及title属性

js 复制代码
mounted () {
  this.initToolTitle()
}
methods: {
  // 初始化富文本编辑器的放大图标
  initToolTitle () {
    const wrapper = this.edit.container.parentNode
    const dom = wrapper.querySelector('.ql-fullScreen')
    if (dom) {
      dom.innerHTML = '<svg t="1697787486376" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8290" width="10" height="10"><path d="M145.066667 85.333333h153.6c25.6 0 42.666667-17.066667 42.666666-42.666666S324.266667 0 298.666667 0H34.133333C25.6 0 17.066667 8.533333 8.533333 17.066667 0 25.6 0 34.133333 0 42.666667v256c0 25.6 17.066667 42.666667 42.666667 42.666666s42.666667-17.066667 42.666666-42.666666V145.066667l230.4 230.4c17.066667 17.066667 42.666667 17.066667 59.733334 0 17.066667-17.066667 17.066667-42.666667 0-59.733334L145.066667 85.333333z m170.666666 563.2L162.133333 802.133333l-76.8 76.8V725.333333C85.333333 699.733333 68.266667 682.666667 42.666667 682.666667s-42.666667 17.066667-42.666667 42.666666v256c0 25.6 17.066667 42.666667 42.666667 42.666667h256c25.6 0 42.666667-17.066667 42.666666-42.666667s-17.066667-42.666667-42.666666-42.666666H145.066667l76.8-76.8 153.6-153.6c17.066667-17.066667 17.066667-42.666667 0-59.733334-17.066667-17.066667-42.666667-17.066667-59.733334 0z m665.6 34.133334c-25.6 0-42.666667 17.066667-42.666666 42.666666v153.6l-76.8-76.8-153.6-153.6c-17.066667-17.066667-42.666667-17.066667-59.733334 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l153.6 153.6 76.8 76.8H725.333333c-25.6 0-42.666667 17.066667-42.666666 42.666666s17.066667 42.666667 42.666666 42.666667h256c25.6 0 42.666667-17.066667 42.666667-42.666667v-256c0-25.6-17.066667-42.666667-42.666667-42.666666z m0-682.666667h-256c-25.6 0-42.666667 17.066667-42.666666 42.666667s17.066667 42.666667 42.666666 42.666666h153.6l-76.8 76.8-153.6 153.6c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733334 0l153.6-153.6 76.8-76.8v153.6c0 25.6 17.066667 42.666667 42.666666 42.666666s42.666667-17.066667 42.666667-42.666666v-256c0-25.6-17.066667-42.666667-42.666667-42.666667z" fill="" p-id="8291" stroke="black" stroke-width="30"></path></svg>'
      dom.setAttribute('title', '全屏')
    }
  }
}

效果如图:

二.给自定义工具栏图标添加逻辑

1.给app.vue中添加样式

主要是给全屏区域设置display:none,然后点击全屏后,给.main-container区域设置隐藏,让全屏区域显示

HTML 复制代码
<!-- app.vue  -->
<style lang="scss">
* {
  margin: 0;
  padding: 0;
}

.full-screen-container {
  display: none;
  height: 100vh;
  width: 100vw;
  flex-direction: column;

  .full-screen-header {
    margin-bottom: 10px;
  }
  .full-screen-body {
    width: 100%;
    height: 100vh;
    margin-top: -30px;

    .quill-editor  {
      padding: 0;
    }
    .ql-container {
      height: calc(100% - 65px);
    }
  }
}
.app-main {
  &.show-full-screen {
    .main-container {
      display: none;
    }
    .full-screen-container {
      display: flex;
    }
  }
}
</style>

2.情景分析

1.当传递了fullScreenHeaderText时

2.当传递了fullScreenTargetClass时

当然也可以fullScreenHeaderText和fullScreenTargetClass都传递

3.在封装的富文本编辑器组件中添加自定义图标逻辑

主要是通过控制节点来实现全屏

设置滚动位置的方法根据情况切换方式,也可以不存在sessionStorage中,在组件中定义一个变量专门存储也可以

js 复制代码
/* 在editorOption中 */
if (this.fullScreenHeaderText || this.fullScreenTargetClass) {
  resultToolbarContainer = [...resultToolbarContainer, 'fullScreen']
}
const baseModules = {
  toolbar: {
  	container: resultToolbarContainer,
  	handlers: {
    	fullScreen: () => {
      	const setIcon = (wrapper, flag) => {
        	const svgMap = {
          	全屏: '<svg t="1697787486376" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8290" width="10" height="10"><path d="M145.066667 85.333333h153.6c25.6 0 42.666667-17.066667 42.666666-42.666666S324.266667 0 298.666667 0H34.133333C25.6 0 17.066667 8.533333 8.533333 17.066667 0 25.6 0 34.133333 0 42.666667v256c0 25.6 17.066667 42.666667 42.666667 42.666666s42.666667-17.066667 42.666666-42.666666V145.066667l230.4 230.4c17.066667 17.066667 42.666667 17.066667 59.733334 0 17.066667-17.066667 17.066667-42.666667 0-59.733334L145.066667 85.333333z m170.666666 563.2L162.133333 802.133333l-76.8 76.8V725.333333C85.333333 699.733333 68.266667 682.666667 42.666667 682.666667s-42.666667 17.066667-42.666667 42.666666v256c0 25.6 17.066667 42.666667 42.666667 42.666667h256c25.6 0 42.666667-17.066667 42.666666-42.666667s-17.066667-42.666667-42.666666-42.666666H145.066667l76.8-76.8 153.6-153.6c17.066667-17.066667 17.066667-42.666667 0-59.733334-17.066667-17.066667-42.666667-17.066667-59.733334 0z m665.6 34.133334c-25.6 0-42.666667 17.066667-42.666666 42.666666v153.6l-76.8-76.8-153.6-153.6c-17.066667-17.066667-42.666667-17.066667-59.733334 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l153.6 153.6 76.8 76.8H725.333333c-25.6 0-42.666667 17.066667-42.666666 42.666666s17.066667 42.666667 42.666666 42.666667h256c25.6 0 42.666667-17.066667 42.666667-42.666667v-256c0-25.6-17.066667-42.666667-42.666667-42.666666z m0-682.666667h-256c-25.6 0-42.666667 17.066667-42.666666 42.666667s17.066667 42.666667 42.666666 42.666666h153.6l-76.8 76.8-153.6 153.6c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733334 0l153.6-153.6 76.8-76.8v153.6c0 25.6 17.066667 42.666667 42.666666 42.666666s42.666667-17.066667 42.666667-42.666666v-256c0-25.6-17.066667-42.666667-42.666667-42.666667z" fill="" p-id="8291" stroke="black" stroke-width="30"></path></svg>',
          	退出全屏: '<svg t="1697780920647" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2558" width="12" height="12"><path d="M257.706667 376.32H128c-11.946667 0-21.333333-9.386667-21.333333-21.333333s9.386667-21.333333 21.333333-21.333334h129.706667c35.413333 0 64-28.586667 64-64V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333a106.666667 106.666667 0 0 1-106.666666 106.666667zM896 376.32h-129.706667a106.666667 106.666667 0 0 1-106.666666-106.666667V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333c0 35.413333 28.586667 64 64 64H896c11.946667 0 21.333333 9.386667 21.333333 21.333334s-9.386667 21.333333-21.333333 21.333333z" fill="#666666" p-id="2559"></path><path d="M896 376.32h-129.706667a106.666667 106.666667 0 0 1-106.666666-106.666667V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333c0 35.413333 28.586667 64 64 64H896c11.946667 0 21.333333 9.386667 21.333333 21.333334s-9.386667 21.333333-21.333333 21.333333zM257.706667 376.32H128c-11.946667 0-21.333333-9.386667-21.333333-21.333333s9.386667-21.333333 21.333333-21.333334h129.706667c35.413333 0 64-28.586667 64-64V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333a106.666667 106.666667 0 0 1-106.666666 106.666667zM680.96 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333a106.666667 106.666667 0 0 1 106.666666-106.666667H896c11.946667 0 21.333333 9.386667 21.333333 21.333333s-9.386667 21.333333-21.333333 21.333334h-129.706667c-35.413333 0-64 28.586667-64 64V896c0 11.946667-9.386667 21.333333-21.333333 21.333333zM343.04 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333c0-35.413333-28.586667-64-64-64H128c-11.946667 0-21.333333-9.386667-21.333333-21.333334s9.386667-21.333333 21.333333-21.333333h129.706667a106.666667 106.666667 0 0 1 106.666666 106.666667V896c0 11.946667-9.813333 21.333333-21.333333 21.333333z" fill="#666666" p-id="2560"></path><path d="M343.04 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333c0-35.413333-28.586667-64-64-64H128c-11.946667 0-21.333333-9.386667-21.333333-21.333334s9.386667-21.333333 21.333333-21.333333h129.706667a106.666667 106.666667 0 0 1 106.666666 106.666667V896c0 11.946667-9.813333 21.333333-21.333333 21.333333zM680.96 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333a106.666667 106.666667 0 0 1 106.666666-106.666667H896c11.946667 0 21.333333 9.386667 21.333333 21.333333s-9.386667 21.333333-21.333333 21.333334h-129.706667c-35.413333 0-64 28.586667-64 64V896c0 11.946667-9.386667 21.333333-21.333333 21.333333z" fill="#666666" p-id="2561" stroke="black" stroke-width="30"></path></svg>'
        	}
        	const fullBtn = wrapper.querySelector('.ql-fullScreen')
        	if (fullBtn) {
          	fullBtn.innerHTML = svgMap[flag]
          	fullBtn.setAttribute('title', flag)
        	}
      	}
      	// 寻找目标节点
      	const findTarget = (node) => {
      		if (!node) return null
        	if (node && node.classList.contains(this.fullScreenTargetClass)) return node
        	return findTarget(node.parentNode)
      	}
        const app = document.querySelector('.app-main')
        const fullScreenContainer = document.querySelector('.full-screen-container')
        const fullScreenBody = fullScreenContainer && fullScreenContainer.querySelector('.full-screen-body')
        const fullScreenHeader = fullScreenContainer && fullScreenContainer.querySelector('.full-screen-header')
        const wrapper = this.edit.container.parentNode
        if (app && fullScreenContainer && fullScreenBody && fullScreenHeader && wrapper) {
          // 【关闭全屏】
          if (app.classList.contains('show-full-screen') && this.prevInsertParentNode && this.insertTarget) {
            this.prevInsertParentNode.replaceChild(this.insertTarget, this.cloneTarget)
            app.classList.remove('show-full-screen')
            setIcon(wrapper, '全屏')
            /* 该方法在测试时不生效,换成另外一种方法,但是在项目中是可以的  */
            /* const mainDom = document.querySelector('.app-main')
            if (mainDom) {
              // 滚动至原位
              mainDom.scrollTop = Number(window.sessionStorage.getItem('mainScrollTop'))
            } */
            // 滚动至原位
            const scrollTop = Number(window.sessionStorage.getItem('mainScrollTop'))
            window.scrollTo(0, scrollTop)
            return
          }
          // 记录需要插入到全屏容器中的目标节点
          this.insertTarget = wrapper
          if (this.fullScreenTargetClass) {
            this.insertTarget = findTarget(wrapper)
          }
          // 【开启全屏】
          if (this.insertTarget) {
            // 记录全屏前的滚动位置
            /* 该方法在测试时不生效,换成另外一种方法,但是在项目中是可以的  */
            // window.sessionStorage.setItem('mainScrollTop', String(document.querySelector('.app-main')?.scrollTop || 0))
            window.sessionStorage.setItem('mainScrollTop', String(window.scrollY || 0))
            app.classList.add('show-full-screen')
            if (this.insertTarget.parentNode) {
              this.prevInsertParentNode = this.insertTarget.parentNode
              // 拷贝节点占位
              this.cloneTarget = this.insertTarget.cloneNode()
              this.cloneTarget.classList.add('full-screen-node-clone')
              this.prevInsertParentNode.replaceChild(this.cloneTarget, this.insertTarget)
            }
            // 插入到全屏容器节点中
            fullScreenBody.appendChild(this.insertTarget)
            this.fullScreenHeaderText && (fullScreenHeader.innerHTML = this.fullScreenHeaderText)
            setIcon(wrapper, '退出全屏')
          }
        }
      }
    }
  }
}
  1. 在使用该封装的富文本编辑器的父组件通过传入fullScreenTargetClass和fullScreenHeaderText来开启富文本编辑器的全屏功能。
  2. setIcon函数,用来控制点击全屏或退出全屏图标和title的切换
  3. findTarget函数,当传递fullScreenTargetClass时由内向外寻找目标class的节点
  4. 先看开启全屏的逻辑,再看关闭全屏的逻辑
  5. 开启全屏:找到设置全屏的节点 => 记录开启全屏的滑动条滚动条位置 => 给app添加一个class的目标是增加权重,也为了比较方便的设置样式 => 拷贝节点占位是为了退出全屏时方便节点的替换。把目标节点放到全屏区域的body中,切换样式setIcon
  6. 退出全屏:判断是否是全屏状态 => 把全屏的节点换回原有的位置 => 切换样式setIcon => 滚动回原有的位置

不足:如果使用组件库组件在一瞬间有明显的高度变化,退出全屏的滚动位置可能不准

三.另外一种通过控制CSS来控制全屏的方法

通过传递进来的class来给当前的编辑器设置class样式来改变,主要是通过设置

css 复制代码
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100%;

来实现全屏

使用富文本编辑器的组件

HTML 复制代码
<div class="full-Screen">
  <quill-editor fullScreenTargetClass="full-Screen">
  </quill-editor>
  <button>其他内容</button>
</div>

封装的富文本编辑器组件

js 复制代码
const baseModules = {
  toolbar: {
    container: resultToolbarContainer,
    handlers: {
      fullScreen: () => {
        const setIcon = (wrapper, flag) => {
          const svgMap = {
            全屏: '<svg t="1697787486376" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8290" width="10" height="10"><path d="M145.066667 85.333333h153.6c25.6 0 42.666667-17.066667 42.666666-42.666666S324.266667 0 298.666667 0H34.133333C25.6 0 17.066667 8.533333 8.533333 17.066667 0 25.6 0 34.133333 0 42.666667v256c0 25.6 17.066667 42.666667 42.666667 42.666666s42.666667-17.066667 42.666666-42.666666V145.066667l230.4 230.4c17.066667 17.066667 42.666667 17.066667 59.733334 0 17.066667-17.066667 17.066667-42.666667 0-59.733334L145.066667 85.333333z m170.666666 563.2L162.133333 802.133333l-76.8 76.8V725.333333C85.333333 699.733333 68.266667 682.666667 42.666667 682.666667s-42.666667 17.066667-42.666667 42.666666v256c0 25.6 17.066667 42.666667 42.666667 42.666667h256c25.6 0 42.666667-17.066667 42.666666-42.666667s-17.066667-42.666667-42.666666-42.666666H145.066667l76.8-76.8 153.6-153.6c17.066667-17.066667 17.066667-42.666667 0-59.733334-17.066667-17.066667-42.666667-17.066667-59.733334 0z m665.6 34.133334c-25.6 0-42.666667 17.066667-42.666666 42.666666v153.6l-76.8-76.8-153.6-153.6c-17.066667-17.066667-42.666667-17.066667-59.733334 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l153.6 153.6 76.8 76.8H725.333333c-25.6 0-42.666667 17.066667-42.666666 42.666666s17.066667 42.666667 42.666666 42.666667h256c25.6 0 42.666667-17.066667 42.666667-42.666667v-256c0-25.6-17.066667-42.666667-42.666667-42.666666z m0-682.666667h-256c-25.6 0-42.666667 17.066667-42.666666 42.666667s17.066667 42.666667 42.666666 42.666666h153.6l-76.8 76.8-153.6 153.6c-17.066667 17.066667-17.066667 42.666667 0 59.733334 17.066667 17.066667 42.666667 17.066667 59.733334 0l153.6-153.6 76.8-76.8v153.6c0 25.6 17.066667 42.666667 42.666666 42.666666s42.666667-17.066667 42.666667-42.666666v-256c0-25.6-17.066667-42.666667-42.666667-42.666667z" fill="" p-id="8291" stroke="black" stroke-width="30"></path></svg>',
            退出全屏: '<svg t="1697780920647" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2558" width="12" height="12"><path d="M257.706667 376.32H128c-11.946667 0-21.333333-9.386667-21.333333-21.333333s9.386667-21.333333 21.333333-21.333334h129.706667c35.413333 0 64-28.586667 64-64V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333a106.666667 106.666667 0 0 1-106.666666 106.666667zM896 376.32h-129.706667a106.666667 106.666667 0 0 1-106.666666-106.666667V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333c0 35.413333 28.586667 64 64 64H896c11.946667 0 21.333333 9.386667 21.333333 21.333334s-9.386667 21.333333-21.333333 21.333333z" fill="#666666" p-id="2559"></path><path d="M896 376.32h-129.706667a106.666667 106.666667 0 0 1-106.666666-106.666667V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333c0 35.413333 28.586667 64 64 64H896c11.946667 0 21.333333 9.386667 21.333333 21.333334s-9.386667 21.333333-21.333333 21.333333zM257.706667 376.32H128c-11.946667 0-21.333333-9.386667-21.333333-21.333333s9.386667-21.333333 21.333333-21.333334h129.706667c35.413333 0 64-28.586667 64-64V128c0-11.946667 9.386667-21.333333 21.333333-21.333333s21.333333 9.386667 21.333333 21.333333v141.653333a106.666667 106.666667 0 0 1-106.666666 106.666667zM680.96 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333a106.666667 106.666667 0 0 1 106.666666-106.666667H896c11.946667 0 21.333333 9.386667 21.333333 21.333333s-9.386667 21.333333-21.333333 21.333334h-129.706667c-35.413333 0-64 28.586667-64 64V896c0 11.946667-9.386667 21.333333-21.333333 21.333333zM343.04 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333c0-35.413333-28.586667-64-64-64H128c-11.946667 0-21.333333-9.386667-21.333333-21.333334s9.386667-21.333333 21.333333-21.333333h129.706667a106.666667 106.666667 0 0 1 106.666666 106.666667V896c0 11.946667-9.813333 21.333333-21.333333 21.333333z" fill="#666666" p-id="2560"></path><path d="M343.04 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333c0-35.413333-28.586667-64-64-64H128c-11.946667 0-21.333333-9.386667-21.333333-21.333334s9.386667-21.333333 21.333333-21.333333h129.706667a106.666667 106.666667 0 0 1 106.666666 106.666667V896c0 11.946667-9.813333 21.333333-21.333333 21.333333zM680.96 917.333333c-11.946667 0-21.333333-9.386667-21.333333-21.333333v-141.653333a106.666667 106.666667 0 0 1 106.666666-106.666667H896c11.946667 0 21.333333 9.386667 21.333333 21.333333s-9.386667 21.333333-21.333333 21.333334h-129.706667c-35.413333 0-64 28.586667-64 64V896c0 11.946667-9.386667 21.333333-21.333333 21.333333z" fill="#666666" p-id="2561" stroke="black" stroke-width="30"></path></svg>'
          }
          const fullBtn = wrapper.querySelector('.ql-fullScreen')
          if (fullBtn) {
            fullBtn.innerHTML = svgMap[flag]
            fullBtn.setAttribute('title', flag)
          }
        }
        // 通过class找到目标节点
        const targetClassNode = document.querySelector(`.${this.fullScreenTargetClass}`)
        const targetEdit = targetClassNode.querySelector('.quill-editor')
        // 【关闭全屏】
        if (targetEdit.classList.contains('full-screen-edit')) {
          targetEdit.classList.remove('full-screen-edit')
          document.body.style.overflow = 'auto'
          setIcon(targetEdit, '全屏')
          return
        }
        // 【开启全屏】
        // 给指定的富文本编辑器添加class
        targetEdit.classList.add('full-screen-edit')
        // 隐藏滚动条
        document.body.style.overflow = 'hidden'
        setIcon(targetEdit, '退出全屏')
      }
    }
  }
}
css 复制代码
.full-screen-edit {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100%;
  background: #fff;
}

再加上相同的退出全屏时设置滚动条位置的方法

四.两种方法总结

第一种方法更有通用性,第二种比较简单,容易实现

设置富文本编辑器的文字颜色

css 复制代码
.quill-editor {
  body,
  hr,
  p,
  blockquote,
  dl,
  dt,
  dd,
  ul,
  ol,
  li,
  pre,
  form,
  fieldset,
  legend,
  button,
  input,
  textarea,
  th,
  td,
  div,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    color: #333;
  }
}

源码

gitee仓库: gitee.com/ice-cream-7...

相关推荐
阿伟来咯~25 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端30 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱33 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai42 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨43 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js