防止绝对定位的div吞咽点击事件而不禁用滚动条

时间:2018-01-18 12:35:28

标签: javascript html css mouseevent dom-events

版本1

代码

以下代码是我在项目中使用的布局(的简化版本):



document.getElementById("map").addEventListener("click", function(e) {
  alert("Map clicked!");
});

document.getElementById("control1").addEventListener("click", function(e) {
  alert("Control 1 clicked!");
});

document.getElementById("control2").addEventListener("click", function(e) {
  alert("Control 2 clicked!");
});

body, html {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
}

.map {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: #0c0;
  padding: 10px;
}

.controlgroup {
  position: absolute;
  top: 10px;
  bottom: 10px;
  right: 10px;
  width: 200px;
  overflow: scroll;
  overflow-y: auto;
  overflow-x: hidden;
}

.control {
  padding: 10px;
}

#control1 {
  background: #c00;
}

.control {
  background: #00c;
}

<div class="map" id="map">
  MAP
</div>
<div class="controlgroup">
  <div class="control" id="control1">
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
  </div>
  <div class="control" id="control2">
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
  </div>
</div>
&#13;
&#13;
&#13;

问题

除非我的浏览器高度大于我的控制组的高度,否则它会按预期工作。

然后,我的控制组会吞下控件下方的点击,而不是传递给地图。

版本2

代码

版本1的一个简单修复是将一个指针事件属性添加到我的CSS中,以忽略对控制组的点击,然后为控件重新启用它们:

&#13;
&#13;
document.getElementById("map").addEventListener("click", function(e) {
  alert("Map clicked!");
});

document.getElementById("control1").addEventListener("click", function(e) {
  alert("Control 1 clicked!");
});

document.getElementById("control2").addEventListener("click", function(e) {
  alert("Control 2 clicked!");
});
&#13;
body, html {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
}

.map {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: #0c0;
  padding: 10px;
}

.controlgroup {
  position: absolute;
  top: 10px;
  bottom: 10px;
  right: 10px;
  width: 200px;
  overflow: scroll;
  overflow-y: auto;
  overflow-x: hidden;
  pointer-events: none;
}

.control {
  padding: 10px;
}

#control1 {
  background: #c00;
}

.control {
  background: #00c;
  pointer-events: auto;
}
&#13;
<div class="map" id="map">
  MAP
</div>
<div class="controlgroup">
  <div class="control" id="control1">
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
  </div>
  <div class="control" id="control2">
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
  </div>
</div>
&#13;
&#13;
&#13;

问题

不幸的是,这打破了控制组滚动条的行为。现在,我无法再使用滚动条滚动控制组。

问题

在我的实际项目中,控件的实际内容和控件的数量对于不同的URL是不同的,但下面的CSS代码是针对所有控件和控件组的。此外,我的实际项目中的控件是通过JavaScript以编程方式生成的,并且可以根据用户输入隐藏或显示某些控件。

所以我宁愿不根据所有控件的总高度硬编码控件组的高度,因为这意味着在加载所有控件后以编程方式计算高度,然后每次重新计算高度添加/删除控件。我想避免这种情况,但我正在努力想出办法!

考虑到这些标准,我该怎么做才能阻止我的控制组吞下应该应用于地图的点击而不禁用其滚动条?

我更喜欢仅使用CSS的解决方案,但我可以使用基于JS的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以从bottom:10px移除.controlgroup,这会使控制组的高度自动生成,因此无法覆盖整个页面高度,然后添加max-height: calc(100% - 20px // Reduce space from top and bottom 10px + 10px );

&#13;
&#13;
document.getElementById("map").addEventListener("click", function(e) {
  alert("Map clicked!");
});

document.getElementById("control1").addEventListener("click", function(e) {
  alert("Control 1 clicked!");
});

document.getElementById("control2").addEventListener("click", function(e) {
  alert("Control 2 clicked!");
});
&#13;
body, html {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
}

.map {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: #0c0;
  padding: 10px;
}

.controlgroup {
    position: absolute;
    top: 10px;
    /* bottom: 10px; */
    right: 10px;
    width: 200px;
    overflow: scroll;
    overflow-y: auto;
    overflow-x: hidden;
    max-height: calc(100% - 20px);
}

.control {
  padding: 10px;
}

#control1 {
  background: #c00;
}

.control {
  background: #00c;
}
&#13;
<div class="map" id="map">
  MAP
</div>
<div class="controlgroup">
  <div class="control" id="control1">
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
    This is control 1<br />
  </div>
  <div class="control" id="control2">
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
    This is control 2<br />
  </div>
</div>
&#13;
&#13;
&#13;