绿满眶商城微信小程序-uniapp
zxl
2025-07-11 01439f14432ee731be561d193c88e3ea31399345
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<template>
    <text
        :eid="eid"
        :change:eid="quillEditor.watchEID"
        :mode="inputmode"
        :change:mode="quillEditor.watchInputMode"
        :focus="focusFlag"
        :change:focus="quillEditor.watchFocus"
        :backspace="backspaceFlag"
        :change:backspace="quillEditor.watchBackSpace"
    ></text>
</template>
 
<script>
/**
 * 富文本renderjs扩展
 * @author sonve
 * @version 1.0.0
 * @date 2024-12-04
 */
 
export default {
    props: {
        eid: {
            type: String,
            default: ''
        }
    },
    data() {
        return {
            inputmode: '', // none | remove
            focusFlag: 0, // 主动聚焦标志
            backspaceFlag: 0 // 主动删除标志
        }
    },
    methods: {
        changeInputMode(mode) {
            this.inputmode = mode
        },
        focus() {
            this.focusFlag++
        },
        backspace() {
            this.backspaceFlag++
        }
    }
}
</script>
 
<script module="quillEditor" lang="renderjs">
export default {
  data() {
    return {
      editorID: ''
        }
  },
  methods: {
    watchEID(newValue, oldValue, ownerInstance, instance) {
      if (newValue) {
        this.editorID = newValue
      }
    },
        watchInputMode(newValue, oldValue, ownerInstance, instance) {
      if (newValue) {
        this.changeQuillInputMode(newValue)
      }
    },
    watchFocus(newValue, oldValue, ownerInstance, instance) {
      if (newValue) {
        this.changeFocus(newValue)
      }
    },
    watchBackSpace(newValue, oldValue, ownerInstance, instance) {
      if (newValue) {
        this.changeBackSpace(newValue)
      }
    },
    /**
     * 通过增加或移出inputmode属性来控制是否允许键盘弹出
     * @param {String} type none | remove
     * @tutorial https://ask.dcloud.net.cn/article/39915
     */
    changeQuillInputMode(type) {
      try {
        // 要关闭软键盘的话,需要给inputmode属性设置none
        // 如果要打开软键盘的话,需要移出inputmode属性
        const el = document.querySelector(`#${this.editorID} .ql-editor`);
        if(!el) return console.warn('==== quill dom error ====');
        if(type == 'none') el.setAttribute('inputmode', 'none')
        if(type == 'remove') el.removeAttribute('inputmode')
      } catch (err) {
        console.warn('==== changeQuillInputMode catch error :', err);
      }
    },
    /**
     * 通过quill节点实例的focus方法来主动触发编辑器聚焦
     */
    changeFocus() {
      try {
        const el = document.querySelector(`#${this.editorID} .ql-editor`);
        if(!el) return console.warn('==== quill dom error ====');
        el.focus()
      } catch (err) {
        console.warn('==== changeFocus catch error :', err);
      }
    },
    /**
     * 通过quill节点实例的deleteText方法来主动触发编辑器删除
     */
    changeBackSpace() {
      try {
        const el = document.querySelector(`#${this.editorID}`);
        const quill = Quill.find(el);
        if(!el || !quill) return console.warn('==== quill dom error ====');
 
        const range = quill.getSelection(); // 获取当前光标位置
 
        if (range && range.length === 0) {
          // 如果没有选中文本且光标存在,则删除前一个字符或 emoji
          if (range.index > 0) {
            // 获取光标前的所有文本
            const text = quill.getText(0, range.index);
            // 规范化 Unicode 字符,确保正确处理组合字符和 emoji
            const normalizedText = text.normalize('NFC');
            // 将文本转换为字符数组,确保正确处理多字节字符
            const chars = Array.from(normalizedText);
            // 计算前一个字符的索引
            const lastCharIndex = chars.length - 1;
            if (lastCharIndex >= 0) {
              // 删除前一个字符(包括多字节字符)
              const lastChar = chars[lastCharIndex];
              const lastCharLength = text.slice(-lastChar.length).length;
              quill.deleteText(range.index - lastCharLength, lastCharLength);
              quill.setSelection(range.index - lastCharLength); // 更新光标位置
            }
          }
        } else if (range && range.length > 0) {
          // 如果有选中文本,则删除选中的文本
          quill.deleteText(range.index, range.length);
          quill.setSelection(range.index); // 更新光标位置
        }
 
      } catch (err) {
        console.warn('==== changeBackSpace catch error :', err);
      }
    },
 
  }
}
</script>