How to use the novice guidance tool intro.com across pages (across routes) in vue project js

Functional requirements

The company requires novice guidance on its own platform, or cross page and cross routing. I found the novice guidance plug-in on the Internet and finally chose intro JS to use, maybe because it looks a little good, so throw it away.

Most of what I write are ideas. If I can understand it, I should be able to easily achieve these effects. If I paste it directly, it is estimated that it will be suspended.

It is suggested to go to intro.com first JS official website take a look at the demo, understand it, and then take a look at the operation based on the demo.

I'm just a small grass-roots programmer. If you have any ideas and logic that make you laugh, don't laugh at me. Please tell me gently. Thank you. I'm very glass hearted.

The following are the real problems they encounter and try to solve them. There are better solutions that can be posted and discussed together.

Use intro JS encountered problems and code

1. Cannot cross route

The biggest problem is intro JS cannot cross route because it obtains and displays the novice guide according to the unique Id value of dom on the current page, so it cannot obtain a page without rendering.
So what I want is to load intro from the beginning on every page JS, after the previous page is guided, you can directly route Push to the next route, and then load it automatically for guidance. After guidance, push to the next route. OK, perfect doll.

Let's start with utils JS file encapsulates a tool class intro JS to facilitate direct reference of each page. Here I directly post the final version of the code. I think it's better to understand.

utils -> intro.js

import introJs from 'intro.js'
import 'intro.js/introjs.css';
import router from '@/router'
import store from '@/store'

let count = 0 // Initialize to 0, and then judge the current step according to the id selector of the dom passed in at each step
let state = 0 // skip: 0 ,done: 1;
export function guide (introSteps) {
  // console.log(sessionStorage.getItem('isIntro'))
  if (!parseInt(sessionStorage.getItem('isIntro'))) {
    return
  }
  introJs().setOptions({
    steps: introSteps,
    /* When the position is selected automatically, the priority of the position arrangement */
    positionPrecedence: ["top", "bottom", "right", "left"],
    prevLabel: "Previous step",
    nextLabel: "next step",
    skipLabel: "skip",
    // Here, because the last step of each page will actually display doneLabel, but in fact, our novice guidance operation has not been completed and needs to jump the route to continue, so the next step is displayed instead of completion.
    doneLabel: "next step", 
    hidePrev: true,
    exitOnOverlayClick: false,
    /* Whether to display the data steps of the description*/
    showStepNumbers: false,
    /* Do you want to use dots to show progress */
    showBullets: false,
    /* Use keyboard Esc to exit */
    exitOnEsc: false,
    /* Default prompt location */
    hintPosition: 'top-left',
    /* Describes the style of the highlighted area */
    highlightClass: 'customHighlight',
    /* The style of the guide description text box */
    tooltipClass: 'customTooltip'
  }).onchange(function (targetElement) {
    // Triggered every time I change, my id style is "guide step < id >
    // id represents the first step of novice guidance, such as "guide-step1", which is judged by id
    count = parseInt(targetElement.id.slice(-1))
  }).onafterchange(function (targetElement) {
    // There are only seven steps for novice guidance designed by the company. If count == 7, it means that now is the last step
    // After the jump is completed, use the dom operation of js to change the doneLabel from "next" to "finish"
    if (count === 7) {
      let i = document.getElementsByClassName('introjs-donebutton')[0].innerHTML = 'got it'
    }
  }).oncomplete(function (targetElement) {
    // The events executed after clicking the finish and skip buttons do not distinguish between finish and skip.
    state = 1
    setTimeout(() => {
      if (state) {
        judgeCount()
      }
    }, 200)
  }).onexit(function (targetElement) {
    // The event to be executed after clicking the finish button
  }).onskip(function (targetElement) {
    // The event to execute after clicking the skip button
    // onskip, which I couldn't find in the official website api at that time, was turned out by me through the source code. I tossed for a long time and was speechless.
    // Because after clicking skip, the novice boot is completed by default. At this time, you need to pass the status to the back end to ensure that there is intro next time JS page is not loaded from time to time, novice guidance.
    // Because vue is written across routes, the completion of each page is not that the user has really completed the novice guidance
    // Therefore, if we don't distinguish between completing and skipping the events triggered respectively, we won't know whether the user is skipping (= = completing the novice guidance) or just completing the current page. We need to continue to jump to the next route.
    state = 0
    // Store in the cache. The intro will not be triggered the next time you enter the novice boot routing page js
    store.state.introStepInfo.isIntro = state
    sessionStorage.setItem('isIntro', state)
  }).start();
}

// This is the corresponding operation for the novice to guide each step and click the next step
// On my side, steps 1 and 2 are on one page, steps 3 and 4 are on one page, steps 5 and 6 are on one page, and step 7 is on one page
// So I don't need to carry out specific operations at 1, 3 and 5. Follow intro JS just go
function judgeCount () {
  // This is some data required for pre stored jump routing
  let _introStepInfo = JSON.parse(sessionStorage.getItem('introStepInfo'))
  switch (count) {
    case 1:
      break
    case 2:
      router.push({
        path: '/courseDetail',
        query: {
          id: _introStepInfo.courseId
        }
      })
      break
    case 3:
      break
    case 4:
      let _introChapterName = sessionStorage.getItem('chapterName')
      router.push({
        path: '/coursePreview',
        query: {
          id: _introStepInfo.courseId,
          chapterId: _introStepInfo.chapterId
        }
      })
      break
    case 5:
      break
    case 6:
      router.push({
        path: '/myCourses'
      })
      break
    case 7:
      sessionStorage.setItem('isIntro', 0)
      break
  }
}

2. Load intro after all the data required for page guidance are obtained and the rendering is completed js

A problem to note here is that some DOMS are rendered only after getting data from the back end. If they are not rendered, intro JS cannot get a unique id value.

Therefore, in the axios package, we need to set a Boolean variable isaaxios with the value of false globally and change it to true after the request comes back.
This is only the most basic. In addition, we should also consider whether the page has more than two DOMS that need to get data to render. Therefore, at this time, we need to add a global variable count, which is + 1 when requesting request, minus 1 when response comes back, and set isAxios to true when count is 0. Then we render intro Set a timer of 500 ms / time in the page life cycle mounted() of JS and judge that isAxios is true. Then we can conduct novice boot and clear it after completion.

These are immature. If there are better methods, you can put forward them.

intro. How to use js tool class

// Introduce their own encapsulated novice boot function
import { guide } from '@/utils/intro'

Set the timer in the mounted() life cycle

let i = setInterval(() => {
    if (!this.isAxios) {
            guide([
              {
                title: 'Open Courses',
                intro: 'View all the courses you have purchased.(1/7)',
                element: document.querySelector('#guide-step1')
              },
              {
                title: 'Curriculum resources',
                intro: 'Click any course cover to enter the course.(2/7)',
                element: document.querySelector('#guide-step2')
              }
            ])
            clearInterval(i)
     }
}, 500)

In fact, there are many small details about this in the package axios, but it is different from intro JS actually doesn't matter much. I won't say it this time. Just pay more attention.

Keywords: Javascript Vue

Added by adyre on Thu, 10 Feb 2022 23:08:00 +0200