允许子div在不影响父div的::before属性的情况下被点击。

huangapple go评论69阅读模式
英文:

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(&quot;puzzle3bg&quot;).style.setProperty(&#39;--cursorX&#39;, x + &#39;px&#39;)
document.getElementById(&quot;puzzle3bg&quot;).style.setProperty(&#39;--cursorY&#39;, y + &#39;px&#39;)
}
document.getElementById(&quot;puzzle3bg&quot;).addEventListener(&#39;mousemove&#39;, updateCursor)
document.getElementById(&quot;puzzle3bg&quot;).addEventListener(&#39;touchmove&#39;, updateCursor)
// I took this from someone else&#39;s codepen so I&#39;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: &quot;&quot;;
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 -->

&lt;div id=&quot;puzzle3&quot;&gt;
&lt;div id=&quot;puzzle3box&quot;&gt;
&lt;div class=&quot;p3correctCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3correctCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3correctCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3wrongCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3wrongCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3wrongCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3wrongCircle&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;p3wrongCircle&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;puzzle3bg&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- 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(&quot;puzzle3&quot;).addEventListener(&#39;mousemove&#39;, updateCursor)
document.getElementById(&quot;puzzle3&quot;).addEventListener(&#39;touchmove&#39;, 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.

huangapple
  • 本文由 发表于 2023年7月14日 08:59:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76684088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定