WEB 编程:富文本编辑器 Quill 配合 Pico.css 样式被影响的问题之还是 iframe

news2024/9/29 7:55:42

这个系列已经写了 3 篇了。这篇写如何使用 iframe 解决标题里面提到的问题。

前情提要

请看上一篇博文:

WEB 编程:富文本编辑器 Quill 配合 Pico.css 样式被影响的问题之Shadow DOM

WEB 编程:富文本编辑器 Quill 配合 Pico.css 样式被影响的问题之Shadow DOM-CSDN博客

缘由

缘由仍然是我想在网页里面放一个富文本编辑器 Quill Editor,然后又想用 Pico.css 给网页一个好看的格式。

然后,Quill Editor 的工具栏按钮的样式被 Pico.css 污染了。搞得很不好看。但是,页面里面还有其它的元素,需要使用 Pico.CSS 来给样式。

前面有篇文章,我提到用 iframe 的方式,把 Quill Editor 单独放在一个没有 Pico.css 的页面中,然后把这个页面,采用 iframe 的方式嵌入到有 Pico.css 的框架页面中。

当时的问题和解决方案

当时想到采用 iframe,测试确实屏蔽了框架页面的 CSS,但是,和 Editor 在一起的,还有其它的输入框。这些输入框,需要给 Pico.css 给以样式。否则这些输入框会很难看。

然后想到采用 Shadow DOM 的解决方案,而不是采用 iframe 的方式。没成想,测试下来,发现 Shadow DOM 的方式,让 Quill Editor 的原本的功能都无法正常操作了。

兜兜转转一大圈,回到 iframe 这个方案

使用 iframe 这个方案,同时要解决页面上其它的页面组件,比如文章标题的输入框,要受到 Pico.css 样式的影响,提交用的按钮,要受到 Pico.css 样式的影响,就必须把文章标题输入框,提交按钮,等,放到 iframe 外面,也就是放到框架页面上。

接下来的问题就是,如何在提交的时候,能同时提交标题输入框的内容,和 iframe 里面的富文本编辑器里面用户输入的内容。

当然,如果写很复杂的 JavaScript 代码,肯定是能搞定这个问题的。但我想要越简单越好,尽量少写代码。比如,我不会自己去创建一个 XMLHttpRequest 用来向服务器提交。我也不想要引入 jQuery 库或者其它的 AJAX 库来干这个事情。因为这样会给页面引入更多的东西,用户打开页面需要下载更多的数据,消耗更多带宽和更多的等待时间。

所以,我还是想用页面的 <form> 来直接提交。

因此,问题就转化成:我在框架页面里面的标题输入框,放进一个 <form> 表单,如何能把这个在 iframe 里面的 Editor 的内容也放进这个 <form> 表单一起提交?

办法就是,用 JavaScript 从框架页面里,把 iframe 页面里的富文本编辑器的内容,读取出来,放到 <form> 表单内部的一个隐藏字段,然后提交表单。这样提交表单时,就可以把标题和文章内容一起提交了。

因此,问题就转化为:如何从框架页面里面,读到 iframe 里面的东西?或者说,如何调用到 iframe 里面的页面的 JavaScript 函数。

解决上述问题的代码如下:

var a = document.querySelector("iframe");
var MyRichText = a.contentWindow.GetContent();

解释一下:

上述代码里面,GetContent() 函数是 Quill Editor 页面里面写的函数。这个函数从 Quill Editor 里面读出用户输入的富文本文字内容。

首先,通过 querySelector("iframe") 把 iframe 找到,然后,取它的 window,然后就是调用 JS 函数。

当然,这里取到 iframe 对象,然后取到它里面的 window 对象,也就可以取到底下的 document 对象,顺理成章就能取到 document 对象底下的按钮,输入框等等。

解决了这个问题,剩下的问题就简单了。用户点击提交按钮,从 iframe 里面读到富文本编辑器的内容后,把内容放到一个隐藏不显示的位于表单内的一个输入框里面,然后提交表单。

到此搞定,测试通过。

完整代码

富文本编辑器所在页面的代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Quill Form Submission</title>
    <script src="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet">
</head>
<body>
    <!-- quill 编辑器的封装 https://quilljs.com/ -->
    <script src="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet">

      <style>
        .edit_container {
            font-family: 'Avenir', Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            margin-top: 60px;
        }
        .ql-editor{
             height:400px;
         }
    </style>



    <div id="editor" class="edit_container">
    </div>



      <script>
          console.log("开始初始化 quill editor");

            const quill = new Quill("#editor", {
                modules: {
                toolbar: [
          { header: [1, 2, 3, 4, 5, 6, false] }, // 标题
          'bold',             // 加粗
          'italic',           // 斜体
          'blockquote',       // 引用
          'link',             // 超链接
          'image',            // 插入图片
          'video',            // 插入视频
          'code',             // 行内代码
          'code-block',       // 代码块
          { list: 'bullet' }, // 无序列表
          { list: 'ordered'}, // 有序列表
          'strike',           // 删除线
          { 'align': [] },    // 对齐方式
          'formula'           // 公式
        ]
                },
                theme: 'snow'
            });


            function GetContent(){
              const html = quill.root.innerHTML;
              //document.getElementById('htmlInput').value = html;
              var AContent = html;
              return AContent;
            };
      </script>
  </body>
</html>

框架页面的代码

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <title></title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2.0.6/css/pico.min.css"
    />
  </head>

  <body>
      <main class="container">
      这里是 Frame 的框架页面。里面是一个 iFrame 页面。

          <form id="myForm" action="ContentUpdate" method="post">
            <input type="hidden" name="html" id="htmlInput">
            <div><label for="MySubject1">标题<input type="text" value="这是标题" name="MySubject1" id="MySubject1" /></label></div>
          </form>

          <iframe id="MyEditor" src="http://localhost:8080/GetEditor" width="100%" height="550"  frameborder="no"></iframe>

          <div>
            <input type="submit" value="Submit" onclick="SubmitRichEditor()" />
          </div>
      </main>

      <script>
        function SubmitRichEditor(){
          var a = document.querySelector("iframe");
          var b = a.contentWindow.document;

          var c='';
          c = a.contentWindow.GetContent();

          console.log("开始从 quill 富文本编辑器读取内容");
          var hi = document.getElementById('htmlInput');
          hi.value = c;
          console.log(hi.value);

          console.log("开始提交");
          var AForm = document.getElementById('myForm');
          AForm.submit();

        };
      </script>
  </body>
</html>

页面图片:

结论

对于页面组件的封装,比如这个富文本编辑器,采用 iframe 看起来是一个比较简单好用的方式。至少比使用 Shadow DOM 的问题少。

当然,假如页面上有一大堆组件,每个都放进 iframe 的话,对浏览器的资源消耗会比较大,可能并不合适。

但是,单纯针对富文本编辑器来看,采用 iframe 来封装,应该是最佳方案。凡是需要它的页面,直接插入一个 iframe 就搞定,直接引入的是一个单独的页面。这个单独的页面,就可以作为一个组件,重复使用,实现代码重用。也让原本可能很复杂的页面简化,把富文本编辑器部分的代码抽离出来成为一个单独的文件,方便修改维护。当然,同时也实现了对 css 样式的封装和隔离,避免了 css 污染的问题。

one more thing...

为了解决这个富文本编辑器被 css 污染的问题,我还测试了7,8 个其它的开源免费的富文本编辑器,有一些不太好用,有一些同样会受到 css 污染,有一些功能又不太够,有一些入门的学习曲线比较陡峭,很难简单地创建一个页面就把它用起来。等等。但是,发现一个国产的富文本编辑器 wangEditor 很不错,功能强大,也很容易使用。它的工具栏样式也不受 Pico.css 的影响 --- 其实也受了点影响,工具栏按钮上的文字变大了。工具栏按钮文字变大后,看起来没那么好看美观,但不严重,不影响使用。而且,wangEditor 的在线文档也非常详细。必须赞一个。

那么,读到这篇文章的同学,也给这篇文章点个赞吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2176191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见字符函数和字符串函数(上)

1. 字符分类函数 字符分类函数是一类用于判断字符是否属于特定的字符类别&#xff08;如字母、数字、标点符号等&#xff09;的函数。在C语言中&#xff0c;这些函数通常可以在<ctype.h>头文件中找到&#xff0c;它们对于文本处理和输入验证非常有用。 这些函数通常返回…

Windows系统镜像下载

目前官网还可以下载的系统有Win10和Win11&#xff0c;Win7因为已经停止维护&#xff0c;所以只能到第三方镜像站下载&#xff0c;下面将具体展示下载方法。 Win7 下载地址&#xff1a;MSDN, 我告诉你 - 做一个安静的工具站 在操作系统中找到Windows 7&#xff0c;在右侧选择…

Python | Leetcode Python题解之第445题两数相加II

题目&#xff1a; 题解&#xff1a; class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:if head is None or head.next is None:return headnew_head self.reverseList(head.next)head.next.next head # 把下一个节点指向自己head…

魔都千丝冥缘——软件终端架构思维———未来之窗行业应用跨平台架构

一、创生-魔都千丝冥缘 在那神秘而复杂的数字世界里&#xff0c;软件的舞台上正上演着一场精彩的剧目。当面对终端单页面中如蛛网般交织的复杂业务逻辑&#xff0c;我们如同在迷雾中摸索前行。多个表单承载着各自的使命&#xff0c;却又有着相同字段的微妙关联&#xff0c;而内…

【C++前缀和 动态规划 贪心】813. 最大平均值和的分组|1936

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C动态规划 贪心(决策包容性) LeetCode813. 最大平均值和的分组 给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个非空子数组&#xff0c;且数组内…

【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术QueSearch

【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术Que2Search 目录 文章目录 【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术Que2Search目录0. 论文信息1. 研究背景&#xff1a;2. 技术背景和发展历史&#xff1a;3. 算法建模3.1 模型架构3.1.1 双塔与分类 …

物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程

一、前言 物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程 1、软件为绿色免安装版&#xff0c;解压即可使用&#xff0c;已经内置数据库&#xff0c;不需再安装。 2、软件下载可以到本文章最后点击官网卡片下。 二、软件程序教程 1、如图&#xff0c;…

C++入门(2)--引用

6.引用 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 类型& 引用变量名(对象名) 引用实体&#xff1b; //引用 //类型& 引用变量名(对象名) 引…

基于php的幸运舞蹈课程工作室管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

24-9-28-读书笔记(二十)-《契诃夫文集》(四)上([俄] 契诃夫 [译] 汝龙 )

文章目录 《契诃夫文集》&#xff08;四&#xff09;上&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09;目录阅读笔记记录总结 《契诃夫文集》&#xff08;四&#xff09;上&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09; 时间过得好快啊&#xff0c;马上又要十月份了&#x…

开源链动2+1模式AI智能名片小程序源码:放大特色,构建独特竞争力

摘要&#xff1a;本文探讨在当今社会背景下&#xff0c;开源链动21模式AI智能名片小程序源码如何通过坚持与众不同来构建独特竞争力。在信息传播便捷但个体易同质化的时代&#xff0c;拥有特色是脱颖而出的关键&#xff0c;而这种模式下的小程序源码具有独特的发展潜力。 一、引…

Golang | Leetcode Golang题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; func compress(chars []byte) int {write, left : 0, 0for read, ch : range chars {if read len(chars)-1 || ch ! chars[read1] {chars[write] chwritenum : read - left 1if num > 1 {anchor : writefor ; num > 0; num / 10 {…

bidict:Python 中高效的双向字典库

在 Python 编程中&#xff0c;字典&#xff08;dict&#xff09;是用于存储键值对的强大数据结构&#xff0c;能够快速地根据键查找值。然而&#xff0c;有时我们不仅需要从键查找值&#xff0c;还需要根据值查找键。这种双向查询需求在很多场景中很常见&#xff0c;如映射表、…

openEuler 修改网卡和常用网络配置

简介 1、网卡启用、禁用和查看状态 2、编辑网卡&#xff0c;配置静态Ip 3、删除之前网卡缓存的Ip 4、机器即连接内网&#xff0c;又连接外网 的网卡配置 5、openEuler 修改默认的镜像仓库&#xff08;推荐&#xff09;1、网卡启用、禁用和查看状态 # 查看网络状态 nmcli devi…

muduo网络库介绍

文章目录 MuduoServer常见接口TcpServer类EventLoop类TcpConnection类 服务器搭建Client常见接口TcpClient类 客户端搭建 Muduo Muduo是陈硕大佬开发的,一个基于非阻塞IO和事件驱动的C高并发网络编程库 这是一个基于主从Reactor模型的网络编程库,线程模型是one loop per thre…

K-means聚类分析对比

K-means聚类分析&#xff0c;不同K值聚类对比&#xff0c;该内容是关于K-means聚类分析的&#xff0c;主要探讨了不同K值对聚类结果的影响。K-means聚类是一种常见的数据分析方法&#xff0c;用于将数据集划分为K个不同的类别。在这个过程中&#xff0c;选择合适的K值是非常关键…

VSCode 中配置 C/C++ 环境的步骤

VSCode 中配置 C/C 环境的步骤 1. 安装 VSCode 1、下载位置 https://code.visualstudio.com/Download2、安装 正常操作步骤&#xff0c;同意协议&#xff0c;下一步&#xff0c;点击完成即可 2. 安装 C/C 扩展 打开 VSCode。 点击左侧的扩展图标&#xff08;或使用快捷键…

Linux网络:网络编程套接字

socket 套接字 socket常见API 创建套接字&#xff1a;&#xff08;TCP/UDP&#xff0c;客户端服务器&#xff09; int socket(int domain, int type, int protocol);绑定端口号&#xff1a;&#xff08;TCP/UDP&#xff0c;服务器&#xff09; int listen(int sockfd, int …

Python 算法交易实验89 QTV200日常推进-模式思考

说明 过去几天大A的表现还是比较戏剧化的。 让我想到了&#xff1a; 1 价稳量缩模式。之前很长一段时间都是这种状态&#xff0c;最终还是大爆发了&#xff0c;这个可取。2 周期模式。假设价格是一个周期为T(T可变)的正弦波&#xff0c;所以最终还是回到了几个月前的位置&…

Java 常用运算符简单总结

目录 1. 运算符​编辑 1.1 算术运算符​编辑 1.1.1 除法运算符​编辑 1.1.2 取模&#xff08;取余&#xff09;运算符​编辑 1.1.3 自增/减运算符​编辑​编辑 1.2 关系运算符 1.3 逻辑运算符 1.3.1 逻辑/短路与 1.3.2 逻辑/短路或 1.4 取反操作 1.5 逻辑异或 1.4 …