electron+vue实现div contenteditable截图功能


Posted in Javascript onJanuary 07, 2020

最近在学习基于electron + electron-vue开发聊天客户端项目时,需要用到编辑器插入表情功能。一般通过input或textarea也能实现,通过插入[笑脸]、(:12 这些标签,展示的时候解析标签就行。

如下图效果:

electron+vue实现div contenteditable截图功能 

在网上找到的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://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截图功能 

实现方式:

单独声明一个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

electron+vue实现div contenteditable截图功能

electron+vue实现div contenteditable截图功能

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截图功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
ECMAScript 基础知识
Jun 29 Javascript
获取网站跟路径的javascript代码(站点及虚拟目录)
Oct 20 Javascript
IE JS无提示关闭窗口不提示的方法
Apr 29 Javascript
JQuery获取文本框中字符长度的代码
Sep 29 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
Dec 26 Javascript
JQuery简单实现锚点链接的平滑滚动
May 03 Javascript
原生js与jQuery实现简单的tab切换特效对比
Jul 30 Javascript
五种js判断是否为整数类型方式
Dec 03 Javascript
JavaScript模块化之使用requireJS按需加载
Apr 12 Javascript
使用mint-ui实现省市区三级联动效果的示例代码
Feb 09 Javascript
vue插件实现v-model功能
Sep 10 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
Dec 05 Javascript
解决vue elementUI中table里数字、字母、中文混合排序问题
Jan 07 #Javascript
Vue程序化的事件监听器(实例方案详解)
Jan 07 #Javascript
微信小程序服务器日期格式化问题
Jan 07 #Javascript
webpack 最佳配置指北(推荐)
Jan 07 #Javascript
微信小程序接入腾讯云验证码的方法步骤
Jan 07 #Javascript
vue实现数据控制视图的原理解析
Jan 07 #Javascript
微信小程序wx.navigateTo方法里的events参数使用详情及场景
Jan 07 #Javascript
You might like
通过dbi使用perl连接mysql数据库的方法
2014/04/16 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
php实现RSA加密类实例
2015/03/26 PHP
作为程序员必知的16个最佳PHP库
2015/12/09 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
php+js实现裁剪任意形状图片
2018/10/31 PHP
JS中处理与当前时间间隔的函数代码
2012/05/23 Javascript
javascript与jquery中跳出循环的区别总结
2013/11/04 Javascript
为Javascript中的String对象添加去除左右空格的方法(示例代码)
2013/11/30 Javascript
jQuery实现tab标签自动切换的方法
2015/02/28 Javascript
浅谈AngularJs指令之scope属性详解
2016/10/24 Javascript
Javascript使用function创建类的两种方法(推荐)
2016/11/19 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
JavaScript对象的特性与实践应用深入详解
2018/12/30 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
利用 JavaScript 实现并发控制的示例代码
2020/12/31 Javascript
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
2018/06/11 Python
django Serializer序列化使用方法详解
2018/10/16 Python
利用Python模拟登录pastebin.com的实现方法
2019/07/12 Python
使用python实现对元素的长截图功能
2019/11/14 Python
使用pyqt5 tablewidget 单元格设置正则表达式
2019/12/13 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
2020/02/26 Python
Python实现微信表情包炸群功能
2021/01/28 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
css3实现3D色子翻转特效
2014/12/23 HTML / CSS
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
施工工地安全标语
2014/06/07 职场文书
2014年中秋节活动总结
2014/08/29 职场文书
九一八事变纪念日演讲稿
2014/09/14 职场文书
城管执法人员个人对照检查材料思想汇报
2014/09/29 职场文书
大学生党员批评与自我批评范文
2014/10/14 职场文书
小学优秀教师事迹材料
2014/12/16 职场文书
交通安全月活动总结
2015/05/08 职场文书
妈妈别哭观后感
2015/06/08 职场文书
2016党校培训心得体会
2016/01/07 职场文书