123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- <template>
- <div>
- <div class="edit-box div_MAX_Height" ref="myEditBox" contenteditable="true" :placeholder="placeholder" v-html="content" :key="keys" :id="keys"
- @blur="saveValue($event)" @click="getFocus($event)" v-on:paste="handlePaste($event)">
- </div>
- </div>
- </template>
- <script>
- export default {
- components: {},
- props:{
- value:{
- type:String,
- default:(value)=>{
- return ""
- }
- },
- placeholder:{
- type:String,
- default:()=>{
- return "请输入"
- }
- },
- keys:{
- type:String,
- default:()=>{
- const len = 6
- const codeList = []
- const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
- const charsLen = chars.length
- for (let i = 0; i < len; i++) {
- codeList.push(chars.charAt(Math.floor(Math.random() * charsLen)))
- }
- return codeList.join('')
- }
- }
- },
- data() {
- return {
- content: this.value||"", // 内容
- };
- },
- watch: {
- value(val){
- this.content = val
- },
- },
- computed: {},
- created() {},
- mounted() {},
- methods: {
- //粘贴
- async handlePaste(e){
- var event = e || window.event
- event.preventDefault();
- const items = (event.clipboardData || window.clipboardData).items;
- let file = null;
- if (!items || items.length === 0) {
- this.$message.error("当前浏览器不支持本地");
- return;
- }
- for (let i = 0; i < items.length; i++) {
- if (items[i].type.indexOf("text") !== -1) {
- var text = (event.originalEvent || event).clipboardData.getData('text/plain') ||'';
- text = text.replace(/\n{1,}/g,'</br>')
- var text2 = `<span>${text}</span>`
- this.setCursor(event,text2,1)
- break;
- }
- // if(items[i].type.indexOf("text/html") !== -1){
- // var string = (event.originalEvent || event).clipboardData.getData('text/html')
- // const srcRegex = /<img\s+(?:[^>]*?\s+)?src\s*=\s*(["'])((?:[^\1"]|\\\1|.)*?)\1/g
- // const result = [...string.matchAll(srcRegex)]
- // var src = result.map(v => v[2])[0]
- // console.log(src)
- // var reader = new FileReader()
- // var srcBase64 = reader.readAsDataURL(src)
- // // var srcBase64 =await this.urlToBase64(src)
- // console.log(srcBase64)
- // continue;
- // }
- if (items[i].type.indexOf("image") !== -1) {
- var e = event || window.event
- e.preventDefault();
- file = items[i].getAsFile();
- break;
- }
- }
- if (!file) {
- return;
- }
- var str = await this.fileToBase64(file)
- var randNum=Math.floor(Math.random()*(9999-1000))+1000;;
- var new_img = '<img key="'+ randNum +'" src="' + str + '" style="width:80px;height: 80px;border: 1px solid #f9f6f675;vertical-align:middle">';
- // 创建新的光标对象
- // var range = document.createRange();
- // // 将光标对象的范围界定为新建的表情节点
- // range.selectNodeContents(new_img);
- // // 定位光标位置在表情节点的最大长度位置
- // range.setStart(new_img, new_img.length);
- // // 将选区折叠为一个光标
- // range.collapse(true);
- // // 清除所有光标对象
- // selection.removeAllRanges();
- // // 添加新的光标对象
- // selection.addRange(range);
- // console.log(event.target.innerHTML)
- var index = window.getSelection().getRangeAt(0)
- this.setCursor(event,new_img,2)
- // var indexText = this.getColumn(event.target,window.getSelection())
- // var index2 = 0
- // var str2 = content.slice(0, indexText) + new_img + content.slice(indexText);
- // event.target.innerHTML = str2
- // this.$nextTick(()=>{
- // var selectedText = window.getSelection();
- // var selectedRange = document.createRange();
- // try{
- // for(var i=0;i<event.target.childNodes.length;i++){
- // if(event.target.childNodes[i].outerHTML == new_img){
- // index2 = i
- // throw new Error()
- // }
- // }
- // }catch{
- // }
- // selectedRange.setStart(event.target,index2+1);
- // selectedRange.collapse(true);
- // selectedText.removeAllRanges();
- // selectedText.addRange(selectedRange);
- // event.target.parentNode.focus();
- // })
-
- // this.saveValue(event)
- // var selection = window.getSelection()
- // window.getSelection().addRange(this.index)
- // console.log(window.getSelection().getRangeAt(0))
-
- },
- /**
- * 根据图片的url转换对应的base64值
- * @param { String } imageUrl 如:http://xxxx/xxx.png
- * @returns base64取值
- */
- async urlToBase64(imageUrl) {
- return new Promise((resolve, reject) => {
- let canvas = document.createElement('canvas')
- const ctx = canvas.getContext('2d')
- let img = new Image()
- img.crossOrigin = 'Anonymous' // 解决Canvas.toDataURL 图片跨域问题
- img.src = imageUrl
- img.onload = function() {
- canvas.height = img.height
- canvas.width = img.width
- ctx.fillStyle = '#fff' // canvas背景填充颜色默认为黑色
- // ctx.fillRect(0,0,img.width,img.height)
- ctx.drawImage(img, 0, 0,img.width,img.height) // 参数可自定义
- const dataURL = canvas.toDataURL('image/jpeg', 1) // 获取Base64编码
- resolve(dataURL)
- canvas = null // 清除canvas元素
- img = null // 清除img元素
- }
- img.onerror = function() {
- reject(new Error('Could not load image at ' + imageUrl))
- }
- })
- },
- //设置光标位置
- setCursor(event,str,type){
- console.log(event)
- var content = event.target.innerHTML
- // previousSibling
- var indexText = this.getColumn(event.target,window.getSelection())
- var index2 = 0
- var childNodes = event.target.childNodes
- if(!content){
- if(event.target.nodeName == 'BR'){
- const span = document.createElement('span');
- span.innerHTML = str;
- event.target.parentNode.insertBefore(span,event.target)
- var selectedRange = document.createRange();
- selectedRange.setStart(event.target,index2);
- return false
- }else{
- event.target.innerHTML = str
- }
- }else{
- content = content.replace(/ /g,'\r')
- var str2 = content.slice(0, indexText) + str + content.slice(indexText);
- event.target.innerHTML = str2.replace(/\r/g,' ')
- }
-
- // console.log(event.currentTarget.childNodes)
- // if(event.target.nodeName == 'BR'){
- // event.target.nodeName = 'SPAN'
- // event.target.innerHTML = '</br>' + str2
- // }
- this.$nextTick(()=>{
- var selectedText = window.getSelection();
- var selectedRange = document.createRange();
- try{
- for(var i=0;i<childNodes.length;i++){
- var html = childNodes[i].outerHTML
- if(type == 1){
- if(html){
- html = html.replace(/\r{1,}|\n{1,}|\r\n{1,}/g,'')
- str = html.replace(/\r{1,}|\n{1,}|\r\n{1,}/g,'')
- }
- }
- if(html == str){
- index2 = i
- throw new Error()
- }
-
- }
- }catch{
- }
- selectedRange.setStart(event.target,index2+1);
- selectedRange.collapse(true);
- selectedText.removeAllRanges();
- selectedText.addRange(selectedRange);
- event.target.parentNode.focus();
- })
- },
- getColumn(node, selectObj) {
- var baseNode = node;
- var anchorNodePosition = this.getPosition(baseNode, selectObj.anchorNode, selectObj.anchorOffset);
- var focusNodePosition = this.getPosition(baseNode, selectObj.focusNode, selectObj.focusOffset);
- var num = Math.min(anchorNodePosition, focusNodePosition)
- return num;
- },
- getNodes(baseNode, path) {
- // 拿到所有类型的节点
- var temPath = path;
- if (baseNode != null) {
- temPath.push(baseNode);
- if (baseNode.childNodes.length > 0) {
- for (let i = 0; i < baseNode.childNodes.length; i++) {
- this.getNodes(baseNode.childNodes[i], temPath);
- }
- }
- }
- },
- getPosition(baseNode, node, offset) {
- //根据节点获取给定node中offset位置在栏位中的实际位置
- let path = [];
- this.getNodes(baseNode, path);
- var retIdx = 0;
- for (let i = 0; i < path.length; i++) {
- if (path[i] == node) {
- retIdx += offset;
- return retIdx;
- } else {
- if (path[i].nodeType == 3) {
- retIdx += path[i].nodeValue.length;
- }else if(i!=0 && path[i].nodeType == 1){
- retIdx += path[i].outerHTML.length;
- }
- }
- }
- return retIdx
- },
- // 将file文件上传转化为base64进行显示
- fileToBase64(file) {
- return new Promise((resolve, reject) => {
- const reader = new FileReader()
- //开始读文件
- reader.readAsDataURL(file)
- reader.onload = () => resolve(reader.result)
- // 失败返回失败的信息
- reader.onerror = error => reject(error)
- })
- },
- getFocus(event){
- event.target.parentNode.focus();
- },
- saveValue(event){
- var a = event.target.innerHTML
- this.$emit('input',a)
- }
- },
- };
- </script>
- <style lang="scss" scoped>
- .edit-box{
- overflow-x: hidden;
- text-overflow: ellipsis;
- padding: 10px 15px;
- // min-height:27px;
- line-height: 1.5;
- outline: #dcdfe6;
- border:1px solid #DCDFE6;
- border-radius:5px;
- div{
- height:30px !important;
- line-height: 30px !important;
- }
- }
- .edit-box:empty::before {
- content: attr(placeholder);
- // margin-left:15px;
- font-style: normal;
- white-space: nowrap;
- color: #cacdd4;
- }
- // .edit-box:focus::before {
- // content:none;
- // }
- </style>
|