近期在学习培训根据electron electron-vue开发闲聊手机客户端新项目时,必须采用在线编辑器插入小表情作用。一般通过input或textarea也可以完成,根据插入[笑容]、(:12 这种标签,展现的情况下分析标签就可以了。

如下图实际效果:

electron+vue实现div contenteditable截图功能 contenteditable div vue JavaScript  第1张  

在网络上寻找的jq插件完成在textarea鼠标光标处插入表情符标签

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title></title>
 <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
 </head>
 <body>
 <div class="container">
 <div class="row">
 <div class="col col-sm-12">
  <button class="btn btn-success" data-emoj="[笑容]">[笑容]</button>
  <button class="btn btn-success" data-emoj="[拼搏]">[拼搏]</button>
  <button class="btn btn-success" data-emoj="[:17]">[:17]</button>
 </div>
 <div class="col col-sm-12">
  <textarea class="form-control" id="content" rows="10"></textarea>
 </div>
 </div>
 </div>
 <script src="https:https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
 <script>
 (function ($) {
 $.fn.extend({
  insertEmojAtCaret: function (myValue) {
  var $t = $(this)[0];
  if (document.selection) {
  this.focus();
  sel = document.selection.createRange();
  sel.text = myValue;
  this.focus();
  } else if ($t.selectionStart || $t.selectionStart == '0') {
  var startPos = $t.selectionStart;
  var endPos = $t.selectionEnd;
  var scrollTop = $t.scrollTop;
  $t.value = $t.value.substring(0, startPos)   myValue   $t.value.substring(endPos, $t.value.length);
  this.focus();
  $t.selectionStart = startPos   myValue.length;
  $t.selectionEnd = startPos   myValue.length;
  $t.scrollTop = scrollTop;
  } else {
  this.value  = myValue;
  this.focus();
  }
  }
 });
 })(jQuery);
 $("button").on("click", function() {
 $("#content").insertEmojAtCaret($(this).attr("data-emoj"));
 });
 </script>
 </body>
</html>

但是这类方式 并并不是我要的相近微信编辑框插入小表情实际效果。

如果是就想起了div仿真模拟 设定 contenteditable="true" 完成富文本编辑实际效果,这类方式 是能够 完成,但是在vue中不可以关联v-model,最终参照一些技术性贴完成了这一作用,一顿操作出来采坑许多 ,因此就做一些共享纪录吧。

vue中根据给div加上contenteditable=true特性完成富文本作用

electron+vue实现div contenteditable截图功能 contenteditable div vue JavaScript  第2张  

完成方法

独立申明一个vue组件,chatInput.vue,根据监视数据信息转变并回到父部件。

1、父部件加上v-model

<template>
 ...
 <chatInput ref="chatInput" v-model="editorText" @focusFn="handleEditorFocus" @blurFn="handleEditorBlur" />
</template>
import chatInput from './chatInput'
export default {
 data () {
 return {
 editorText: '',
 ...
 }
 },
 components: {
 chatInput,
 },
 ...
}

2、v-model中传到的值在子部件prop中获得

export default {
 props: {
 value: { type: String, default: '' }
 },
 data () {
 return {
 editorText: this.value,
 ...
 }
 },
 watch: {
 value() {
 ...
 }
 },
}

3、根据监视获得到的prop值,并将该值取值给子部件中的v-HTML主要参数,双重关联就ok了。

chatInput.vue组件

<!-- vue完成contenteditable作用 -->

<template>
 <div 
 ref="editor"
 class="editor"
 contenteditable="true"
 v-html="editorText"
 @input="handleInput"
 @focus="handleFocus"
 @blur="handleBlur">
 </div>
</template>

<script>
 export default {
 props: {
 value: { type: String, default: '' }
 },
 data () {
 return {
 editorText: this.value,
 isChange: true,
 }
 },
 watch: {
 value() {
 if(this.isChange) {
  this.editorText = this.value
 }
 }
 },
 methods: {
 handleInput() {
 this.$emit('input', this.$el.innerHTML)
 },
 // 清除在线编辑器
 handleClear() {
 this.$refs.editor.innerHTML = ''
 this.$refs.editor.focus()
 },
 // 获得聚焦点
 handleFocus() {
 this.isChange = false
 this.$emit('focusFn')
 },
 // 失去焦点
 handleBlur() {
 this.isChange = true
 this.$emit('blurFn')
 },

 /**
 * 鼠标光标处插入內容
 * @param html 必须插入的內容
 */
 insertHtmlAtCaret(html) {
 let sel, range;
 if(!this.$refs.editor.childNodes.length) {
  this.$refs.editor.focus()
 }
 if (window.getSelection) {
  // IE9 and non-IE
  sel = window.getSelection();

  if (sel.getRangeAt && sel.rangeCount) {
  range = sel.getRangeAt(0);
  range.deleteContents();
  let el = document.createElement("div");
  el.appendChild(html)
  var frag = document.createDocumentFragment(), node, lastNode;
  while ((node = el.firstChild)) {
  lastNode = frag.appendChild(node);
  }
  range.insertNode(frag);
  if (lastNode) {
  range = range.cloneRange();
  range.setStartAfter(lastNode);
  range.collapse(true);
  sel.removeAllRanges();
  sel.addRange(range);
  }
  }
 } else if (document.selection && document.selection.type != "Control") {
  // IE < 9
  document.selection.createRange().pasteHTML(html);
 }
 this.handleInput()
 }
 }
 }
</script>

<style>

</style>

部件作用早已亲自测试,立即一次性取走应用。

下列是一些参照:
1、vue官方网描叙, 自定部件的v-model:

一个部件上的 v-model 默认设置会运用名叫 value 的 prop 和名叫 input 的恶性事件,v-model的值可能传到子部件中的prop

/zb_users/upload/20/09/27/components-custom-events.html#自定部件的-v-model
2、vue中div可编写鼠标光标处插入內容

/zb_users/upload/20/09/27/177989.htm

/zb_users/upload/20/09/27/146257.htm

electron+vue实现div contenteditable截图功能 contenteditable div vue JavaScript  第3张

electron+vue实现div contenteditable截图功能 contenteditable div vue JavaScript  第4张

electron vue中完成截屏作用

关键应用的是微信截图dll,根据node实行就可以

screenShot() {
 return new Promise((resolve) => {
 const { execFile } = require('child_process')
 var screenWin = execFile('./static/PrintScr.exe')
 screenWin.on('exit', function(code) {
 let pngs = require('electron').clipboard.readImage().toPNG()
 let imgData = new Buffer.from(pngs, 'base64')
 let imgs = 'data:image/png;base64,'   btoa(new Uint8Array(imgData).reduce((data, byte) => data   String.fromCharCode(byte), ''))
 resolve(imgs)
 })
 })
},

小结

之上上述是我给大伙儿详细介绍的electron vue完成div contenteditable截屏作用,期待对大伙儿有一定的协助,假如大伙儿有一切有意者帮我留言板留言,我会立即回应大伙儿的。在这里也特别感谢大伙儿对网址的适用!
如果你觉得文中对给你协助,热烈欢迎转截,劳烦标明出處,感谢!