在react单页应用集成tinymce 并且使用self-host 的时候,如果首次加载的页面不是tinymce的页面,那么从别的页面进入tinymce的页面会报错:
tinymce.min.js:9 Uncaught TypeError: Cannot read property 'open' of undefined
at Lz (tinymce.min.js:9)
at Iz (tinymce.min.js:9)
at jz (tinymce.min.js:9)
at WE.<anonymous> (tinymce.min.js:9)
at Array.<anonymous> (tinymce.min.js:9)
at On (tinymce.min.js:9)
at i (tinymce.min.js:9)
at tinymce.min.js:9
at HTMLScriptElement.r.onload (tinymce.min.js:9)
这是由于没有获得iframe的window对象。至于为什么没获得 暂不深究 ,先解决问题。
从官方的@tinymce/tinymce-react 源码中找到了这一段代码:
Editor.prototype.getScriptSrc = function () {
if (typeof this.props.tinymceScriptSrc === 'string') {
return this.props.tinymceScriptSrc;
}
else {
var channel = this.props.cloudChannel;
var apiKey = this.props.apiKey ? this.props.apiKey : 'no-api-key';
return "[https://cdn.tiny.cloud/1/](https://cdn.tiny.cloud/1/)" + apiKey + "/tinymce/" + channel + "/tinymce.min.js";
}
};
由此可见,官方的做法是每次初始化的时候都会去校验,加载js文件。考虑到tinymce-react 最大的问题 就是需要去官方的地址加载文件。所以,我们主要需要解决的就是去自己的路径加载文件。解决思路,就是直接把官方的实现拿来,然后,改掉里面的路径。
把官方的代码直接copy过来 ,改下依赖和加载路径即可。
react-editor里面的就是官方的代码。原来的代码改成这样:
import React, {useEffect, useRef} from "react";
import _ from "lodash";
import {Editor} from "./react-editor";
const TinymceEditor = ({value, onChange, height, uploadAction}) => {
const tinymceEditorRef = useRef();
useEffect(() => {
let editor = tinymceEditorRef.current;
if (editor) {
if (value !== editor.getContent()) {
editor.setContent(value);
}
}
}, [value]);
return <>
<Editor initialValue={value} init={{
branding: false,
language: 'zh_CN',
statusbar: true,
browser_spellcheck: true,
height: height,
menubar: false,
init_instance_callback: (editor) => {
},
images_upload_handler: function (blobInfo, succFun, failFun) {
let file = blobInfo.blob();
let formData = new FormData();
formData.append("file", file);
if (uploadAction) {
uploadAction(formData).then((result) => {
succFun(result.url);
});
}
},
}}
plugins={['advlist autolink link image lists']}
toolbar={'undo redo | styleselect | bold italic bullist numlist forecolor backcolor | alignleft aligncenter alignright alignjustify | outdent indent | link image'}
onInit={(initEvent, editor) => {
tinymceEditorRef.current = editor;
}}
onEditorChange={(content, editor) => _.debounce(() => {
if (onChange) {
onChange(content);
}
}, 500)}
/>
</>
}
export default TinymceEditor
在tinymce-react v3.5.0 版本下 ,我发现有了 tinymceScriptSrc 这个配置项,可以直接配置 tinymce.min.js的地址,不需要自己去重写了。