Browse Source

fix: 支持输入法输入,修正光标只能跟随最后一个字符移动的问题,修正快速输入出现bug的现象

ChenYangfan 6 years ago
parent
commit
5a89488f5c

+ 1 - 1
src/App.vue

@@ -1,5 +1,5 @@
 <template>
-  <div id="app">
+  <div>
     <router-view />
   </div>
 </template>

+ 39 - 13
src/components/editor/EditableItem.vue

@@ -3,8 +3,10 @@
     ref="element"
     :is="item.type"
     :id="item.id"
-    @input="handleInput"
-    @keydown="handleKeyDown"
+    @compositionstart.stop="handleCompositionStart"
+    @compositionend.stop="handleCompositionEnd"
+    @input.stop="handleInput"
+    @keydown.stop="handleKeyDown"
     contenteditable
     v-html="item.content"
   >
@@ -19,17 +21,32 @@ export default {
   name: 'editable-item',
   props: ['item', 'pageId'],
   data: function() {
-    return {}
+    return {
+      isCompositionStarted: false,
+      range: null
+    }
   },
   computed: {
-    ...mapState({
-      range: state => state.editor.range
-    })
+    ...mapState({})
   },
   mounted() {},
-  updated() {},
+  updated() {
+    console.log('updated', this.range)
+  },
   methods: {
+    handleCompositionStart() {
+      this.isCompositionStarted = true
+    },
+    handleCompositionEnd(e) {
+      this.isCompositionStarted = false
+      this.handleInputValue(e)
+    },
     handleKeyDown(e) {
+      if (!this.range) {
+        this.range = window.getSelection().getRangeAt(0)
+      }
+      console.log('keydown', this.range)
+
       switch (e.key) {
         case 'Enter':
           e.preventDefault()
@@ -37,7 +54,7 @@ export default {
             pageId: this.pageId,
             itemId: this.item.id
           })
-          requestAnimationFrame(() => {
+          this.$nextTick(() => {
             const focusNode = document.getElementById(this.item.id).nextSibling
             focusNode.focus()
           })
@@ -49,6 +66,9 @@ export default {
       }
     },
     handleInput(e) {
+      !this.isCompositionStarted && this.handleInputValue(e)
+    },
+    handleInputValue(e) {
       const diff = { content: e.target.textContent }
       this.item.type === 'div' &&
         Object.entries(blockTypeRegs)
@@ -64,11 +84,17 @@ export default {
         itemId: this.item.id,
         diff
       })
-      requestAnimationFrame(() => {
-        const selection = window.getSelection()
-        selection.collapseToEnd()
-        selection.extend(selection.anchorNode, e.target.textContent.length)
-        selection.collapseToEnd()
+
+      this.$nextTick(() => {
+        console.log(this.range.startOffset)
+        this.range.setStart(
+          this.range.startContainer,
+          this.range.startOffset + 1
+        )
+
+        this.range.collapse()
+        window.getSelection().removeAllRanges()
+        window.getSelection().addRange(this.range)
       })
     }
   }

+ 4 - 3
src/components/editor/Editor.vue

@@ -1,9 +1,9 @@
 <template>
-  <section id="container">
+  <div id="container">
     <template v-for="page in pages">
       <editing-page-vue :key="page.id" :page="page"></editing-page-vue>
     </template>
-  </section>
+  </div>
 </template>
 
 <script>
@@ -15,6 +15,7 @@ export default {
     EditingPageVue
   },
   created() {},
+  mounted() {},
   computed: {
     ...mapState({
       pages: state => state.editor.pages
@@ -23,7 +24,7 @@ export default {
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
 #container {
   min-height: 100vh;
   padding: 10px;

+ 1 - 1
src/store/modules/editor.js

@@ -14,7 +14,7 @@ import uuid from 'uuid'
 export default {
   state: {
     pages: [],
-    range: {}
+    range: null
   },
 
   mutations: {