ポインタイベント
シーン
会社のプロジェクトでそのようなシーンに遭遇しました。製品(アイコン、価格、その他の情報)があり、アイコンにカーソルを合わせると、詳細情報を表示するためのフローティングツールチップが表示されます。製品が無効になっている場合は、黒になりますマスクが上に覆われているため、現時点では選択できません。問題が発生します。アイコンにカーソルを合わせてツールチップを表示したいのですが、上に黒のマスクがあります。どうすればよいですか。する?
コードは次のとおりです(コードが長くなりすぎないように、一部のタグが削除されています)。
<style>
.container {
width: 500px;
height: 300px;
background: red;
position: relative;
}
.mask {
width: 100%;
height: 100%;
background: green;
position: absolute;
z-index: 2;
}
.content {
width: 500px;
height: 300px;
background: blue;
}
</style>
<body>
<div class="container">
<div class="mask"></div>
<p class="content">我是内容</p>
</div>
<script>
const mask = document.querySelector('.mask');
const container = document.querySelector('.container');
const content = document.querySelector('.content');
content.addEventListener('mouseenter', () => {
console.log('content mouseenter');
});
mask.addEventListener('mouseenter', () => {
console.log('mask mouseenter');
});
container.addEventListener('mouseenter', () => {
console.log('container mouseenter');
});
</script>
</body>
复制代码
ただし、その効果は、カーソルを合わせると、印刷順序が次のようになることです。
// container mouseenter
// mask mouseenter
复制代码
その時、考えてから、どうやってこの問題を解決するかを考え続けました。マスクがかかっていたのですが、上mouseenter
されて、content
からトリガーpointer-events
ポインタイベントとは何ですか?
Mdnでの定義を見てみましょう
ポインタイベントCSSプロパティは、特定のグラフィック要素がマウスイベントのトリガーになる可能性がある状況(存在する場合)を指定します。
それには多くの価値があります:
/* Global values */
pointer-events: inherit;
pointer-events: initial;
pointer-events: unset;
/* Keyword values */
pointer-events: auto;
pointer-events: none;
/* 以下的属性仅适用于SVG */
pointer-events: visiblePainted;
pointer-events: visibleFill;
pointer-events: visibleStroke;
pointer-events: visible;
pointer-events: painted;
pointer-events: fill;
pointer-events: stroke;
pointer-events: all;
复制代码
<div class='mask'>
上記の問題を解決するには、上記に1つ追加するだけで済みますpointer-events: none
。印刷順序を見てみましょう。
// container mouseenter
// content mouseenter
复制代码
pointer-events:none
なぜですか? Mdnドキュメントの説明を見てみましょう。
要素がマウスイベントのトリガーになることはありません。ただし、子孫要素のpointer-eventsプロパティが別の値を指定している場合、マウスイベントは子孫要素を指すことができます。その場合、マウスイベントは、キャプチャまたはバブリングフェーズ中に親要素のイベントリスナーをトリガーします。
したがって.mask
、上記にこの属性を追加しましたが、これはマウスイベントのトリガーにはならないため、マウスイベントのトリガーは正常になり.content
、この問題は正常に解決されました。
しかし、この定義はわかりますが、その子孫要素もこの属性を指定していて、それがnoneでない場合、マウスイベントは子孫要素を指すことができ、残りは省略されます...デモをもう一度書いてみましょう。
<style>
.mask-child {
width: 200px;
height: 300px;
background: yellow;
pointer-events: auto;
}
</style>
<body>
<div class="container">
<div class="mask">
<div class="mask-child"></div>
</div>
<p class="content">我是内容</p>
</div>
<script>
const maskChild = document.querySelector('.mask-child');
maskChild.addEventListener('mouseenter', () => {
console.log('maskChild mouseenter');
});
</script>
</body>
复制代码
.mask
この部分を今すぐコードに追加します。もう一度見てみましょう。子を追加し、.mask-child
そのイベントをリッスンしたことに注意してくださいmouseenter
。効果を見てみましょう。
// container mouseenter
// mask mouseenter
// maskChild mouseenter
复制代码
当然のことながら、トリガーされるのは同じmask
イベントであるmouseenter
ため、要素の指定されたイベントをスキップする場合は、そのイベントに設定できますが、その子孫は属性を再度pointer-events:none
指定しないように注意する必要があります。pointer-events
それ以外の場合は失敗します。
例
- マウスイベント(ドラッグ、ホバー、クリックなど)をトリガーしません。
<style>
button {
pointer-events: none;
}
</style>
<button onclick="handleClick()">测试</button>
<script>
function handleClick() {
console.log('handleClick');
}
</script>
复制代码
handleClickを出力しません。
- また、設定されている場合
:hover
、:active
疑似クラスはトリガーされません。
以前のようにhover
、無効にされた要素の効果をキャンセルしたい場合は、次のように書くことができます。
<p class="content disable"></p>
<style>
.content:not(disable):hover {
}
</style>
复制代码
そして今、私たちはそれをこのように書くことができます、それはもっと簡単ですか?
<p class="content disable"></p>
<style>
.content.disable {
pointer-events: none;
}
.content:hover {
}
</style>
复制代码
実際、cssの優先順位のために、以下に.disable
置くとます。
<p class="content disable"></p>
<style>
.content:hover {
background: black;
}
.content.disable {
background: yellow;
}
</style>
复制代码
要約する
上記はこの記事の全内容であり、私自身にとっては小さな記録です。お役に立てば幸いです。