[Feature Request] Lifecycle events
lonix1 opened this issue · comments
There are various events, e.g. for the tour: onDestroyed
, and for steps: onNextClick
, onPrevClick
, onCloseClick
.
But they're not useful for a reasonably complex page. I needed events like these:
onTourStarting
onTourStopping
onStepActivating
onStepDeactivating
Those would be more robust and cover the important cases: before/after the tour and before/after each step. That would also work well with async use cases.
Here is my workaround until (hopefully) such events would be natively supported. The trick is to repurpose the onPrevClick
, onNextClick
, onCloseClick
and onDestroyed
events.
const driver = window.driver.js.driver;
const driverObj = driver({
onPrevClick: function(element, step, options) {
let callback = function() { if (driverObj.hasPreviousStep() !== undefined) driverObj.movePrevious(); else driverObj.destroy(); }; // workaround for bug https://github.com/kamranahmedse/driver.js/issues/492
if (typeof onStepDeactivating !== 'undefined') {
onStepDeactivating(driverObj.getActiveIndex(), function () {
if (typeof onStepActivating !== 'undefined' && !driverObj.isFirstStep()) {
onStepActivating(driverObj.getActiveIndex() - 1, callback);
}
else {
callback();
}
});
}
else if (typeof onStepActivating !== 'undefined' && !driverObj.isFirstStep()) {
onStepActivating(driverObj.getActiveIndex() - 1, callback);
}
else {
callback();
}
},
onNextClick: function(element, step, options) {
let callback = function() { if (driverObj.hasNextStep() !== undefined) driverObj.moveNext(); else driverObj.destroy(); }; // workaround for bug https://github.com/kamranahmedse/driver.js/issues/492
if (typeof onStepDeactivating !== 'undefined') {
onStepDeactivating(driverObj.getActiveIndex(), function () {
if (typeof onStepActivating !== 'undefined' && !driverObj.isLastStep()) {
onStepActivating(driverObj.getActiveIndex() + 1, callback);
}
else {
callback();
}
});
}
else if (typeof onStepActivating !== 'undefined' && !driverObj.isLastStep()) {
onStepActivating(driverObj.getActiveIndex() + 1, callback);
}
else {
callback();
}
},
onCloseClick: function (element, step, options) {
let callback = function() { driverObj.destroy(); };
if (typeof onStepDeactivating !== 'undefined') {
onStepDeactivating(driverObj.getActiveIndex(), callback);
}
else {
callback();
}
},
onDestroyed: function(element, step, options) {
if (typeof onTourStopped !== 'undefined') {
onTourStopped();
}
},
});
let callbackTourStarting = function() { driverObj.drive(); };
if (typeof onTourStarting !== 'undefined') {
onTourStarting(callbackTourStarting);
}
else {
callbackTourStarting();
}
I use the CDN scripts on a server-rendered site, so I use the workaround like so:
<script>
function onTourStarting(callback) {
callback();
}
function onStepActivating(activeIndex, callback) {
if (activeIndex === 3) {
loadSomething();
callback();
}
else if (activeIndex === 7) {
doAsyncFoo(function() {
callback();
});
}
else {
callback();
}
}
function onStepDeactivating(activeIndex, callback) {
if (activeIndex === 3) {
reset();
}
callback();
}
function onTourStopped() {
cleanup();
}
</script>
That works really well, and as you can see in the second code block it exposes a very friendly API for callers.
But it would be nice if such events would be exposed natively by the library.
(If someone has a neater workaround, please post it below.)