2

While using introjs.js, I am trying to set the position of a tooltip (.introjs-tooltip) but, if I use the onafterchange event, my code runs, and then the position of the tooltip is set by introjs, and my values for top and left are overwritten. How can I make my change AFTER introjs has done it's calculations for the location of the tooltip?

<div>
  <div class="divStep step1">
    <span>Nothing much going on here</span>
  </div>
  <div id="step2" class="divStep step2">
    <span>This is step 2</span>
  </div>
  <div id="step3" class="divStep step3">
    <span>This is step 3</span>
  </div>
</div>

body {
    background-color: #00eeee;
}

.divStep {
    display: block;
    height: 100px;
    width: 400px;
    background-color: #fff;
    margin: 10px;
    padding: 10px;
}

.tt-step2 {
    top: 0 !important;
    left: 0 !important;
    background-color: #ff0000;
}

var myIntro = {
    tooltipPosition: 'bottom',
    steps: [
        {
            intro: 'Howdy! This is step 1'
        },
        {
            element: '#step2',
            intro: 'This is step 2',
            onbeforechange: function(){
                console.log('onbeforechange step 2');
              $('.introjs-tooltip').addClass('tt-step2');
              console.log('has class? ' + $('.introjs-tooltip').hasClass('tt-step2'));
            },
            onchange: function(){
                console.log('onchange step 2');
              $('.introjs-tooltip').addClass('tt-step2');
              console.log('has class? ' + $('.introjs-tooltip').hasClass('tt-step2'));
            },
            onafterchange: function(){
                console.log('onafterchange step 2');
              $('.introjs-tooltip').addClass('tt-step2');
              console.log('has class? ' + $('.introjs-tooltip').hasClass('tt-step2'));
            }
        },
        {
            element: '#step3',
            intro: 'This is step 3'
        }
    ]
}

function launchIntro(){
    var intro = introJs();
    intro.setOptions(myIntro);

    intro
        .onbeforechange(function(){
                currentStep = this._options.steps[this._currentStep];
            if(currentStep.onbeforechange) {
                currentStep.onbeforechange();
            }
        })
        .onchange(function(){
            currentStep = this._options.steps[this._currentStep];
            if(currentStep.onchange) {
                currentStep.onchange();
            }
        })
        .onafterchange(function(){
            currentStep = this._options.steps[this._currentStep];
            if(currentStep.onafterchange) {
                currentStep.onafterchange();
            }
        })
        .start();
}

launchIntro();
  • Do you have some sample code we can take a look at? – clarmond Mar 27 '18 at 12:18
  • Thank you for your response! I created a fiddle here: https://jsfiddle.net/rogdawg/wLwdkx0e/2/ – Roger Knowles Mar 28 '18 at 15:24
  • there's an issue on github about this. https://github.com/usablica/intro.js/issues/936 Unfortunately, without any replies. I'd appreciate if you cared to share your solution. Thanks. – sr9yar Oct 08 '19 at 18:39

1 Answers1

0

I came across a similar issue. Currently IntroJS library has an open issue on github.

I had an assignment to heavily customize the elements styles and adjust some behavior.

I managed to handle the situation by using MutationObserver

Here's an example snippet:

const observer = new MutationObserver((mutations) => {  
    const { target } = mutations[0];

    document.querySelector('.introjs-tooltip').style.top = `${      
        document.querySelector('.introjs-helperLayer').clientHeight
        - document.querySelector('.introjs-tooltip').clientHeight - 10}px`;

    return null; });

observer.observe(   
    document.querySelector('.introjs-tooltip'),     
    { attributes: true, attributeOldValue: true, attributeFilter: ['style'] }, 
);
sr9yar
  • 4,850
  • 5
  • 53
  • 59