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

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

时间:2024-09-29 22:50:35浏览次数:10  
标签:WEB 文本编辑 Pico Quill iframe css 页面

这个系列已经写了 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/[email protected]/dist/quill.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/quill.snow.css" rel="stylesheet">
</head>
<body>
    <!-- quill 编辑器的封装 https://quilljs.com/ -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/quill.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/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/[email protected]/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 的在线文档也非常详细。必须赞一个。

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

标签:WEB,文本编辑,Pico,Quill,iframe,css,页面
From: https://blog.csdn.net/pcplayer/article/details/142624606

相关文章

  • 【Web APIs day 03 事件流、事件委托、其他事件:优化多个事件绑定和实现常见网页交互】
    WebAPIs-第3天目标:学习事件流,事件委托,其他事件等知识,优化多个事件绑定和实现常见网页交互事件流移除事件监听其他事件元素尺寸与位置综合案例事件流为什么要学习事件流?可以帮我们解决一些疑惑,比如点击子盒子会会弹出2次的问题事件流指的是事件完整执行过程中的......
  • Delphi 12.2 新增的 WebStencils 尝鲜
    WebStencils是Delphi新增的服务器端WEB控件 这个玩意怎么用,用起来有意义吗?试试才知道。以下测试的描述都是基于DelphiWebBroker这个WEB服务器端框架。最新出来的,各方面资料很少,官方也没有详细文档,只能自己摸索。网上我能够搜到的相关资料:corneliusdavid/webste......
  • 阿里云 SAE Web:百毫秒高弹性的实时事件中心的架构和挑战
    作者:胡志广(独鳌)背景Serverless应用引擎SAE事件中心主要面向早期的SAE控制台只有针对于应用维度的事件,这个事件是K8s原生的事件,其实绝大多数的用户并不会关心,同时也可能看不懂。而事件中心,是希望能够成为一个更高维度入口,可以总览全局的事件(着重于异常事件),并且配置相关......
  • webGL入门(五)绘制多边形
    代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • webGL入门对于LINES_STRIP与LINE_STRIP绘制连线的不同之处
    图片对比:上图为LINE_STRIP 上图为LINES_STRIPLINE_STRIP代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0&q......
  • Web服务器小项目(Linux / C / epoll)
    欢迎访问我的另一个博客:https://xingzhu.top/注意:前置知识:HTTP:https://xingzhu.top/archives/web-fu-wu-qiLinux多线程:https://xingzhu.top/archives/duo-xian-cheng源码放github上了,欢迎star:https://github.com/xingzhuz/webServer思路实现代码server.h......
  • Web 服务器
    欢迎访问我的另一个博客:https://xingzhu.top/项目:https://xingzhu.top/archives/webfu-wu-qi-xiao-xiang-mu-linux-c-epollHTTP协议客户端(浏览器):通过浏览器地址栏给服务器发送请求,浏览器内部进行数据的封装根据http协议进行封装,封装完毕,数据发送给服务器等待......
  • JavaWeb之过滤器
    1.过滤器的概念过滤器是JavaServlet规范中定义的组件,用于在请求到达Servlet之前或响应返回客户端之前,对请求或响应进行拦截和处理。过滤器可以实现以下功能:日志记录:记录请求的详细信息,如URI、参数、时间等。身份验证和授权:检查用户是否已登录,是否有权限访问资源。输入输出......
  • Java Web开发:实际问题与解决方案
    引言在JavaWeb开发中,面对高并发、复杂业务逻辑和安全威胁等挑战,开发者需要灵活应对,找到有效的解决方案。本文将探讨一些实际开发中常见的问题,并结合最新技术提供切实可行的解决方案和示例代码。1.性能瓶颈1.1问题描述随着用户访问量的增长,应用的性能可能出现瓶颈,导致响......
  • Python Web 应用中的 API 网关集成与优化
    PythonWeb应用中的API网关集成与优化目录......