admin管理员组

文章数量:1394077

JsFiddle: JsFiddle

I have a bootstrap popover window and a button to call the popover out.

My goal is: I want to have Intro.js feature to introduce:

step 1: click the button;

step 2:Here is the popover window.

Intro.js provides an option that can pre-define the steps programmically. So here's my code of introjs:

var intro2 = introJs();
  intro2.setOptions({
      exitOnOverlayClick: true,
      showBullets: false,
      //showStepNumbers: false,
      steps: [
      {
        element: document.querySelector('#saveSelection'),
        intro: "Click this button to call popover window.",
        position: 'top'
      },
      {
        element: document.querySelector('.popover.fade.top.in'),
        intro: "popover windown",
        position: 'top'
      }, 
      ],
  }).setOption('doneLabel', 'Close').start();
  });

But my problem is that while I was in the introJs layout(step1), it located the button but this time popover window wasn't called out. Then I went ahead to click the button, popover called out, then I click next on Introjs, it couldn't locate my popover window.

The reason probably is because when introJs was initialized at the first time. it has already scanned those elements in the steps I defined in intro2.setOptions, but since the popover is a dynamic element so introJs couldn't find a popover named class="popover fade top in" at the initial stage.

Same issue happened for bootstrap Modal.

Any solutions?

JsFiddle: JsFiddle

I have a bootstrap popover window and a button to call the popover out.

My goal is: I want to have Intro.js feature to introduce:

step 1: click the button;

step 2:Here is the popover window.

Intro.js provides an option that can pre-define the steps programmically. So here's my code of introjs:

var intro2 = introJs();
  intro2.setOptions({
      exitOnOverlayClick: true,
      showBullets: false,
      //showStepNumbers: false,
      steps: [
      {
        element: document.querySelector('#saveSelection'),
        intro: "Click this button to call popover window.",
        position: 'top'
      },
      {
        element: document.querySelector('.popover.fade.top.in'),
        intro: "popover windown",
        position: 'top'
      }, 
      ],
  }).setOption('doneLabel', 'Close').start();
  });

But my problem is that while I was in the introJs layout(step1), it located the button but this time popover window wasn't called out. Then I went ahead to click the button, popover called out, then I click next on Introjs, it couldn't locate my popover window.

The reason probably is because when introJs was initialized at the first time. it has already scanned those elements in the steps I defined in intro2.setOptions, but since the popover is a dynamic element so introJs couldn't find a popover named class="popover fade top in" at the initial stage.

Same issue happened for bootstrap Modal.

Any solutions?

Share Improve this question asked Apr 15, 2016 at 15:12 QIWEN HUQIWEN HU 2493 gold badges8 silver badges19 bronze badges 2
  • Did you ever find the solution to this problem? I would also like to dynamically load the steps in intro.js – Special Character Commented Jul 8, 2016 at 16:56
  • @Brandon Roberts I used alternative solution and fixed it. Popover window doesn't generate into DOM in document.ready() state. So I put a button inside of popover window. So every time when it displays on the page, I click that button to call intro.js, then introjs will find where the popover window is and display correctly. – QIWEN HU Commented Jul 8, 2016 at 21:00
Add a ment  | 

3 Answers 3

Reset to default 7

If anyone is still looking for a solution on google, I figured out a working solution that can be applied to other cases of attaching a step's element to dynamic objects.

On the intro object init, add the following to enable step-specific function calls before loading the step. (function creds)

intro2.onbeforechange(function(){
  if (this._introItems[this._currentStep].preChange) {
    this._introItems[this._currentStep].preChange();
  }
});

Within the popover step, use the preChange attribute to call a function and dynamically set the element and position of that step.

  {
    intro: "popover windown",
    preChange: function(){
      this.element = document.querySelector('.popover.fade.top.in');
      this.position = "top";
    }
  },

Note that the code in general will break if the popover is not active when moving onto to the popover step, so you would want to enforce/check if the popover is open before moving onto that step. Otherwise, assuming that the popover is visible in this example, it functions as expected

JSFiddle

I had the same problem. I couldn't access the intro2's private property _introItems to change the array.

So I do this instead and it works.

intro2.onafterchange((el) => {
    if (intro2.currentStep() === theStepYouWantToChange) {
        const targetElement: HTMLElement = document.querySelector('.popover.fade.top.in');
        
        if (targetElement) {
            targetElement.classList.add('introjs-showElement')
        }
    }
});

Hope this helps.

If I'm not mistaken, you have the same problem as asked Event binding on dynamically created elements?

On that case you have to bind a function to the dinamic created element.

本文标签: javascriptHow to make Introjs select the element that dynamically generated after page loadStack Overflow