您好,登录后才能下订单哦!
最近在学习基于electron + electron-vue开发聊天客户端项目时,需要用到编辑器插入表情功能。一般通过input或textarea也能实现,通过插入[笑脸]、(:12 这些标签,展示的时候解析标签就行。
如下图效果:
在网上找到的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属性实现富文本功能
实现方式:
单独声明一个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
https://cn.vuejs.org/v2/guide/components-custom-events.html#自定义组件的-v-model
2、vue中div可编辑光标处插入内容
https://www.jb51.net/article/177989.htm
https://www.jb51.net/article/146257.htm


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截图功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对亿速云网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。