1、编写公共js
判断是否需要替换图片
function replaceImage(originUrl) {
if (originUrl.indexOf('file://') > -1) {
return true; //本地文件替换
} else if (originUrl.indexOf('https://docimg2.docs.qq.com') > -1) {
return false; //来自腾讯文档不替换
}
};
//判断是mac还是window
function getPosType() {
var agent = navigator.userAgent.toLowerCase();
var isMac = /macintosh|mac os x/i.test(navigator.userAgent);
if (agent.indexOf('win32') >= 0 || agent.indexOf('wow32') >= 0) {
return 'win';
}
if (agent.indexOf('win64') >= 0 || agent.indexOf('wow64') >= 0) {
return 'win';
}
if (navigator.userAgent.indexOf('Intel Mac') > 0) {
return 'x64Mac'; //'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
} else {
return 'arm64Mac';
}
}
//base64图片转成文件流格式
function base64ToFile(data, fileName) {
const dataArr = data.split(',');
const byteString = atob(dataArr[1]);
const options = {
type: 'image/jpeg',
endings: 'native',
};
const u8Arr = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
u8Arr[i] = byteString.charCodeAt(i);
}
let formData = new FormData();
let fileOfBlob = new File([u8Arr], fileName ? fileName : new Date().getTime() + '.jpg', options); //返回文件流
formData.append('upload', fileOfBlob);
return formData;
}
//反斜杠转斜杠
function backslashToSlash(val) {
return val.replace(/\\/g, '/');
}
//协议是否注册。有注册就打开
customProtocolCheckFunc = (val) => {
//https://gitee.com/xoobom/wpspaster/releases
window.customProtocolCheck(val,(err) => {
window.open('/download-wpspaster.jsp', '_blank');
},
(res) => { },
500
);
};
//处理富文本粘贴word图片
function initEditor(editorId,callBack){
const socket = io("http://localhost:9001", {
transports: ['websocket'], //不加这个会跨域
autoConnect: true, //是否自动连接
reconnection: false, //关闭重连
});
let newImgUrlListAll = [];
socket.on("getImgByLocal", function (res1) {
// let url ='http://xoobom.com:8023/file/upload'
let url ='../common/kindeditor!jQueryFileUpload.action?dir=download-center'
axios.post(
url,
base64ToFile(res1.data.base64)).then(function (res2) {
let prefix = ['x64Mac', 'arm64Mac'].includes(getPosType()) ? 'file:/' : 'file:///';//kindeditor的话mac是file:/,win是file://
newImgUrlListAll.push({
originUrl: prefix + res1.data.filePath,//kindeditor是file://
url: '/'+res2.data[0].url,
});
})
});
socket.on('connect_error', (error) => {
customProtocolCheckFunc('wpspaster://');//协议是否注册。有注册就打开
});
// 'wordpaster', 'map', 'flash',
var editor = KindEditor.create(editorId, {
width: '100%',
height: '300px',
uploadJson: "../common/kindeditor!kindeditorUpload.action?",
allowFileManager: true,
formatUploadUrl: false,
newlineTag: 'p',
items: [
'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'cut', 'copy', 'paste',
'plainpaste', 'wordpaste','|', 'justifyleft', 'justifycenter', 'justifyright',
'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image',
'media', 'insertfile', 'table', 'hr', 'emoticons', 'code', 'pagebreak',
'link', 'unlink', '|', 'about'],
afterBlur:callBack,
filterMode: false,
pasteType: 2,
afterCreate: function () {
var self = this;
// 监听ctrl+v事件
self.edit.doc.body.addEventListener('keydown', function (e) {
if (e.keyCode == 86) {
setTimeout(()=>{
const htmlString = self.html();
const div = document.createElement('div');
div.innerHTML = htmlString;
let newImgUrlList = div.getElementsByTagName('img');
if (newImgUrlList.length > 0) {
for (let i = 0; i < newImgUrlList.length; ++i) {
if (replaceImage(newImgUrlList[i].src)) {
console.log('newImgUrlList')
let filePath = ['x64Mac', 'arm64Mac'].includes(getPosType()) ? newImgUrlList[i].src.slice(6) : newImgUrlList[i].src.slice(8);
socket.emit('getImgByLocal', {
'filePath': filePath,
});
}
}
}
}, 10);
}
});
// 监听浏览器鼠标右键粘贴事件
self.edit.doc.body.addEventListener('paste', function (e) {
setTimeout(()=>{
const htmlString = self.html();
const div = document.createElement('div');
div.innerHTML = htmlString;
let newImgUrlList = div.getElementsByTagName('img');
if (newImgUrlList.length > 0) {
for (let i = 0; i < newImgUrlList.length; ++i) {
if (replaceImage(newImgUrlList[i].src)) {
console.log('newImgUrlList')
let filePath = ['x64Mac', 'arm64Mac'].includes(getPosType()) ? newImgUrlList[i].src.slice(6) : newImgUrlList[i].src.slice(8);
socket.emit('getImgByLocal', {
'filePath': filePath,
});
}
}
}
}, 10);
});
}
});
//Object.create返回一个新对象,新对象的_proto_就是传进去的参数 js原生监听数组的方法
let newProtetype = Object.create(Array.prototype);
let methods = ["push", "pop", "shift", "unshift", "reserve", "sort", "splice"];
methods.forEach(function (method) {
//新原型上添加同名[method] ,返回原来的Array.prototype[method]
newProtetype[method] = function (...args){
let content = editor.html();
setTimeout( ()=> {
if (newImgUrlListAll.length > 0) {
if (replaceImage(newImgUrlListAll[0].originUrl)) {
content = content.replace(
/<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
function (mactch, capture) {
let current = '';
for (let i = 0; i < newImgUrlListAll.length; i++) {
let sourcePath = '';//粘贴原路径
if (getPosType() == 'win') {
sourcePath = backslashToSlash(capture.replace(/(&)/gi, '&'));
} else {
sourcePath = capture.replace(/(&)/gi, '&');
}
if (sourcePath == newImgUrlListAll[i].originUrl) {
current = newImgUrlListAll[i].url;
break;
}
}
current = current ? current : capture;
return mactch.replace(
/src=[\'\"]?([^\'\"]*)[\'\"]?/i,
'src=' + current,
);
});
editor.html(content);
}
} // 匹配并替换 img中src图片路径
},10);
return Array.prototype[method].call(this,...args);
}
})
//绑定新的原型
newImgUrlListAll.__proto__ = newProtetype;
}
//处理富文本粘贴word图片--end
2、页面中应用如下
//富文初始化
initEditor('#content', function() {
this.sync();
//手动重新验证
var bv = $("#addInfoForm").data('bootstrapValidator');
bv.revalidateField("jobInfo.content");
})
以下图片展示的是相关控件,该控件是收费的