英文:
Allow child div to be clicked through a parent div without messing with the parent div's ::before property
问题
我有一个带有“手电筒”效果的蓝色不透明框,用于游戏中透过框查看。这个游戏涉及在框内寻找在“手电筒”区域内移动的圆圈。
我想要让“手电筒”效果能够正常工作,但允许点击事件穿过框(父级div)以触发与圆圈(子级div)相关的onclick事件。
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function updateCursor(e) {
var x = e.offsetX
var y = e.offsetY
document.getElementById("puzzle3bg").style.setProperty('--cursorX', x + 'px')
document.getElementById("puzzle3bg").style.setProperty('--cursorY', y + 'px')
}
document.getElementById("puzzle3bg").addEventListener('mousemove', updateCursor)
document.getElementById("puzzle3bg").addEventListener('touchmove', updateCursor)
// 我从别人的codepen中借用了这段代码,所以不确定如何修改它
<!-- language: lang-css -->
#puzzle3 {
display: inline-block;
text-align: center;
}
#puzzle3bg {
display: block;
width: 750px;
height: 750px;
--cursorX: 375px;
--cursorY: 375px;
}
#puzzle3bg::before {
content: "";
display: block;
width: 750px;
height: 750px;
position: relative;
background: radial-gradient(
circle 100px at var(--cursorX) var(--cursorY),
rgba(170,255,255,.3) 0%,
rgba(170,255,255,.6) 80%,
rgba(170,255,255,1) 100%
);
z-index: 10;
}
.p3correctCircle {
display: inline-block;
position: absolute;
background: #00FF00;
border-radius: 50%;
width: 50px;
height: 50px;
transition-duration: 600ms;
z-index: 0;
}
.p3wrongCircle {
display: inline-block;
position: absolute;
background: #FF0000;
border-radius: 50%;
width: 50px;
height: 50px;
transition-duration: 600ms;
z-index: 0;
}
<!-- language: lang-html -->
<div id="puzzle3">
<div id="puzzle3box">
<div class="p3correctCircle"></div>
<div class="p3correctCircle"></div>
<div class="p3correctCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
</div>
<div id="puzzle3bg"></div>
</div>
<!-- end snippet -->
每当我尝试使用pointer-event
的方法时,要么“手电筒”效果不起作用,要么子级div仍然无法工作。也许我一直都做错了,所以我会感激任何帮助。
英文:
I have this blue opaque box with a "flashlight" effect to see through the box for a game. The game involves looking for circles that move inside the box through a "flashlight" area.
I want to be able to have the "flashlight" effect work but allow clicks to pass through the box (parent div) in order to fire an onclick event with the circles (child divs).
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function updateCursor(e) {
var x = e.offsetX
var y = e.offsetY
document.getElementById("puzzle3bg").style.setProperty('--cursorX', x + 'px')
document.getElementById("puzzle3bg").style.setProperty('--cursorY', y + 'px')
}
document.getElementById("puzzle3bg").addEventListener('mousemove', updateCursor)
document.getElementById("puzzle3bg").addEventListener('touchmove', updateCursor)
// I took this from someone else's codepen so I'm not sure how to modify it
<!-- language: lang-css -->
#puzzle3 {
display: inline-block;
text-align: center;
}
#puzzle3bg {
display: block;
width: 750px;
height: 750px;
--cursorX: 375px;
--cursorY: 375px;
}
#puzzle3bg::before {
content: "";
display: block;
width: 750px;
height: 750px;
position: relative;
background: radial-gradient(
circle 100px at var(--cursorX) var(--cursorY),
rgba(170,255,255,.3) 0%,
rgba(170,255,255,.6) 80%,
rgba(170,255,255,1) 100%
);
z-index: 10;
}
.p3correctCircle {
display: inline-block;
position: absolute;
background: #00FF00;
border-radius: 50%;
width: 50px;
height: 50px;
transition-duration: 600ms;
z-index: 0;
}
.p3wrongCircle {
display: inline-block;
position: absolute;
background: #FF0000;
border-radius: 50%;
width: 50px;
height: 50px;
transition-duration: 600ms;
z-index: 0;
}
<!-- language: lang-html -->
<div id="puzzle3">
<div id="puzzle3box">
<div class="p3correctCircle"></div>
<div class="p3correctCircle"></div>
<div class="p3correctCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
<div class="p3wrongCircle"></div>
</div>
<div id="puzzle3bg"></div>
</div>
<!-- end snippet -->
Whenever I try the pointer-event stuff, either the "flashlight" effect doesn't work or the child divs are still not working. But maybe I've been doing it wrong, so I'd appreciate any help.
答案1
得分: 0
正如您提到的,pointer-events: none
会导致一切都无法正常工作,这是因为您的手电筒只有在鼠标移动到手电筒本身上时才会跟随光标。这意味着手电筒位于所有其他元素之上,阻止您点击它们。
您可以通过在手电筒元素上禁用 pointer-events
来缓解这个问题:
#puzzle3bg {
display: block;
width: 750px;
height: 750px;
--cursorX: 375px;
--cursorY: 375px;
pointer-events: none; // 禁用所有点击功能
}
并且监听可点击的父元素 #puzzle3
上的 mousemove
/touchmove
事件:
document.getElementById("puzzle3").addEventListener('mousemove', updateCursor)
document.getElementById("puzzle3").addEventListener('touchmove', updateCursor)
这样,您将能够通过手电筒点击目标圆圈,而手电筒将在鼠标后面移动,因为它的位置是在启用了 pointer-events
的元素上跟踪的。
英文:
As you mentioned, pointer-events: none
breaks everything, that's because your flashlight follows the cursor only when you move your mouse over the flashlight itself. Meaning the flashlight is on top of all other elements and blocks you from clicking them.
You can mitigate that by disabling pointer-events
on your flashlight element:
#puzzle3bg {
display: block;
width: 750px;
height: 750px;
--cursorX: 375px;
--cursorY: 375px;
pointer-events: none; // Disables all click functionality
}
AND listening to mousemove
/touchmove
events on an element that is clickable, like the parent element #puzzle3
:
document.getElementById("puzzle3").addEventListener('mousemove', updateCursor)
document.getElementById("puzzle3").addEventListener('touchmove', updateCursor)
That way you will be able to click the target circles through the flashlight, and the flashlight will move after your mouse because it's position is tracked on an element that has pointer-events
enabled.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论