收藏
回答

关于PC端小程序中的键盘事件,如何有效的注册和撤销?

诸位在涉及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 );

完美,收工,感谢诸位围观~~


最后一次编辑于  10-23
回答关注问题邀请回答
收藏

2 个回答

  • 江南懒人
    江南懒人
    10-23

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

    10-23
    有用
    回复
  • 智能回答 智能回答 本次回答由AI生成
    10-23
    有用
登录 后发表内容