我想在用户点击的位置在较大的div内渲染一个较小的div。我可以通过从offsetX
获取offsetY
和event
来做到这一点。这很好,直到较大的div内有子div。 onclick
事件监听器会触发最外部的div,但是event
属性是相对于单击的子项而不是父项而言的。
我在这里做了一个小例子
https://codepen.io/markgeeromano311/pen/rPppRV
单击左子项时,您可以看到它工作正常,因为其x和y与父项在同一点。但是,当您单击正确的孩子时,它显然会破裂。
父母必须留一个Flexbox,如果可以的话,我想避免在每个孩子身上放置听众作为解决方法。
谢谢!
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>
答案 0 :(得分:1)
是的,没有必要向孩子添加单个事件侦听器。您可以使用div
和e.target.offsetLeft
来获得子e.target.offsetTop
的相对偏移,然后将其添加到e.offsetX
和e.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