z-index无法正常工作

时间:2015-12-14 15:13:16

标签: javascript html css leaflet z-index

我目前正在使用Leaflet和Mapbox来创建自定义地图。一直都很好,直到我开始研究弹出窗口。

我的情况:我有一个自定义导航/控制面板,但需要后面任何打开的弹出窗口(目前不是)。

我准备了JSFiddle和此屏幕截图

enter image description here

我的部分CSS是

#map-nav {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: 2;
}
.leaflet-popup-pane, .leaflet-popup {
  z-index: 1000 !important;
}

默认的传单类的z-index为7(我认为),我只是将其覆盖为100%肯定。在浏览器(FF / Chrome)中检查代码时,我看到z-index设置正确,.leaflet-popup中没有其他元素设置z-index

我已经读到负面z-index可以解决这个问题,但是当我使用多个元素时,我真的很喜欢一个不那么“hacky”的解决方案 - 如果有的话。 (欢迎JavaScript解决方案,因此标签)

正如我从代码检查中看到的,Leaflet将一些属性设置为.leaflet-popup,其位置方面为:transform: translate3d(..)bottomleft

感谢任何帮助。

修改

我可以将#map-nav置于#map-content内,但仍然无效fiddle。但是,当我尝试模仿这一点而不是地图内容时,it does work

1 个答案:

答案 0 :(得分:11)

The problem is that #map-nav exists in an entirely different stacking context than the marker and its popup.

The way you have it set up right now, the entire map is behind #map-nav. So, changing the z-index on either #map-nav or the .leaflet-popup-pane won't really help.

Disclaimer: This is a terrible, terrible hack. If you look into Leaflet's documentation and find a way to add your own widgets, I'd highly recommend doing that instead of this.

That said, I have something which sort of works (your mileage may vary):

  1. Move #map-nav into .leaflet-map-pane
  2. Create a MutationObserver and observe changes to the attributes of .leaflet-map-pane.
  3. Whenever the style attribute of .leaflet-map-pane changes, grab its style.transform property and extract the x and y values. Invert those values and apply them to #map-nav.

var map = L.map('map-content', {
  zoomControl: false
}).setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
  attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
  maxZoom: 18,
  id: 'rauschundrausch.cih3gisks00r8rlly0ob5s2me',
  accessToken: 'pk.eyJ1IjoicmF1c2NodW5kcmF1c2NoIiwiYSI6ImNpaTYyeW14MTAwNml2eW0zcmR6aHIzdDcifQ.6T8nzYq49rFnvcqk6lgYPg'
}).addTo(map);

var marker = L.marker([51.5, -0.09]).addTo(map);
marker.bindPopup("this is a<br>large<br>popup<br>in<br>terms of height");

var mapNav = document.getElementById("map-nav");

var mapPane = document.querySelector(".leaflet-map-pane");

var rxTranslate = /translate(?:3d)?\(([^\)]+)\)/i;

mapPane.appendChild(mapNav);

var observer = new MutationObserver(function(mutations) {
  if (mutations.some(m => m.attributeName === "style")) {
    // apply an inverse transform
    mapNav.style.transform = "translate(" + mapPane
      .style
      .transform
      .match(rxTranslate)[1]
      .split(",")
      .slice(0, 2) /* extract only x and y; discard z */
      .map(n => parseFloat(n) * -1 + "px") /* invert values */ + ")";
  }
});

observer.observe(mapPane, {
  attributes: true
});
#map {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
#map-nav {
  position: absolute;
  left: 10px;
  top: 10px;
  width: 100px;
  height: 100px;
  background-color: #ccc;
  z-index: 200;
  box-shadow: inset 0 0 0 1px #f00;
}
#map-content {
  width: 100%;
  height: 100%;
}
.leaflet-popup-pane {
  z-index: 3;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>
<div id="map">
  <div id="map-content">
    <div id="map-nav"></div>
  </div>
</div>

This may lag on some clients while dragging. You could use a timeout to defer the update but that would mean the nav menu would move around until you stop dragging.