Firing javascript function between intro.js steps
Just in case anyone else stumbles across this as I did, I found that the 'steps' array you can pass to setOptions can be accessed in "this._introItems" when Intro is executing.
You can define functions then in the 'steps' array and then execute them at the appropriate time (onchange, etc.) using Intro's built in functions.
// https://introjs.com/docs/intro/options/
//https://introjs.com/example/programmatic/index.html
var options = {
steps: [{
element: '#myElement',
intro: "This step has two functions",
myBeforeChangeFunction: function() {
alert('this is a before change loaded function');
},
myChangeFunction: function() {
alert('this is a change loaded function');
},
},
{
element: '#mySecondElement',
intro: "This has no functions, which is why we need to check for the existence of functions below",
}]
};
var intro = introJs();
// add the options object with the steps/functions above
intro.setOptions(options);
//use the intro.js built in onbeforechange function
intro.onbeforechange(function(){
// check to see if there is a function on this step
if(this._introItems[this._currentStep].myBeforeChangeFunction){
//if so, execute it.
this._introItems[this._currentStep].myBeforeChangeFunction();
}
}).onchange(function() { //intro.js built in onchange function
if (this._introItems[this._currentStep].myChangeFunction){
this._introItems[this._currentStep].myChangeFunction();
}
}).start();
I hope this helps somebody!
I think I found a better solution, by setting a callback on step changes :
introJs().onchange(function(targetElement) {
console.log(targetElement.id);
switch (targetElement.id)
{
case "step1":
function1();
break;
case "step2":
function2();
break;
}
}).start();
this._currentStep is better.
introJs().onchange(function(targetElement) {
console.log(this._currentStep);
}).start();
Another solution would be to alter it's step events in a more generic way:
//setup your guide object and steps, with the addition of
//event attributes per step that match the guide objects
//available callbacks (onchange, onbeforechange, etc.)
var guide = introJS();
var options = {
steps:[
{
element: '#step1',
intro: 'Your content...',
position: 'top',
onchange: function(){
//do something interesting here...
},
onbeforechange: function(){
//do something else interesting here...
}
},{
element: '#step2',
intro: 'Your content...',
position: 'top',
onchange: function(){
//do something interesting here...
},
onbeforechange: function(){
//do something else interesting here...
}
}
]
};
createStepEvents: function( guideObject, eventList ){
//underscore loop used here, foreach would work just as well
_.each( eventList, function( event ){
//for the guid object's <event> attribute...
guideObject[event]( function(){
//get its steps and current step value
var steps = this._options.steps,
currentStep = this._currentStep;
//if it's a function, execute the specified <event> type
if( _.isFunction(steps[currentStep][event]) ){
steps[currentStep][event]();
}
});
}, this );
}
//setup the events per step you care about for this guide
createStepEvents( guide, ['onchange','onbeforechange']);
This way you can specify which events happen on the description object of the step, rather than disconnecting events and their associated events.