wangeditor是后盾比拟罕用的一个富文本编辑器,官网链接:https://www.wangeditor.com/
留神:
兼容支流的 PC 浏览器,如 Chrome Firefox Safari Edge 等。
暂不反对挪动端编辑(反对挪动端查看)。
不再反对 IE 浏览器。
我的需要,可能在挪动端编辑、查看,并且可能联动后盾。
我在网上找了很多挪动端的富文本编辑器,都不合乎我的需要,最初应用了webview的形式去实现wagneditor4版本。
具体实现代码如下:
index.vue文件代码
<template> <view class="initiateContract"> <div class="headerTip" :style="'margin-top:' + height + 'px;'"> <div class="title"> <div class="txt">{{ contractDetails.title }}</div> <div class="status"> <u-tag v-if="contractDetails.flow_status === '1'" :text="contractDetails.flow_status_name" type="info" size="mini" plain></u-tag> <u-tag v-if="contractDetails.flow_status === '2'" :text="contractDetails.flow_status_name" type="warning" size="mini" plain></u-tag> <u-tag v-if="contractDetails.flow_status === '3'" :text="contractDetails.flow_status_name" type="warning" size="mini" plain></u-tag> <u-tag v-if="contractDetails.flow_status === '5'" :text="contractDetails.flow_status_name" type="success" size="mini" plain></u-tag> </div> </div> <div class="info">留神:合同签订区的代码英文,如company_sign、demand_sign、aunt_sign等英文代码请勿删除</div> </div> <view class="html-box"> <web-view :src="'../../../hybrid/html/viewContract/index.html?data=' + obj" @message="getMessage" ref="wv"></web-view> </view> <view class="footer" v-if="isKeyboard === false"> <view class="box"> <view class="item" v-if="contractDetails.flow_status == '1'" @click="saveContract"> <view class="btn"> <u-button type="primary" :key="1" :plain="true" text="保留合同"></u-button> </view> </view> <view class="item"> <view class="btn"> <u-button type="primary" :key="2" text="分享预览"></u-button> </view> </view> <view class="item" v-if="contractDetails.flow_status == '1'" @click="openConfirmSigning"> <view class="btn"> <u-button type="primary" :key="3" text="开始签约"></u-button> </view> </view> <view class="item" v-if="contractDetails.flow_status !== '1'"> <view class="btn"> <u-button :disabled="true" :key="4" type="success" text="签约中"></u-button> </view> </view> </view> </view> </view></template><script> import cluesHttp from '@/api/client/index.js' var wv export default { name: "electronContractEdit", data() { return { dianzi_hetong_id: '', form: { id: '0', hetong_id: '', muban_id: '', }, contractDetails: {}, contractContent: '', currentWebview: null, shareImgInfo: {}, isKeyboard: false, contentHtml: '', } }, onLoad() { const vm = this; uni.$on('to-parent', (data) => { switch( data.type ){ case '1': uni.setClipboardData({ data: this.shareImgInfo.result.tips, success: function () { uni.showToast({ icon: 'none', title: '链接已复制' }) } }); break; case '2': break; } }); // 获取上个页面传来的参数 const self = this const eventChannel = this.getOpenerEventChannel(); eventChannel.on('getInitiateContractParams', function(res) { _this.contractDetails = res _this.dianzi_hetong_id = res.id self.currentWebview = self.$scope.$getAppWebview().children()[0] self.currentWebview.evalJS(`getParams(${JSON.stringify(res)})`) }) }, onReady() { // #ifdef APP-PLUS var currentWebview = this.$scope.$getAppWebview() setTimeout(function() { wv = currentWebview.children()[0] wv.setStyle({ top: uni.getStorageSync('navbarHeight') + 84, bottom: 71, width: uni.getSystemInfoSync['screenWidth'] }) }, 100); // 键盘升起,避免遮挡编辑器内容 uni.onKeyboardHeightChange((res) => { if(this.isKeyboard === true) { this.isKeyboard = false wv.setStyle({ top: uni.getStorageSync('navbarHeight') + 84, bottom: 71, width: uni.getSystemInfoSync['screenWidth'] }) } else { this.isKeyboard = true wv.setStyle({ top: uni.getStorageSync('navbarHeight') + 84, bottom: res.height, width: uni.getSystemInfoSync['screenWidth'] }) } }) // #endif }, methods: { back() { uni.navigateBack() }, saveContract() { const self = this; self.currentWebview.evalJS("uniEvent('saveContract')"); //app向html发送数据 }, openConfirmSigning() { let params = { form: { dianzi_hetong_id: this.dianzi_hetong_id, } } uni.showModal({ title: '开始签约', content: '发动签约后,合同内容不能再次批改,同时会耗费一份合同的使用量,是否开始签约?', complete: (res) => { if(res.confirm === true) { cluesHttp.startElectronContractSigning(params).then(res => { uni.showToast({ icon: 'none', title: '签约胜利' }) }) } } }) }, getMessage(e) { if(e.detail.data[0].msg === 'saveContract') { //保留合同 let params = { form: { title: this.contractDetails.title, id: this.dianzi_hetong_id, content: e.detail.data[0].content } } cluesHttp.saveElectronContractDetail(params).then(res => { uni.showToast({ icon: 'none', title: '保留胜利' }) }) } }, }, beforeDestroy() { uni.$off('to-parent') uni.offKeyboardHeightChange() }, }</script><style lang="scss" scoped> .initiateContract { .header { display: flex; align-items: center; justify-content: space-between; padding: 10px 20px 10px; .left { display: flex; align-items: center; justify-content: flex-start; } .title { text-align: center; } .right { height: 34px; opacity: 0; text-align: right; display: flex; align-items: center; justify-content: flex-end; } .item { // width: 30%; } } .headerTip { background-color: #ffedd1; z-index: 999; padding: 10px; font-size: 12px; .title { color: #f9ae3d; display: flex; justify-content: space-between; align-items: center; padding-bottom: 10px; border-bottom: 1px solid #ececec; } .info { word-break: break-all; } } .footer { position: fixed; bottom: 0px; left: 0px; right: 0px; z-index: 9999; padding: 10px 0 20px; background: #fff; border-top: 1px solid #f3f3f3; .box { display: flex; justify-content: space-around; align-items: center; .item { .btn { margin: 0 auto; } } } } }</style>
/hybrid/html/viewContract/index.html文件代码
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title>查看合同</title> <link rel="stylesheet" href="./css/index.css" /> <link rel="stylesheet" href="./css/wangeditor.css"> </head> <body> <div class="post-message-section"> <div class="container"> <!-- 工具栏 --> <div id="toolbar-container" class="toolbar" style="display: none;"></div> <!-- 编辑器 --> <div id="text-container" class="text"></div> </div> </div> <script src="../js/wangeditor.js"></script> <script type="text/javascript"> var userAgent = navigator.userAgent; if (/quickapp/i.test(userAgent)) { // quickapp document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>'); } if (!/toutiaomicroapp/i.test(userAgent)) { document.querySelector('.post-message-section').style.visibility = 'visible'; } </script> <!-- uni 的 SDK --> <script src="../js/uni-webview.js"></script> <!-- <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script> --> <script type="text/javascript"> console.log('接管css参数', decodeURIComponent(location.href.split('data=')[1])) let params = JSON.parse(decodeURIComponent(location.href.split('data=')[1])) let dianziHetong = null let html = '' // 创立富文本编辑器 const E = window.wangEditor const editor = new E('#toolbar-container', '#text-container') editor.create() window.getParams = (data) => { console.log("webview外部:", data) dianziHetong = data console.log(dianziHetong.flow_status == '1') let title = dianziHetong.title let contractHtml = dianziHetong.content let flow_status_name = dianziHetong.flow_status_name let flow_status = dianziHetong.flow_status if (flow_status === '1') { document.getElementById('text-container').style.height = '100vh' } else { editor.disable() } editor.txt.html(contractHtml) } document.addEventListener('UniAppJSBridgeReady', function() { // webview加载实现,显示页面 document.getElementsByClassName('post-message-section')[0].style.display = 'block' // app被动与html通信,用于增加图片到canvas中 function addUniEvenPassthrough() { window.uniEvent = function(info) { console.log('app传来的数据', info) switch (info) { case 'saveContract': uni.postMessage({ data: { msg: 'saveContract', content: editor.txt.html() } }); break; } } } addUniEvenPassthrough() }) </script> </body></html>
创立富文本编辑器用法:
<!-- 工具栏 --><div id="toolbar-container" class="toolbar" style="display: none;"></div><!-- 编辑器 --><div id="text-container" class="text"></div><script> // 创立富文本编辑器 const E = window.wangEditor const editor = new E('#toolbar-container', '#text-container') //如果不想显示工具栏,能够将款式设置为display: none; editor.create() //创立 editor.disable() //禁止编辑 editor.txt.html() //获取文本内容</script>