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

这个系列已经写了 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.xdnf.cn/news/1549807.html

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

相关文章

深度学习反向传播-过程举例

深度学习中&#xff0c;一般的参数更新方式都是梯度下降法&#xff0c;在使用梯度下降法时&#xff0c;涉及到梯度反向传播的过程&#xff0c;那么在反向传播过程中梯度到底是怎么传递的&#xff1f;结合自己最近的一点理解&#xff0c;下面举个例子简单说明&#xff01; 一、…

锐捷 NBR 1300G路由器 越权CLI命令执行漏洞

漏洞描述 锐捷NBR 1300G路由器 越权CLI命令执行漏洞&#xff0c;guest账户可以越权获取管理员账号密码 漏洞复现 FOFA title"锐捷网络 --NBR路由器--登录界面" 请求包 POST /WEB_VMS/LEVEL15/ HTTP/1.1 Host: Connection: keep-alive Content-Length: 73 Autho…

网络编程(12)——完善粘包处理操作(id字段)

十二、day12 之前的粘包处理是基于消息头包含的消息体长度进行对应的切包操作&#xff0c;但并不完整。一般来说&#xff0c;消息头仅包含数据域的长度&#xff0c;但是如果要进行逻辑处理&#xff0c;就需要传递一个id字段表示要处理的消息id&#xff0c;当然可以不在包头传i…

naocs注册中心,配置管理,openfeign在idea中实现模块间的调用,getway的使用

一 naocs注册中心步骤 1 nacos下载安装 解压安装包&#xff0c;直接运行bin目录下的startup.cmd 这里双击运行出现问题的情况下 &#xff08;版本低的naocs&#xff09; 在bin目录下 打开cmd 运行以下命令 startup.cmd -m standalone 访问地址&#xff1a; http://localh…

一文了解:最新版本 Llama 3.2

Meta AI最近发布了 Llama 3.2。这是他们第一次推出可以同时处理文字和图片的多模态模型。这个版本主要关注两个方面&#xff1a; 视觉功能&#xff1a;他们现在有了能处理图片的模型&#xff0c;参数量从11亿到90亿不等。 轻量级模型&#xff1a;这些模型参数量在1亿到3亿之间…

基于SSM+小程序的高质量阅读微信管理系统(阅读5)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 1、其管理员管理文章&#xff0c;留言板&#xff0c;交流论坛以及用户信息。 2、用户收藏并评论文章&#xff0c;查看和评论论坛交流信息&#xff0c;管理自己发布的帖子&#xff0c;管理…

数据结构与算法笔记7:最小生成树-Prim和Kruskal算法

常用的最小生成树的算法主要有两种&#xff0c;一种是Prim算法&#xff0c;一种是Kruskal算法。题目链接&#xff1a;KamaCoder 53. 寻宝&#xff08;第七期模拟笔试&#xff09; 这里假设有V个节点&#xff0c;因为我们的节点的标号是1~V&#xff0c;这样我们直接使用标号作…

队列及笔试题

队列 先进先出 使用单链表进行队尾插入 队头删除 其中带头结点直接尾插&#xff0c;不带头结点第一次操作要判断一下 但是带头结点需要malloc和free 函数传需要修改的参数方法 1、二级指针 2、带哨兵位的头结点 3、返回值 4、如果有多个值&#xff0c;用结构体封装起来…

努比亚 Z17 NX563J Root 教程三方REC刷写工具教程

教程&#xff1a;1&#xff0c;自用成功 正常链接列表 adb devices 检查fastboot链接列表 fastboot devices 解锁设备fastboot oem nubia_unlock NUBIA_NX563J 我用的解锁设备是&#xff1a;fastboot flashing unlock 1.打开开发者选项。将OEM解锁的按钮打开 2.下载附件努…

甄选范文“论企业应用系统的数据持久层架构设计”,软考高级论文,系统架构设计师论文

论文真题 数据持久层(Data Persistence Layer)通常位于企业应用系统的业务逻辑层和数据源层之间,为整个项目提供一个高层、统一、安全、并发的数据持久机制,完成对各种数据进行持久化的编程工作,并为系统业务逻辑层提供服务。它能够使程序员避免手工编写访问数据源的方法…

MQ基础:RabbitMQ真面目

同步调用方式&#xff0c;指的是发送方直接发送给接收方的形式。而这种方式在某些情况下可能出现问题&#xff0c;比如当业务逻辑变得复杂&#xff0c;同步的方式需要等待上一条指令被接收后才会继续&#xff0c;对性能的影响很大。 异步的方式&#xff0c;增加了一个消息代理…

微信小程序操作蓝牙

主要流程&#xff1a; 1.初始化蓝牙适配器openBluetoothAdapter&#xff0c;如果不成功就onBluetoothAdapterStateChange监听蓝牙适配器状态变化事件 2.startBluetoothDevicesDiscovery开始搜寻附近的蓝牙外围设备 3.onBluetoothDeviceFound监听寻找到新设备的事件&#xff0c;…

PHP爬虫淘宝商品SKU详细信息获取指南

在电子商务领域&#xff0c;获取商品的SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;详细信息对于商家进行库存管理、订单处理和客户服务至关重要。淘宝作为中国最大的电商平台之一&#xff0c;提供了丰富的API接口&#xff0c;使得开发者能够通过PHP爬虫…

前端学习笔记-JS进阶篇-02

构造函数&数据常用函数 1、深入对象 1.1、创建对象三种方式 1. 利用对象字面量创建对象 2. 利用new Object 创建对象 3. 利用构造函数创建对象 1.2、构造函数 构造函数&#xff1a;是一种特殊的函数&#xff0c;主要用来初始化对象 使用场景&#xff1a;常规的{...} 语…

springboot购物网站源码分享

开头&#xff1a;springboot购物网站源码分享 题目&#xff1a;springboot购物网站源码分享 主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Mysql|大数据|SSM|SpringBoot|Vue|Jsp|MYSQL等)、学习资料、JAVA源码、技术咨询 文末联系获取 感兴趣可以先收藏起来&#xff…

报数游戏 - 华为OD统一考试(E卷)

2024华为OD机试&#xff08;E卷D卷C卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 100个人围成一圈&#xff0c;每个人有一个编号&#xff0c;编号从1开始到100。他们从1开始依次报数&#xff0c;报到为M的人自动退出圈圈&#xff0c;然后下一个人接着从1开始…

基于SpringBoot+Vue的茶园茶农文化交流平台

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

【MySQL实战45讲4-5】索引

文章目录 索引的定义索引的常见模型哈希表有序数组二叉搜索树 InnoDB的索引模型索引维护页分裂页合并页分裂和页合并的影响避免页分裂 覆盖索引最左前缀原则索引下推 索引的定义 索引的出现其实就是为了提高数据查询的效率&#xff0c;就像书的目录一样。一本500页的书&#x…

tee命令:轻松同步输出到屏幕与文件

一、命令简介 ​tee​ 命令在 Linux 和 Unix 系统中用于读取标准输入的数据&#xff0c;并将其同时输出到标准输出和文件中。简单来说&#xff0c;tee​ 命令可以用来分割数据流&#xff0c;使其既能够被输出到屏幕&#xff0c;也能够被写入到文件中。 ​​ ‍ 二、命令参数…

基于PI控制器的车辆行驶控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 步骤一: 确定目标与测量 4.2 步骤二: 计算误差 4.3 步骤三: 设计PI控制器 4.4 步骤四: 应用控制信号 4.5 步骤五: 反馈循环 5.完整工程文件 1.课题概述 基于PI控制器的车辆行驶控制系统是一种常…