Quill的text-change回调内调用getSelection报undefined错误
问题原因
这个错误是JavaScript普通函数的this动态绑定特性导致的:
- 事件绑定时传入的是普通
function声明的回调,这类函数的this指向在函数执行时才确定,不会继承定义位置外层的上下文。 - Quill触发
text-change事件执行回调时,会将回调内部的this绑定到Quill实例本身,和你外层持有editor属性的业务上下文(比如Vue/React组件实例、自定义类实例)不是同一个对象。此时回调内访问this.editor会得到undefined,调用getSelection方法就会抛出Cannot read properties of undefined (reading 'getSelection')错误。 - 其他位置能正常调用
this.editor,是因为对应位置的代码this指向正确的业务实例,不存在上下文丢失问题。
修复方案
根据使用场景选任意一种即可:
- 方案1:使用箭头函数(最推荐)
箭头函数的this是词法绑定,会直接继承外层代码的上下文,不会出现指向偏移:this.editor.on('text-change', (delta, oldDelta, source) => { // ... 原有业务逻辑 if(/* 你的判断条件 */) { const range = this.editor.getSelection() } }) - 方案2:直接使用Quill回调默认绑定的
this
Quill已经把回调内的this指向了编辑器实例,不需要再通过this.editor访问实例,直接调用实例方法即可:this.editor.on('text-change', function (delta, oldDelta, source) { // ... 原有业务逻辑 if(/* 你的判断条件 */) { // 此处this本身就是Quill编辑器实例 const range = this.getSelection() } }) - 方案3:显式固定外层上下文引用
如果需要同时使用外层业务上下文和Quill实例,可以提前缓存外层this引用,或者用bind显式绑定上下文:// 缓存外层this const that = this this.editor.on('text-change', function (delta, oldDelta, source) { // ... 原有业务逻辑 if(/* 你的判断条件 */) { // that指向外层业务实例,函数内this指向Quill实例 const range = that.editor.getSelection() } })
注意:如果后续需要通过
off方法移除该事件监听,使用箭头函数、bind生成的回调需要提前存为独立变量,否则无法匹配原回调导致监听移除失败。
内容的提问来源于stack exchange,提问作者Freisent Klod
相关产品推荐
相关产品推荐

