intro.js icon indicating copy to clipboard operation
intro.js copied to clipboard

Interaction not working properly when multiple stacking contexts exist.

Open KevinMoran99 opened this issue 3 years ago • 15 comments

Description

I'm working on a project in which I'm trying to implement introjs, but I've noted that when highlighting an element that's inside of a different stacking context (i.e. an input inside a modal with z-index: 1000), the element does get highlited properly, but interaction in the element is not posible, even if disableInteraction: false is explicitly set in the option's configuration.

Expected Behavior

Interaction should be allowed on highlited elements inside another stacking context.

Actual Behavior

Interaction does not work in this case, clicking the highlited element does nothing.

Errors and Screenshots

When right click -> inspecting the highlited box, dev tools takes me to the div with "introjs-helperLayer" class, oposed to normal behaviour in which inspecting the box takes me to the actual element. For what I have seen, this happens because, even when the element gets the "showElement" class that gives it an enormous z-index, it is still in the modal's stacking context, so it cannot be put over the helperLayer which exists in the root stacking context. I've read through the docs to see if there's an existing solution to this problem, but I haven't found anything (don't know if there's actually a common solution that I have overlooked). image image

Environment (optional)

Tried on both Chrome and Firefox, introjs version is 3.4.0, we're developing an Angular application using PrimeNG.

KevinMoran99 avatar Apr 06 '21 19:04 KevinMoran99

I am having this same issue. I want interactivity in a bootstrap modal, rearranging the DOM doesn't seem to resolve the problem either.

ajjones20 avatar Apr 20 '21 19:04 ajjones20

I can look into this but I believe this is an exception where element interaction doesn't work because you have an absolute/fixed parent.

Let me know if anyone has any suggestions.

afshinm avatar Apr 26 '21 07:04 afshinm

I too get this issue, I agree it seems to be because the target's parent is absolutely positioned.

Unfortunately this makes intro unusable for me. It sounds like there is no workaround?

If in chrome dev tools I take untick the position: absolute then I can see its actually selectable, to me this would suggest that however you are creating the "hole" to click it just isn't looking at the elements actual position.

sdraper69 avatar Apr 26 '21 15:04 sdraper69

I can look into this but I believe this is an exception where element interaction doesn't work because you have an absolute/fixed parent.

Let me know if anyone has any suggestions.

Indeed, the parent elements of the components that give me this issue are either absolute or fixed. One kinda hacky solution that I found was to analyze the structure of said components and identify specifically which elements of the DOM generated new stacking contexts.

So, I declared the below functions.

  • The first one gets called when I initialize the intro.js tour, and gets rid of the modal's stacking context by obtaining each element that generates it and removing from it the property that creates the context (zIndex, position absolute/fixed, transform, scale, etc)
  • The second one then gets called in .onbeforeexit(), and makes sure that the modal's elements recover their original properties. image

That way, I managed to have everything that I needed in the same stacking context, and hence could use the interaction inside the modal. However, this 'solution' it's still really problematic, as I have to specifically analyze any component that generates a stacking context. There are still some bugs that happen when I do this that I haven't solved yet, and I believe that those could be a consequence of playing this way with the DOM's properties (for example, when I highlight a button that's inside the footer of the modal, the intro.js overlay scrolls down in order to move that button to the middle of the viewport, generating an unusual scroll on my application).

Also, note that in "removeModalStackingContext", I give a zIndex to the 'header' element, which is the modal's header. I did that because when I removed the stacking context from the modal, my app's nabvar would be rendered over the header, resulting in a graphical issue. Those kind of special considerations are what make this solution a really poor one.

I don't know if this approach, as buggy and problematic as it may seem, could help to conceive an idea to properly fix this, haha. Another idea that went through my head was to somehow make the intro.js helpers to render inside the target's stacking context, but as I had no idea on how to make that, I decided to go for the approach of removing the modal's stacking context and then restoring it.

KevinMoran99 avatar Apr 27 '21 01:04 KevinMoran99

this solution works for me as well. thank you so much

ajjones20 avatar Apr 27 '21 15:04 ajjones20

微信图片_20210507150608 微信图片_20210507151035 1620371535(1) 如果目标元素的父元素有z-index,此时遮罩层会完全覆盖住,将遮罩层两个元素移动到目标元素同级中,可以避免覆盖 If the parent element of the target element has a z-index, then the mask will be completely overwritten. Moving the two mask elements to the same level as the target element can avoid overwriting

xiaocaohulian avatar May 07 '21 07:05 xiaocaohulian

To summarize this thread: You cannot interact with the highlighted element if the target element's parent has the z-index value set to anything other than auto (i.e stacking contexts). For now, I'm going to focus on adding more tests to capture the current state.

@xiaocaohulian I like your suggestion and I believe can fix the issue. Can you send a PR?

afshinm avatar May 21 '21 09:05 afshinm

Has there been any progress on this issue? Currently I'm stuck on some ancient version of intro.js because this problem did not exist at that point.

rynkk avatar Jun 16 '21 22:06 rynkk

@rynkk not yet unfortunately. what version of intro.js are you using right now?

afshinm avatar Jun 17 '21 07:06 afshinm

@afshinm I am using 2.9.3. I'm gonna try to pin point where the regression happened.

Edit: From what I can tell, 3.0.1 was the last working version; the regression was introduced with the reskin of intro.js @3.1.0.

rynkk avatar Jun 17 '21 10:06 rynkk

@xiaocaohulian image image

chenxu-javascript avatar Jul 06 '21 10:07 chenxu-javascript

Any progress on this issue? I have the exact same problems with v5.0.0.

scifresh avatar Feb 17 '22 15:02 scifresh

只需要在创建introJs对象的时候,设置选择器到带z-index的父级元素里就可以了 比如有一个modal。

justhzd avatar Apr 09 '22 18:04 justhzd

@scifresh use introJs([targetElm])

justhzd avatar Apr 09 '22 18:04 justhzd

css .introjs-overlay { pointer-events: none; } .introjs-helperLayer { pointer-events: none; }

pointer-events - CSS:层叠样式表 | MDN

需要注意,一旦加上这个属性,遮罩下的任意元素均可操作交互。

jiangbinwangyi avatar Jul 24 '23 05:07 jiangbinwangyi