How do I get Bootstrap Tour to work with a jQuery dialog?

﹥>﹥吖頭↗ 提交于 2019-12-03 08:46:17

The problem rests in the fact that the jQuery-UI Dialog has created a new stacking context and so changes to the z-index of the #content element will only show up relative to it's current stacking context.

For proof, add the following css, and you'll still see the #content div display above the dialog, which has a z-index of 100. --> i.e. Z-indexes are not absolute! ... jsFiddle

#content { z-index: 0 !important; }

From What No One Told You About Z-Index:

Every stacking context has a single HTML element as its root element. When a new stacking context is formed on an element, that stacking context confines all of its child elements to a particular place in the stacking order. That means that if an element is contained in a stacking context at the bottom of the stacking order, there is no way to get it to appear in front of another element in a different stacking context that is higher in the stacking order, even with a z-index of a billion!

New stacking contexts can be formed on an element in one of three ways:

  • When an element is the root element of a document (the element)
  • When an element has a position value other than static and a z-index value other than auto
  • When an element has an opacity value less than 1

The problem is Bootstrap Tour doesn't really have a good way of identifying this. When they start a tour on an element, they apply:

  • A full screen black tour-backdrop with a z-index of 1009,
  • A white tour-step-background behind the object with a z-index of 1010
  • and apply a z-index to the current tour element of 1011

...but the last z-index has no effect since our object is already in a stacking context. It is just positioned higher than any of the other elements within that stack (which it already was). Incidentally, that's why removing the z-index from ui-front results in the proper appearance because it frees the element from its current stack.


Here's what Bootstrap Tours should be doing, and we'll do manually with DOM manipulation.

The problem is that they are trying to position the elements relative to one another with z-indexes, but anytime the tour object is in a stacking context different from the .tour-step-background and .tour-backdrop, this will fail.

Solution? Place the elements you're generating inside the same stacking context!

Here's a simplified markup tree

  • Body
    • Tour background (normally goes here)
    • New stacking context
      • Tour object
      • Tour background (should go here)

To override this, we'll plugin to the tours onShown method and move the backdrops ourselves:

In JavaScript, when creating a tour, we'll do the following:

var t = new Tour({
    backdrop: true,
    onShown: function(tour) {
        var stepElement = getTourElement(tour);
        $(stepElement).after($('.tour-step-background'));
        $(stepElement).after($('.tour-backdrop'));
    }
});

function getTourElement(tour){
    return tour._steps[tour._current].element
}

This uses jQuery's .after() DOM manipulation to move the backdrop to the same stacking context as our tour object.

Also, we'll need to position both our tour backdrop elements as fixed instead of absolute, so they don't try to squeeze inside of our dialog. We can do that with the following CSS:

.tour-step-background, 
.tour-backdrop {
    position: fixed;
}

Working Demo in Fiddle

Which should look like this:

I had the problem and I cheated by setting the opacity of tour-step-background to 0.4

The right jsfiddle working with the last version of bootstrap tour

[http://jsfiddle.net/KyleMit/DYNbj/82/][1]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!