Skip to content

A wrapper around driver.js to make handling dynamic elements become simpler

License

Notifications You must be signed in to change notification settings

halws/driver-js-dynamic-wrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Purpose

Driver.js is a nice and easy to use library for highlighted showcase tour. The only cumbersome use case for me was handling steps on dynamically created elements. There is an issue, where multiple driver solution was proposed. So, I've used that one, and created this wrapper to handle edge cases (mostly) by plugin.

Usage and demo

Install using npm:

$ npm install driver-js-dynamic-wrapper

Get started:

import Driver from 'driver-js-dynamic-wrapper'
import 'driver.js/dist/driver.min.css';

Creating multiple steps on dynamic elements. Original source

Problem explanation

Problem occurs when defining the steps via original defineSteps(). Here library iterates throw DOM elements and skip step if it's not available. So in result dynamically created steps(delayed) are omitted. To "fix" that you should refresh steps before moving into dynamically created element.

  • Refreshing steps meant to update original driver.js steps to make it catch all currently visible DOM elements defined in steps configuration.
  • Consider you move from first steps to second. The 2nd step highlight dynamically created element after some action. For example redirection to next page action take a 500ms. To make refreshSteps() "pick up" step you should delay before.
  • Delaying is possible to do inside onNext() or onPrevious() functions inside steps configuration JSON. In more advanced scenario you could wait for some AJAX request, etc. then call refreshSteps()

Initial call

const driver = new Driver();
const mainConfig = {...}; // driver.js options 

driver
    .init(mainConfig)
    .defineSteps(stepsConfig(driver))     
    .start();

Defining a steps

Back to example with two steps, where 2nd step highlight dynamically created element

const stepsConfig = (Driver) => [
  {
    element: "#step-1",
    popover: {
      title: "first title ...",
      description: "first description ...",
    },
    async onNext(Element) {
      // prevent double click
      if (Driver.lockClick) return Driver.preventMove();

      Driver.handleNext(Element).preventMove();

      if (Driver.elementIsVisible) {
        Driver.continue();
        return;
      }

    // required delay to make DOM element #step-2 became visible
    // I use delay() as promise-based function, but it possible to wrap code bellow with setTimeout()
    // await delay(500)

      Driver.refreshSteps().continue();
    },
  },
  {
    element: "#step-2",
    popover: {
      title: "second title ...",
      description: "second description ...",
    },
  },
]; 

API

I didn't touch original driver.js code, you can access all the methods of driver.js. Some of this methods have the same name as in original plugin. They do the same functionality. I've duplicated them to make it chainable.

method description
init(opt = {}) initialize instance; receives all original options from driver.js
handleNext({ node }) locks double click; handle step number; should always be called inside onNext()
handlePrevious({ node }) locks double click; handle step number; should always be called inside onPrevious()
defineSteps(steps = []) set steps; receives Array of step's definition.
refreshSteps() refresh steps for tour; should be called after delay to catch DOM elements
reset() reset all steps and the tour to 0
start(stepNumber = 0) start tour from specified step, accept numbers
preventMove() prevent moving next step
continue() continue tour; it tries to get next visible step and start tour from it

getter description
elementIsVisible check if current step's element is visible

Examples

Useful

  • promise-based function delay()
    function delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }   
  • css fixes

    stacking bug when animated with children of fixed elements

    kamranahmedse/driver.js#133 (comment)

        div#driver-highlighted-element-stage, div#driver-page-overlay {
        background: transparent !important;
        outline: 5000px solid rgba(0, 0, 0, .75)
        }
  • link to vue-js plugin

TO-DO

  • add TS support
  • add tests
  • add example with multiple scenarios
  • add Cypress-like get() syntax to catch elements automatically without manual timeout

About

A wrapper around driver.js to make handling dynamic elements become simpler

Resources

License

Stars

Watchers

Forks

Packages

No packages published