诸位在涉及PC端小程序中键盘事件时,是否遇到过这样的问题。【需求场景】:需要在某个组件中实现“通过键盘方向键移动容器(box)的位置”。
【实现方案一】最初的实现方式如下:
a. 在组件的初始化事件中,进行键盘事件注册:wx.onKeyDown( this.handleKeyDown );
b. 在组件的销毁事件中,清除键盘事件注册:wx.offKeyDown( this.handleKeyDown );
这样实现遇到的问题是:
handleKeyDown 函数体中,对象this的指向是不正确的,也就是说,无法在handleKeyDown中有效的访问“当前组件”的上下文。
【实现方案二】
既然方案一中的this执行不正确,那是不是在注册事件时,用bind函数绑定一下this就可以了呢?于是,实现方式调整为:
a. 在组件的初始化事件中,进行键盘事件注册:wx.onKeyDown( this.handleKeyDown.bind( this ) );
b. 在组件的销毁事件中,清除键盘事件注册:wx.offKeyDown( this.handleKeyDown.bind( this ) );
这样实现之后,能够正确响应键盘事件了,但是,发现没有按照预期有效地清除鼠标事件。也就是说,页面已经切换,组件已经销毁,但是,对应的键盘事件监听器并没有被清除,导致的后果是:当组件再次初始化时,按下键盘按键,this.handleKeyDown会被执行多次(因为没有有效销毁,而进行了多次有效注册)。
后来仔细查看官方文档,发现给出的示例如下:
const listener = function (res) { console.log(res) }
wx.onKeyDown(listener)
wx.offKeyDown(listener) // 需传入与监听时同一个的函数对象
关键问题在于:用bind函数实现this对象的绑定,本质上是“生成了一个全新的函数对象”,所以wx.offKeyDown和wx.onKeyDown绑定的 listener 显然是不相同的。
在这里求助诸路大神,帮忙指点指点,感谢~
【问题解决】
经过分析和测试,已经解决这个问题,思路如下:将bind函数返回的“新函数”保存起来,然后用这个保存起来的函数作为 wx.onKeyDown
和 wx.offKeyDown的参数,完整的示例代码如下。
a. 在组件的初始化事件中,创建一个binded对象,内容为:this.bindedHandleKeyDown = this.handleKeyDown.bind( this ) ;
b. 在组件的初始化事件中,用第一步创建的binded对象,进行键盘事件注册:wx.onKeyDown( this.bindedHandleKeyDown );
c. 在组件的销毁事件中,用第一步创建的binded对象,清除键盘事件注册:wx.offKeyDown( this.bindedHandleKeyDown );
完美,收工,感谢诸位围观~~

类成员变量 如何定义?如何在 this.listener 中实现“当前实例的上下文(this对象)信息的访问”?请给出示例,感谢