electron+vue div contenteditable 캡 처 기능 구현

8329 단어 vuedivcontenteditable
최근 에 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 캡 처 기능 을 실현 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!

좋은 웹페이지 즐겨찾기