Front-end Development Start to Practice: Calculate the exposure time (residence time) of each module in a page

Products want to see the active pages put out. Users are more interested in what information is on their pages, and they are not interested in what information is on their pages at all. => Calculate the residence time of each module in the page

The first time I heard this demand, my brain started to run crazily, and then I thought of plan 1, plan 2, plan 3... there are many failed ideas I have forgotten, here is the third plan I finally adopted.

Solution 1: Page is divided into modules according to page dom

var bodyChildrenLists = $('body').children()
var bodyChildDomLsit = []
var initHeight = 0
for (var i = 0; i < bodyChildrenLists.length; i++) {
    if (bodyChildrenLists[i].tagName !== 'SCRIPT') {
        bodyChildDomLsit.push({
        className: bodyChildrenLists[i].className,
        height: bodyChildrenLists[i].offsetHeight
      })
    }
}

Existing problems:
Different people have different code styles, so this scheme is not suitable for this kind of code style.

<body>
    <div class="container">
        <div class="header"></div>
        <div class="nav"></div>
        <div class="footer"></div>
    </div>
</body>

It's a good way to do it, that is, if you have a consistent code style, it's better to use it.

Solution 2: Calculate all the actions of the user after opening the page

var scrollTop = 0
var time = Date.now()
window._stayStatus = {
// Record trajectory, down > 1 move downward and upward, sliderDis move distance, time-consuming move, initDis initial distance, initTime initial time
    moveData: [],
    enterTime: Date.now()
}
var moveData = window._stayStatus.moveData
var currentMoveIndex = 0
function move () {
    var currentTime = Date.now()
    var currentScrollTop = $(window).scrollTop()
    var dis = currentScrollTop - scrollTop
    var disTime = currentTime - time
    // The time difference between the last sliding page and this sliding page is more than 100 ms, depending on the user staying for a certain period of time.
    if (disTime > 100) {
        if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down === 0) {
            moveData[currentMoveIndex].time += disTime
        } else {
            moveData.push({
                down: 0,
                initTime: time, // initTime represents the initial time to enter this state
                initDis: currentScrollTop, //initDis denotes the initial position to enter this state
                sliderDis: dis, // The distance of sliding in this state
                time: disTime // Time spent in this state (ms)
            })
        }
    } else {
        // Slide down
        if (dis >= 0) {
            // If the previous sliding state is downward, only the sliding distance and the sliding time need to be accumulated on the original data.
            if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down > 0) {
                moveData[currentMoveIndex].sliderDis += dis
                moveData[currentMoveIndex].time += disTime
            } else {
                moveData.push({
                    down: 1,
                    initTime: currentTime,
                    initDis: currentScrollTop,
                    sliderDis: dis,
                    time: disTime
                })
            }
        } else {
            if (moveData[currentMoveIndex] && moveData[currentMoveIndex].down < 0) {
                moveData[currentMoveIndex].sliderDis += dis
                moveData[currentMoveIndex].time += disTime
            } else {
                moveData.push({
                    down: -1,
                    initTime: currentTime,
                    initDis: currentScrollTop,
                    sliderDis: dis,
                    time: disTime
                })
            }
        }
    }
    currentMoveIndex = moveData.length - 1
    time = currentTime
    scrollTop = currentScrollTop
  }
  window.onscroll = function (e) {
    move()
  }

The data obtained from the above methods are as follows:

Representation: After staying 2728 ms from the top 2 px, the user slides down 612 PX for 595 ms, then stays at 8649 ms from the top 612 px, and finally slides up 604 PX for 167 Ms.

Existing problems:
Although the final amount of data will not be very large, it is difficult to analyze such data to the data group. This is the way I think when I don't dock with the product. It's a bit complicated. But this way can simulate the user's behavior more vividly.

Scheme 3: Fixed module size, calculate the residence time of each module

Docking with my product is the basic requirement:

  • Every 1300px height is used as a module to carry out buried point statistics.
  • When the exposure range of each screen is greater than 400 px, the effective exposure will take a long time to start recording.
  • The reporting time of each module is the sum of sliding time and static residence time in the module.
  • Set the current module as module 0. When the user does not reach module 1, the repeated sliding time is recorded as the time within module 0.
  • Setting the current module as module 0, when the user arrives at module 1 and returns module 0 through sliding behavior, the module 0 data will be re-recorded once.
  • The last reporting time is when the user leaves the page (entering the next process page or closing the browser). The user leaving behavior and scenarios that can be monitored need to be counted.

According to the above requirements, I made a small demo, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="//lib04.xesimg.com/lib/jQuery/1.11.1/jquery.min.js"> </script>
  <script src="//zt.xueersi.com/apStatic/js/qz-rem.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .section {
      height: 1300px;
      border-bottom: 1px solid #f00;
      box-sizing: border-box;
      padding-top: 400px;
    }
  </style>
</head>
<body>
  <div id="app">
    <div>
      <p>Residence time 0:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 0">{{0}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 1:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 1">{{1}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 2:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 2">{{2}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 3:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 3">{{3}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 4:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 4">{{4}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 5:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 5">{{5}}  ----  {{item.time}}</p>
    </div>
    <div>
      <p>Residence time 6:</p>
      <p v-for="item in movedata" v-if="parseInt(item.pos / 1300) === 6">{{6}}  ----  {{item.time}}</p>
    </div>
  </div>
  <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        movedata: [],
        scrollTop: $(window).scrollTop(),
        time: Date.now(),
        stayTime: 0
      },
      mounted () {
        // When some pages scroll to a certain height, the refreshed pages will also be fixed at that height. Initialize movedata data
        var index = parseInt(this.scrollTop / 1300) + 1
        for (var i = 0; i <= index; i++) {
          this.movedata.push({
            pos: i * 1300,
            time: 0
          })
        }
        window.onscroll = () => {
          this.scrollTop = $(window).scrollTop()
        }
        setInterval(() => {
          var currentTime = Date.now()
          var disTime = currentTime - this.time
          // Calculate the serial number of the module currently displayed on the screen. There are at most two modules in a screen. CurrtIndex always specifies the module above.
          var currentIndex = parseInt(this.scrollTop / 1300)
          var length = this.movedata.length
          if (currentIndex + 1 >= length) {
            for (var i = length; i <= currentIndex + 1; i++) {
              this.movedata.push({
                pos: 1300 * i,
                time: disTime
              })
            }
          } else {
            // Calculate how much the current scroll height exceeds the full screen
            var modeDis = this.scrollTop - this.movedata[currentIndex].pos
            // Indicates that the display area of the module above the screen exceeds 400, which can accumulate the residence time.
            if ((1300 - modeDis) > 400) {
              this.movedata[currentIndex].time += disTime
            }
            // Represents that the display area of the module below the screen exceeds 400, which can accumulate residence time.
            if (modeDis > 400) {
              this.movedata[currentIndex + 1].time += disTime
            }
          }
          this.time = currentTime
        }, 1000)
      }
    })
  </script>
</body>
</html>

In this way, the array length of movedata is equal to the number of modules in the page.

Here I recommend my front-end learning exchange circle: 767273102, which is learning front-end from the most basic HTML+CSS+JS [cool effects, games, plug-in packaging, design patterns] to mobile HTML5 project actual combat learning materials have been collated, sent to each front-end small partner. The latest technology in 2019 keeps pace with the needs of enterprises. Friends are learning and communicating in it. Every day Daniel will explain the front-end technology regularly.

Learning front-end, we are serious

Keywords: Web Development Vue JQuery IE Mobile

Added by cristal777 on Tue, 04 Jun 2019 06:01:24 +0300