TinyMCE 5是一款功能强大且灵活的富文本编辑器,可以嵌入Web应用程序中.
1.在HTML代码中
<head>
标签中引入下边的代码块
<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
*
如果使用webpack包管理工具
npm install tinymce
您也可以通过 tinyMCE 自定义自己所需要的pugins,以满足自己需求的同时,可以减少包的重量
2.在<body>
中加入如下HTML代码
<h1>TinyMCE Quick Start Guide</h1>
<form method="post">
<textarea id="mytextarea">Hello, World!</textarea>
</form>
</body>
3.新增<script>
标签,调用tinymce的init
方法
<script>
tinymce.init({
selector: '#mytextarea'
});
</script>
当你引入tinyMCE插件时,全局自动注入tinymce
对象,你可以在任何位置去调用它的方法,您可以使用console.log(tinymce)
去查看它的所有方法
此时您的页面已初步构建完成,打开浏览器,可以看到如下的功能页面
下面我们就开始完善适合需求的各项功能组件
window.tinymce.init({
selector: `#mytextarea`,
language: "zh",
width:'300px',
height: '300px',
font_formats:
"宋体=SimSun;微软雅黑=Microsoft Yahei;华文黑体=STHeiti;华文楷体=STKaiti;华文仿宋=华文仿宋;思源黑体=Source Han Sans CN;思源宋体=Source Han Serif SC;华文细黑=STXihei;黑体=SimHei;方正粗圆简体=方正粗圆简体;Andale Mono=andale mono,times;",
fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
contextmenu://
"link image imagetools inserttable | cell row column deletetable | headings",
content_css: [
"//fonts.googleapis.com/css?family=Lato:300,300i,400,400i",
"//www.tinymce.com/css/codepen.min.css"
body_class: "panel-body",
object_resizing: false,
toolbar: [
'undo redo |styleselect| bold italic forecolor backcolor | fontselect |fontsizeselect | alignleft aligncenter alignright alignjustify |' +
'ht| bullist numlist outdent indent | removeformat|' +
'link image media code codesample hr charmap preview anchor pagebreak insertdatetime me blocks' +
'dia emoticons fullscreen save'
menubar: "file edit insert view format table",
plugins: ['advlist anchor autolink autosave code codesample directionality emoticons fullscreen hr image imagetools media insertdatetime link lists nonbreaking noneditable pagebreak powerpaste preview print save searchreplace spellchecker tabfocus table textpattern visualblocks visualchars quickbars charmap'],
quickbars_selection_toolbar:
"bold italic underline forecolor backcolor | fontselect |fontsizeselect | formatselect | quicklink blockquote",
quickbars_image_toolbar:
"alignleft aligncenter alignright quicklink | imageoptions",
formats: {
alignleft: {
block: "div",
styles: { display: "flex", justifyContent: "flex-start" },
classes: "left"
aligncenter: {
block: "div",
styles: {
display: "flex",
justifyContent: "center"
classes: "center"
alignright: {
block: "div",
styles: { display: "flex", justifyContent: "flex-end" },
classes: "right"
quickbars_insert_toolbar: "quickimage quicktable media",
autosave_restore_when_empty: false,
end_container_on_empty_block: true,
powerpaste_word_import: "merge",
powerpaste_html_import: "merge",
powerpaste_allow_local_images: true,
paste_data_images: true,
paste_preprocess: (pluginApi, data) => {
const content = data.content;
const newContent = this.yourCustomFilter(content);
data.content = newContent;
code_dialog_height: 450,
code_dialog_width: 1000,
charmap_append: [],
imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
image_advtab: false,
default_link_target: "_blank",
link_title: false,
media_live_embeds: true,
file_picker_types: "media",
media_alt_source: false,
media_url_resolver: function(data, resolve) {
try {
let videoUri = encodeURI(data.url);
let embedHtml = `<p><video controls="controls" width="100%" height="auto"> <source src="${videoUri}" type="video/mp4" /></video></p> <p style="text-align: left;"> </p>`;
resolve({ html: embedHtml });
} catch (e) {
resolve({ html: "" });
save_enablewhendirty: true,
nonbreaking_force_tab: true,
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value);
_this.hasInit = true;
editor.on("NodeChange Change KeyUp SetContent", () => {
if (this.value !== "") {
this.hasChange = true;
this.$emit("input", editor.getContent());
});
save_onsavecallback: () => {
let content = window.tinymce.get(this.id).getContent();
if (this.newImgUrl.length) {
content = content.replace(
/<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
(mactch, capture) => {
let current = "";
console.log(this.newImgUrl);
for (let i = 0; i < this.newImgUrl.length; i++) {
console.log(
capture.replace(/(&)/gi, "&") ==
this.newImgUrl[i].originUrl
if (
capture.replace(/(&)/gi, "&") ==
this.newImgUrl[i].originUrl
current = this.newImgUrl[i].url;
break;
current = current ? current : capture;
return mactch.replace(
/src=[\'\"]?([^\'\"]*)[\'\"]?/i,
"src=" + current
}
setup(editor) {
editor.on("FullscreenStateChanged", e => {
_this.fullscreen = e.state;
});
images_upload_handler(blobInfo, success, failure, progress) {
urlconverter_callback(url, node, on_save, name) {
const assignUrl = [
"blob:http://localhost",
"data:image/gif;base64"
let curl = url;
let isInnerUrl = false;
try {
assignUrl.forEach(item => {
if (url.indexOf(item) > -1) {
isInnerUrl = true;
throw new Error("EndIterate");
});
} catch (e) {
if (e.message != "EndIterate") throw e;
if (node == "img" && !isInnerUrl) {
let json;
getBase64(url).then(base64 => {
const url = ``;
request({
url,
file: data2blob(base64, mimes["png"]),
filename: "file" + "." + "png"
}).then(res => {
if (res.data.code == 0) {
_this.newImgUrl.push({
originUrl: curl,
url: res.data.data.url
});
} else {
failure("Invalid JSON: " + res.data.data.msg);
});
});
return url;
});
因为复制粘贴组件powerpaste是收费项目,但又是一个完整编辑器不可或缺的功能,所以这里给出它的下载地址 https://download.csdn.net/download/wddwwwq1/12579334,请自行下载。
在这里我们重点讲解关于powerpaste
的功能构建
urlconverter_callback(url, node, on_save, name) {
const assignUrl = [
"blob:http://localhost",
"data:image/gif;base64",
"http://192.168.2.221",
"http://192.168.2.222",
"http://192.168.2.223",
"http://192.168.2.224",
let curl = url;
let isInnerUrl = false;
try {
assignUrl.forEach(item => {
if (url.indexOf(item) > -1) {
isInnerUrl = true;
throw new Error("EndIterate");
});
} catch (e) {
if (e.message != "EndIterate") throw e;
if (node == "img" && !isInnerUrl) {
let json;
getBase64(url).then(base64 => {
const url =
process.env.NODE_ENV !== "production"
? ""
: "";
request({
url,
file: data2blob(base64, mimes["png"]),
filename: "file" + "." + "png"
}).then(res => {
if (res.data.code == 0) {
_this.newImgUrl.push({
originUrl: curl,
url: res.data.data.url
});
} else {
failure("Invalid JSON: " + res.data.data.msg);
});
});
return url;
上述代码是复制粘贴功能的核心,因为我们复制的图片不一定是自己服务器的图片,所以我们需要把其他服务器的http图片,保存在我们的服务器上。
-
当编辑器文本中包含有图片首先我们给出一个数组assignUrl
,列出您不想让编辑器检测的域名,然后使用回调函数的url
去检查是否跟数组白名单的域名相匹配,如果包含,则表示是自己服务器的图片,不需要再上传服务器。
-
urlconverter_callback
回调函数有四个参数(url, node, on_save, name)
,其中url
表示检测的链接地址,node
则表示此链接所在的标签名字。例如<a href="http://www.baidu.com"></a>
和<img src="https://timgsa.baidu.com/timg.jpg" />
-
判断node == img && !isInnerUrl
,如果为true
,则表明我们需要手动上传图片到我们自己的服务器,首先把http格式的图片转换为base64
export default function(img) {
function getBase64Image(img, width, height) {
var canvas = document.createElement("canvas");
canvas.width = width ? width : img.width;
canvas.height = height ? height : img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL();
return dataURL;
var image = new Image();
image.crossOrigin = '';
image.src = img;
var deferred = new Deferred();
if (img) {
image.onload = function() {
deferred.resolve(getBase64Image(image));
} else {}
return deferred.promise;
function Deferred() {
var self = this;
self.promise = new Promise(function(resolve, reject) {
self._resolve = resolve;
self._reject = reject;
});
Deferred.prototype.resolve = function(data) {
this._resolve(data);
Deferred.prototype.reject = function(data) {
this._reject(data);
这里使用canvas
画图工具转换图片,最后使用canvas.toDataURL()
在转换为base64的图片格式
说明:如不了解canvas
,请自行学习
- 因为上传图片是异步,并且上传需要时间,等待服务器返回图片地址时,我们已经把文本显示在编辑器之中,所以在我们
return url
的时候,还没有得到返回结果,由于tinymce
不支持异步处理函数,我尝试用async await
处理也没有实际作用,所以我们可以在点击保存文本的时候去手动替换需要替换的图片地址,在上传图片返回结果时我们把图片地址保存在一个数组之中_this.newImgUrl.push({ originUrl: curl, url: res.data.data.url });
,以便在保存的时候操作回填。
save_onsavecallback: () => {
let content = window.tinymce.get(this.id).getContent();
if (this.newImgUrl.length) {
content = content.replace(
/<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
(mactch, capture) => {
let current = "";
for (let i = 0; i < this.newImgUrl.length; i++) {
if (
capture.replace(/(&)/gi, "&") ==
this.newImgUrl[i].originUrl
current = this.newImgUrl[i].url;
break;
current = current ? current : capture;
return mactch.replace(
/src=[\'\"]?([^\'\"]*)[\'\"]?/i,
"src=" + current
}
因为我使用的VUE构建,代码块里的this
请自行注意理解
*参考链接地址
【tinyMce官方文档】:https://www.tiny.cloud/docs/
1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况
本文使用的后台是Java。前端为Jsp(前端都一样,后台如果语言不通得自己做 Base64编码解码)
因为公司业务需要支持IE8 ,网上其实有很多富文本框,效果都很好。
例如www.wangEditor.com 但试了一圈都不支持IE8 。
所以回到Ueditor,由于官方没有维护,新的neuditor 也不知道什么时候能支持word自动转存,只能自己想办法。
如果没有必要,不建议使用.
tinymce是很优秀的一款富文本编辑器,可以去官网下载。https://www.tiny.cloud
这里分享的是它官网的一个收费插件powerpaste的旧版本源码,但也不影响功能使用。
http://blog.ncmem.com/wordpress/2019/08/07/umeditor%E7%B2%98%E8%B4%B4word%E5%9B%BE%E7%89%87/
以vue为例说明:
将tinymce下载后放到static目录下,不用npm安装。
powerpaste放到\static\
很多时候我们用一些管理系统的时候,发布新闻、公告等文字类信息时,希望能很快的将word里面的内容直接
粘贴到
富文本编辑器里面,然后发布出来。减少排版复杂的工作量。
下面是借用百度doc 来快速实现这个word
粘贴到
富文本编辑器里面
工具/原料
百度doc
任意
富文本编辑器,以UEDdito为例
方法/步骤
登录,http://word.baidu.com
点击右上角 导入文档,如图所示
导入后,系统会自动将word的内容加载进去。此时 点击右上角编辑,Ctrl+A复制所有内容
这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用
后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)
<%@pagelanguage="java"import="java.util.*"pageEncoding="utf-8"%><%@
pagecontentType="text/html;charset=utf-8"%><%@
pageim...
要在tinymce/tinymce-vue富文本编辑器中实现图片上传功能,你可以按照以下步骤操作:
1. 首先,确保你已经安装了tinymce和tinymce-vue的依赖包。你可以去[TinyMCE官方网站](https://www.tiny.cloud/get-tiny/self-hosted/)下载最新的TinyMCE压缩包,并解压到你的项目目录中。然后,安装tinymce-vue依赖包,可以使用npm或yarn进行安装。
2. 接下来,将TinyMCE的skins文件夹复制到你的项目的public文件夹下。这个文件夹包含了富文本编辑器的样式文件。
3. 然后,创建一个Vue组件来封装el-upload控件,并将其整合到tinymce-vue中。你可以将这个组件放在你的项目的src/components文件夹下。具体的组件代码可以参考上述提供的链接。
通过以上步骤,你就可以在tinymce/tinymce-vue富文本编辑器中实现图片上传功能了。请注意,这只是一种实现方式,具体的实现方式可能因项目需求的不同而有所差异。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* [vue3 中 tinymce+tinymce-vue 富文本编辑器使用](https://blog.csdn.net/oooosadas/article/details/131176384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
- *3* [vue-tinymce 富文本编辑器自定义图片上传](https://download.csdn.net/download/hadues/13183093)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
[ .reference_list ]