One of my tips has a button which the user can press to change the layout, which swaps an element which for identical another, even though they share the same selector. After I change the layout, if I click next to a tip which highlights the swapped element, the tip goes offscreen. The targetElement in the onchange callbacks refer to a DOM element which no longer exists on the page...
My thinking was that I would be able to call refresh() in onbeforechange but it didn't refresh the elements on the page.
I think refresh should either recache the elements, or the elements should be more dynamic and calculated on the fly, especially with todays single page applications.
So you mean we should provide a function that scans and redefines all elements again?
Sure, that works
I have a similarly "dynamic" page using AngularJS, and some of the elements in my page get recreated as ilovett mentioned. The autorefresh feature in Angular-Intro automatically calls refresh() when things change on the Angular side, and that made the situation a bit better, but it still doesn't work in some cases.
I'm not yet familiar with introjs' code, but is there some reason that the elements need to be cached? Can't you just lookup the element right when the user requests the next or previous element? This isn't performance critical code.
I have also seen one case where it is possible in for my currently focused element to be recreated (same id, but a new DOM node got created). Initially, when this happens, the introjs overlay just moves to the top left corner. But then, if I hit Back or Next, introjs crashes on the last line of code below, because oldShowElement is null:
//remove old classes
var oldShowElement = document.querySelector('.introjs-showElement');
oldShowElement.className = oldShowElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, '');
Is this discussion still current ? I use this for an AngularJS application and allow user actions on some of the intro steps that swaps elements out for others that use the same selector. I agree with @mindjuice that this isn't performance-critical code, so I'd love to see introJS either not cache the elements and just compute them when the relevant step is clicked, or refresh the cache. I'm happy to go through the code and make this change if you are okay with it. This is a fantastic library and we'd love to use it in more of our applications.
+1, I also use this with AngularJS, I swap elements with ng-if, and intro fails to find them after they were removed, even if I do .refresh()
However, I found a workaround - after doing the swap, I manually do:
intro._introItems[3].element = document.querySelector('#step4');
It feels a bit hacky though.
:+1: I have similar issue with angularJS.. @michalmikolajczyk Thank for work around.. @afshinm Yes it would be great IF we can redefined elements..
Having the same issue using Durandal cached views. Any update on this issue
Thanks a lot @michalmikolajczyk ! You saved my life.
For me, using ng-show instead of ng-if for the highlighted elements fixed the issue.
Is this thread active ? I am facing the same issue as @ilovett . Please provide a work around
Thanks @michalmikolajczyk !
One note from me, I had to add introjs-fixParent (to parents which are positioned customly) and introjs-showElement (to the target element) classes custom because targetElement was overlayed by introjs tooltip :)
I wrote a little workaround for this problem, maybe it helps someone:
introJs.onbeforechange(function(targetElement) {
introJs._options.steps.forEach(function (step, key) {
if(step.element){
introJs._introItems[key].element = document.querySelector(step.element);
introJs._introItems[key].position = step.position ? step.position : 'bottom';
}
});
});
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
+1, I also use this with AngularJS, I swap elements with
ng-if, and intro fails to find them after they were removed, even if I do.refresh()However, I found a workaround - after doing the swap, I manually do:
It feels a bit hacky though.