1. 程式人生 > 其它 >編輯器基礎contenteditable

編輯器基礎contenteditable

<template>
  <div class="edit-container">
    <div id="myEditor" ref="myEditor" contenteditable="true" @blur="getBlur()" @keyup="statisticsNum()" />
    <div class="flex-between-center bottom-btn">
      <div class="flex-start-center">
        <div class="button" @click="openEmoji">插入表情</div>
        <div class="button" @click="addLink">插入超連結</div>
        <div class="button" @click="addMiniprogramLink">插入小程式</div>
      </div>
      <div class="statistics">已輸入{{ total }}字</div>
    </div>
    <div v-if
="isOpenEmoji" class="emoji-content"> <div v-for="(item, index) in emojiList" :key="index" class="emoji-item" @click="addEmoji(index)">{{ item }}</div> </div> </div> </template> <script> import emojiData from './emoji.json'; let sel; let range; export default
{ data() { return { total: 0, emojiList: [], isOpenEmoji: false }; }, methods: { // 字數統計 statisticsNum() { const limitText = this.$refs.myEditor.innerHTML; const limitLen = limitText.length; if (limitText === '') { this.$refs.myEditor.blur(); }
else { // this.setFocus($('#myEditor')); } this.total = limitLen; }, // 獲取全部表情 getEmoji() { for (const i in emojiData) { this.emojiList.push(emojiData[i].char); } }, openEmoji() { this.isOpenEmoji = !this.isOpenEmoji; }, // 新增表情 addEmoji(index) { for (const i in this.emojiList) { if (index === Number(i)) { const face = this.emojiList[index] + '&nbsp;'; this.insertHtml(face); } } }, // 插入超連結 addLink() { const link = `<a target='_blank' contenteditable='false' href='https://www.baidu.com/'>超連結(百度)</a>`; this.insertHtml(link); }, // 插入小程式 addMiniprogramLink() { const link = `<a target='_blank' contenteditable='false' href='https://www.baidu.com/' data-miniprogram-appid='111' data-miniprogram-path='https://www.baidu.com/'>虛擬小程式</a>`; this.insertHtml(link); }, // 作用:失去焦點時獲取游標的位置 getBlur() { sel = window.getSelection(); if (sel && sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); // range.deleteContents(); } }, // 作用:在contenteditable="true"文字框游標處插入內容 insertHtml(html) { // IE9 and non-IE if (window.getSelection) { if (sel && sel.getRangeAt && sel.rangeCount) { const el = document.createElement('div'); el.innerHTML = html; const frag = document.createDocumentFragment(); let 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.statisticsNum(); }, // 作用:設定游標始終在文字最後 // 情景:利用contenteditable=”true”模擬輸入框時,focus()方法會將游標定位在文字的首位,需要將游標挪到最後一位 // 注意:根據實際情況判斷是否需要這段程式碼 setFocus(el) { el = el[0]; // jquery 物件轉dom物件 el.focus(); range = document.createRange(); range.selectNodeContents(el); range.collapse(false); sel = window.getSelection(); // 判斷游標位置,如不需要可刪除 if (sel.anchorOffset !== 0) { return; } sel.removeAllRanges(); sel.addRange(range); } }, created() { this.getEmoji(); } }; </script> <style scoped> .flex-between-center { display: flex; justify-content: space-between; align-items: center; } .flex-start-center { display: flex; justify-content: start; align-items: center; } .edit-container { position: relative; width: 500px; height: 300px; background: #859ffc; border: 1px solid #EBEEF5; margin: 20px; font-size: 12px; } #myEditor { box-sizing: border-box; width: 460px; height: 230px; background: #fff; margin: 20px auto 0; padding: 10px; line-height: 18px; } .bottom-btn { box-sizing: border-box; width: 460px; height: 30px; background: #fff; margin: 0 auto; padding: 0 10px; border-top: 1px solid #EBEEF5; } .button { margin-right: 10px; color: #57e; cursor: pointer; } .statistics { color: #999; } .emoji-content { width: 220px; height: 280px; background: #fff; border: 1px solid #EBEEF5; border-radius: 4px; position: absolute; top: 0px; left: 502px; display: flex; flex-wrap: wrap; padding: 10px; overflow: auto; } .emoji-item { width: 14%; font-size: 18px; list-style: none; text-align: center; cursor: pointer; } </style>