This is the second day of my participation in the August More text Challenge. For details, see: August More Text Challenge

A rose is a fragrance in the hand. Like it first, check it later.

The business requirements

Products need to do a buried point recently, both in preview goods and preview the enterprise information need statistics to stay for the length of the user, but it has a characteristic, is the commodity and enterprise information are written in the H5, eventually the H5 home page will be nested AnZhuoDuan small programs and their products and IOS side, because of the nested, The complexity of things to deal with, and the fact that it’s nested in three different host environments, is a headache, and there are some events that H5 can’t listen to.

A problem encountered

  • In my last article, I explained how to solve the problem of closing the browser to send statistics in H5 and testing to see if it was sent successfully; usenavigator.sendBeaconSending interface andwindow.addEventListener('unload', function(){}, false)To listen for browser closures,Click on me for more details
  • There are two difficult points to be explained here:
    • 1. In the nested H5 page of APP or small program, we cannot listen when the user switches the software to the background.
    • 2. When the user clicks the built-in back button at the upper left corner in the nested applet and IOS hosting environment, H5 cannot listen to the user exiting the current H5 page.

solution

  • Before solving the above difficulties, I want to talk about how to calculate the statistical time preview. If I am not wrong, it is estimated that many people will see the same requirements as ME at the beginning. What statistical preview time? Get a timer? Is that performance intensive? Does my code run and jump? A series of questions.
    • In fact, it is not that difficult to count the time, we only need to record once, when we enter the H5 page, we will new a timestamp(new Date).getTime()Save it to global, how do we need to call the interface statistics duration when we are in(new Date).getTime()You take a timestamp and you subtract the timestamp that you saved when you came in and you get onePreview timeThe subtraction here is milliseconds, you can convert it yourself.
  • Now that we’ve solved the time statistics problem, we’re going to solve today’s difficult problem.
    • To solve these two difficult problems, we mainly use a listening event in H5visibilitychange, this time can monitor whether the page is hidden, here we will introduce in detail:

visibilitychange

The VisibilityChange event is triggered on the document when the contents of its tabs become visible or hidden.

  • The MDN document has two points to note

When the value of the visibleStateState property is converted to hidden, Safari does not trigger VisibilityChange as expected; Therefore, in this case, you also need to include code to listen for pageHide events.

For compatibility reasons, be sure to use the document. The addEventListener instead of the window. The addEventListener to register the callback. Safari <14.0 supports only the former.

Important code

document.addEventListener("visibilitychange".function() {
  if (document.visibilityState === 'visible') {
      // The page is displayed
    // backgroundMusic.play();
  } else {
      // The page is hidden
    // backgroundMusic.pause();}});Copy the code

Logic thinking

  • Set a variable globally to record the initial time. When the page is hidden (e.g. switch background) and listens to document.visibilityState === ‘hidden’ under visibilityChange, we send the time statistics to the server. When document.visibilityState === ‘visible’, we start the new statistics time, so that we can accurately complete the required statistics time to the server.

  • At this time, a new problem began to appear, that is, after nested H5, in ios system, the visibilityChange event could not be triggered by directly clicking the back button in the upper right corner of the system, which made us very confused. Some people would suggest that it could be solved by listening to the event of closing the browser or closing the website. All I can say is that these are not monitored, most of the events you are thinking of will not trigger the H5 page so the quiet events are a little scary, this is only ios, Android phones and Hongmonphones do not have this situation.

    • To solve this situation, I thought for a long, long time and almost spun myself, and finally came up with this solution:
    H5 nested APP

    If the nested ios APP, when the user clicks the upper left corner of the back button, by the APP life cycle call H5 method, in H5 window mount a function written by yourself, when the call to the mounted function sent statistics upload to the server;

    H5 nested applets

    If it’s nested in H5 of the applet, we can’t do that anymore, because the applet can’t call anything on the page on H5 when the page is destroyed, so not only can the page is destroyed and you can’t call the H5 method but you can’t call any of the methods in H5 at any time, So here we need to use WeChat provides a method of wx. MiniProgram. PostMessage document details, how should we reasonable use this approach? My idea is that every time need to record this entry page using this method, the need to upload parameters and time records and assigned to wx. MiniProgram. PostMessage ({data: {}}), how to when the user clicks on a small program native returns, we can in native writing a method used to receive the parameters;

    < web - view bindmessage = "bindmessage" > < / web - view > / / js bindmessage () {} / / H5 page receive send back parameters wx. MiniProgram. PostMessage ({ data: 'foo' })Copy the code

We can get the parameters directly in the small program to complete sending statistics;

conclusion

In fact, it is not difficult to solve these problems, the difficulty is how to think outside the box, can not be fixed in H5 to listen to all events or complete all operations. To recap: The main code we used was

// On the H5 page, listen for events
document.addEventListener("visibilitychange".function() {
  if (document.visibilityState === 'visible') {
      // The page is displayed
    // backgroundMusic.play();
  } else {
      // The page is hidden
    // backgroundMusic.pause();}});// For the content that H5 page sends to the applet
wx.miniProgram.postMessage({ data: 'foo' });
// The method used for ios-app calls
window.logData = function() {};
Copy the code
// The applet native code binding listens for H5 return parameters<web-view bindmessage="bindmessage"></web-view>
Copy the code
bindmessage(){
// The H5 page receives the parameters sent back
}
Copy the code

With this code, we have what we want.

Creation is not easy, like remember to like, if there is a mistake, please leave a message in the comment area.