htmledit_views">
背景:vue项目,同一个页面存在多个编辑器场景。
按照往常一样,将编辑器封装成组件然后在页面引入,只能显示最后渲染的一个编辑器,前面渲染的都会消失。尝试过直接用iframe指向文档地址,不用金山提供的jdk还是有一样的问题。
下面是金山的开发给的解决方案:
以下是我根据自己的情况实现的:这个html和需要用到的jdk放在public文件夹中
html">// KSIframe.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>www</title>
</head>
<body>
</body>
<script src="./open-jssdk-v0.0.13.umd.js"></script>
<script>window.onload = () => {const params = new URLSearchParams(window.location.search);console.log(params.get('url'), 'url')// console.log(params.get('editorId'), 'editorId')// console.log(params.get('isShowTopArea'), 'isShowTopArea')// console.log(params.get('isShowHeader'), 'isShowHeader')// console.log(params.get('isEditable'), 'isEditable')const param1 = params.get('url')const param2 = params.get('editorId')const isEdit = params.get('isEditable') === 'true';const isShowTopArea = params.get('isShowTopArea') === 'true';const isShowHeader = params.get('isShowHeader') === 'true';const url = param1let div = document.createElement('div');div.setAttribute('id', param2); // 设置iframe的IDdiv.style.height = '520px'
// 将div添加到DOM中document.body.appendChild(div); // 添加到body的末尾const KSInstance = OpenSDK.config({url,mount: document.querySelector("#"+param2), // 挂载 iframe 节点commandBars: [{cmbId: 'HeaderMiddle', // 组件 IDattributes: {enable: isEdit, // 禁用组件(组件显示但不响应点击事件)},},],wordOptions: {enableReadOnlyComment: isEdit,isBestScale: false, // 打开文档时,默认以最佳比例显示},commonOptions: {isShowTopArea, // 隐藏顶部区域(头部和工具栏)isShowHeader, // 隐藏头部区域// isBrowserViewFullscreen: false, // 是否在浏览器区域全屏// isIframeViewFullscreen: false, // 是否在 iframe 区域内全屏// acceptVisualViewportResizeEvent: true, // 控制 WebOffice 是否接受外部的 VisualViewport},});window.addEventListener('message', function(event) {// console.log(event.origin, '------>', window.location.origin);if (event.origin !== window.location.origin) {return; // 只接受来自特定源的消息}// console.log('Received message:', event.data);let getData = event.dataswitch (getData.type) {case 'insertEle':insertEle(getData.content, getData.markName)break;case 'setMode':setMode(getData.mode);break;case 'deleteEle':deleteEle(getData.key);break;default:console.log('没这个方法')}// 可以回复消息// event.source.postMessage('Hi there!', event.origin);}, false);async function insertEle(content, markName) {await KSInstance.ready();const selection = await KSInstance.Application.ActiveDocument.ActiveWindow.Selection// 区域对象const range = await selection.Rangeconst start = await range.Startconst end = start + content.length// 在选区后面插入内容await selection.InsertAfter(content)// const end = await range.End// console.log(range, 'range')// console.log(start, 'start1')// console.log(end, 'end1')await KSInstance.Application.ActiveDocument.Bookmarks.Add({Name: markName,Range: {Start: start,End: end}})const marks1 = await KSInstance.Application.ActiveDocument.Bookmarks.Json()}async function setMode(mode){await KSInstance.ready();const app = KSInstance.Applicationawait app.ActiveDocument.SetReadOnly({Value: mode === 'preview'})}async function deleteEle(ceebElemPlaceHolder) {await KSInstance.ready();const app = KSInstance.Applicationapp.ActiveDocument.ReplaceText([{key: ceebElemPlaceHolder,value: ''}])}};
</script>
</html>
文档地址
等初始化需要用到的参数,放在父页面iframe的src中,通过路由参数传递。其它对文档的操作,用iframe通信的方式实现。
let urlEncoded = encodeURIComponent(fileUrl),src = `/KSIframe.html?url=${urlEncoded}&editorId=${this.editorId}&isShowTopArea=${this.isShowTopArea}&isShowHeader=${this.isShowHeader}&isEditable=${this.isEditableFile}`this.$nextTick(()=>{let box = document.getElementById(this.editorBoxId) // 插入iframe的父元素// 移除所有子元素box.replaceChildren();let iframe = document.createElement('iframe')iframe.setAttribute('src', src)iframe.setAttribute('id', this.editorIframeId)iframe.style.height = '500px'iframe.style.width = '100%'function handleLoaded(){let postData = {type: 'setMode',mode: isPreview ? 'preview' : 'edit'}iframe.contentWindow.postMessage(postData, window.location.origin);this.removeEventListener('load', handleLoaded, false);}iframe.addEventListener('load', handleLoaded, false);box.appendChild(iframe)})
iframe通信操作文档内容:
let iframe = document.getElementById(this.editorIframeId)
let postData = {type: 'deleteEle',key: yourKey
}
iframe.contentWindow.postMessage(postData, window.location.origin);let iframe = document.getElementById(this.editorIframeId)
let postData = {type: 'insertEle',content,markName,
}
iframe.contentWindow.postMessage(postData, window.location.origin);