javascript - 防止绝对定位的 div 在不禁用滚动条的情况下吞噬点击事件

标签 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>

问题

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

然后,控件下方的点击被我的控制组吞没,而不是传递给 map 。


版本 2

代码

第 1 版的一个天真的修复是在我的 CSS 中添加一个指针事件属性以忽略对控件组的点击,然后为控件重新启用它们:

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;
  pointer-events: none;
}

.control {
  padding: 10px;
}

#control1 {
  background: #c00;
}

.control {
  background: #00c;
  pointer-events: auto;
}
<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>

问题

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


问题

在我的实际元素中,对于不同的url,控件的实际内容和控件个数是不同的,但是下面的CSS代码是对所有控件和控件组收费的。此外,我的实际元素中的控件是由 JavaScript 以编程方式生成的,某些控件可以根据用户输入隐藏或显示。

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

考虑到这些标准,我应该怎么做才能防止我的控制组在不禁用其滚动条的情况下吞噬应该应用于 map 的点击?

我更喜欢纯 CSS 的解决方案,但我可以接受基于 JS 的解决方案。

最佳答案

您可以从 .controlgroup 中删除 bottom:10px,这将使 controlgroup 的高度自动,因此它不会覆盖整个页面的高度,然后添加 max-height: calc(100% - 20px//从顶部和底部减少空间 10px + 10px );

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;
    max-height: calc(100% - 20px);
}

.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>

关于javascript - 防止绝对定位的 div 在不禁用滚动条的情况下吞噬点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48321532/

相关文章:

javascript - 如何在 vue.js 中不使用循环方法将类型数组对象更改为格式化对象?

javascript - 使用 JavaScript 启用被阻止的文本选择

html - 横向和纵向横向滚动网站布局的中心 Div

css - 使用 CSS 和 CoffeeScript 添加按钮

javascript - AngularJS - 将单击事件绑定(bind)到指令元素的子元素

javascript - 如何隐藏JWPlayer播放按钮?

javascript - 谷歌应用程序脚本: Illegally formed XML syntax

html - 防止表单输入类型 ="number"中的负输入?

android - html5 Android 应用程序上的谷歌导航

javascript - 网络套接字。互联网丢失、保持事件消息、应用程序架构等