In the small program, we often have the keyboard up the operation scenario, but in different scenarios the solution is not the same, or need to be specific to the problem.

Demand analysis

Recently, there was a requirement in the project that when you click the comment button from the list page to enter the details page, after loading the page, the keyboard automatically turns up to enter the comment state. From a requirement point of view, we should call the keyboard in onReady, because onReady is called when the page is first rendered. In practice, however, we have found that some poorly configured phones will load the page slowly, and the page will not be fully rendered when onReady is called, causing placeholder and input components to be mispositioned. The essence of this is that the onReady lifecycle function does not assume that the page has been rendered when called. (Although the documentation describes it as done.)

The previous action was to call up the keyboard in the onReady lifecycle function.

this.setData({ focus: true })
Copy the code

The problem was discovered and delayed

setTimeout((a)= > {
  this.setData({ focus: true})},300)
Copy the code

But this is a palliative, and a good phone user will wait 300 milliseconds unnecessarily, while a bad phone user will wait 300 milliseconds without solving the problem.

solution

So since the applet doesn’t provide us with an ideal post-render callback, let’s think of a different approach: use short polling and call up the keyboard when the page is rendered.

Since we’re going to use short polling, what are we going to poll for? What signals that the page has been rendered? In this case, I’m using the wx.createsElectorQuery () method, which returns an instance of a SelectorQuery object, calls the Select method on that instance to select the node I want to poll, and checks whether the argument is null in the callback function. If monitored node information is returned, rendering is complete. At this point you can carry out keyboard up operation.

let timer = setInterval((a)= > {
  wx.createSelectorQuery().select('#comment-section').boundingClientRect(rect= > {
    if(rect ! = =null&& timer ! = =null) {
      clearInterval(timer)
      timer = null
      this.setData({ focus: true })
    }
  }).exec()
}, 50)
Copy the code

On top of that, it would be unwise to simply force focus to be true.

The default page is pushed when the keyboard is up, which is not a good experience if there are very few comments. So we need to determine a height, above this value, push up, not push up. This value depends on the actual situation. The push action is determined by the adjust-position property of the Input component, pushing if it is true and not otherwise. This is where the node information in the parameters returned by the callback comes in handy.

// Use this.setdata ({focus: true}) to determine the node height
if (rect.height < 500) this.setData({ push: false })
else this.setData({ push: true })
Copy the code

The onBlur function is faulty

In the actual operation, we found that after the keyboard is adjusted, there will be a summary and automatically retracted. After investigation, the problem of onBlur function was found. In onBlur function, we manually set focus to false, but this step was not necessary, and caused side effects. After we removed this part of the code, the issue of the keyboard automatically folding was resolved.

encapsulated

Although we fulfilled the requirements of this mission, it is clear that such missions will occur again in the future. So we’d be wise to wrap the whole process up for next call.

So here’s the way we use it:

const Util = require("xxx") // Introduce encapsulated libraries

/** * lifecycle function - listen for the page to complete the first rendering */
onReady: function () {
  Util.onTotalReady('#comment-section'.50, rect => {
    if (rect.bottom < 500) this.setData({ push: false })
    else this.setData({ push: true }}
    this.setData({ focus: true})})}Copy the code

summary

In the process of solving the keyboard tuning, we can see the simple development process of wechat small program. The emergence of this problem is essentially the inaccuracy of the life cycle function provided by small program to us. Otherwise, how can I not get node information when the page is rendered? The react componentWillMount lifecycle functions don’t have this problem, so hopefully the applets will be a little more powerful and we’ll write a little less hack code.