这里的答案是不要在聚合物中使用 tinymce,tinymce 严重依赖文档根目录,shadow dom 会破坏它。
但就像生活中的一切一样,一切都不会丢失......
在您的聚合物模板中使用一个对象,让该对象加载 tinymce 并解决文档根问题。一旦以这种方式加载,您就可以从对象访问 tinymce。
创建一个 HTML 文件来加载 tinymce
<!DOCTYPE html>
<html>
<head>
<script src="https://cloud.tinymce.com/stable/tinymce.min.js"></script>
<style>
html { height: 96%; }
body { height: 96%; }
</style>
</head>
<body>
<textarea>Loading...</textarea>
<script>
var ta = document.querySelector('textarea');
ta.tinymce = tinymce;
var editorChangeHandler;
tinymce.init({ selector: 'textarea', height: document.body.scrollHeight - 100, setup: function (editor) {
editor.on('Paste Change input Undo Redo', function () {
if (editorChangeHandler) { clearTimeout(editorChangeHandler); }
editorChangeHandler = setTimeout(function () {
ta.dispatchEvent(new CustomEvent('save'));
}, 2000);
});
} });
</script>
</body>
</html>
现在你只需要在你的组件模板中添加一个对象,使用对象的data属性来加载html。
加载后,您可以访问它,查询对象 dom 并获取 textarea,添加事件侦听器以保存自定义事件并预先设置内容,调整高度。我只测试了同一个域,因此请注意这可能会破坏跨域,但无论如何您都希望与其他组件一起提供服务。
将您的对象添加到组件模板中
<object id="editor" type="text/html" data="/src/lib/tinymce/tinymce.html"></object>
还有一些预加载、抓取东西、设置高度和捕捉保存的方法
ready() {
super.ready();
// wait five seconds before capturing input
var interval = setInterval(() => {
if (!this.$.editor.contentDocument.body) return;
let ta = this.$.editor.contentDocument.body.querySelector('textarea');
if (!ta || !ta.tinymce || !ta.tinymce.activeEditor) return;
// clear interval now loaded
window.clearInterval(interval);
setTimeout(() => {
// resize on window change
window.addEventListener('resize', this._updateEditorSize.bind(this));
// pre load
ta.tinymce.activeEditor.setContent(this.element.value);
// catch updates every few seconds, this will then have a 4 second debounce on save too naturally
ta.addEventListener('save', (ev) => {
this.set('element.value', ta.tinymce.activeEditor.getContent({ format: 'raw' }));
});
}, 250);
}, 250);
}
这是聚合物 3 和 tinymce 的工作场景,可快速加载、自动调整大小并从对象捕获保存事件,我不必更改 tinymce 的默认设置。您还可以将此方法用于其他方式来绕过某些嵌入式应用程序的 shadow dom。