javascript - 获取相对于最近的相对父级的点击位置
问题描述
我想在用户点击的地方在一个较大的 div 中渲染一个小 div。我可以通过offsetX
从offsetY
. event
这工作正常,直到较大的 div 中有子 div。onclick
最外层 div 的事件侦听器触发,但event
属性随后相对于单击的子级而不是父级。
我在这里做了一个小例子
https://codepen.io/markgeeromano311/pen/rPppRV
您可以在单击左子项时看到它工作正常,因为它的 x 和 y 与父项位于同一点。但是,当您单击正确的孩子时,它显然会中断。
父母必须保持弹性盒,如果可以的话,我想避免将听众放在每个孩子身上作为修复。
谢谢!
document.getElementById('outer').addEventListener('click', renderCM)
function renderCM(e) {
const cm = document.getElementById('contextmenu')
console.log(e)
cm.style.left = e.offsetX + 'px'
cm.style.top = e.offsetY + 'px'
cm.style.display = 'block'
}
#outer {
width: 200px;
height: 200px;
background-color: red;
display: flex;
position: relative;
padding: 5px;
}
.inner {
width: 50%;
height: 100%;
background-color: blue;
border: 1px solid;
}
#contextmenu {
display: none;
width: 10px;
height: 10px;
position: absolute;
background-color: yellow;
}
#outermost {
height: 350px;
background-color: orange;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div id="outermost">
<div id="outer">
<div id="contextmenu"></div>
<div onclick=alert class="inner">
</div>
<div class="inner">
</div>
</div>
解决方案
是的,没有必要为孩子添加单独的事件监听器。您可以div
使用e.target.offsetLeft
and获得子项的相对偏移量e.target.offsetTop
,然后将其添加到e.offsetX
ande.offsetY
它应该为您提供正确的位置,而cm
不管 的数量是多少divs
:
document.getElementById('outer').addEventListener('click', renderCM)
function renderCM(e) {
const cm = document.getElementById('contextmenu')
cm.style.left = e.target.offsetLeft + e.offsetX + 'px'
cm.style.top = e.target.offsetTop + e.offsetY + 'px'
cm.style.display = 'block'
}
#outer {
width: 200px;
height:200px;
background-color: red;
display: flex;
position: relative;
padding: 5px;
}
.inner {
width: 50%;
height: 100%;
background-color: blue;
border: 1px solid;
}
#contextmenu {
display: none;
width: 10px;
height: 10px;
position: absolute;
background-color: yellow;
}
#outermost {
width: 350px;
height: 350px;
background-color: orange;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div id="outer">
<div id="contextmenu"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>
编辑:更好的解决方案:
function renderCM(e) {
const cm = document.getElementById('contextmenu')
cm.style.left = e.layerX + 'px'
cm.style.top = e.layerY + 'px'
cm.style.display = 'block'
}
感谢@Alok Singh 指出layerX
并layerY
推荐阅读
- angular - 在新选项卡中打开组件
- reactjs - 将应用程序部署到 Heroku 时,如何将对 localhost 的调用更改为外部 api 调用?
- nuget - VS 2019 Nuget - 项目参考
- javascript - Ionic 将 SVG 导出为图像,在 Android 上工作,在 IOS 上剪切图像
- javascript - Node.js molude.exports 返回:不是函数
- python - 使用 Python 和 Airflow 的 Postgres 复制命令
- javascript - How to drag a scaled element
- android - Running React Apollo website on Android device - the step with react-native is unclear
- php - Codeigniter 分页未正确过滤
- c# - Pass dynamic Type to Generic List