質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

421閲覧

mouseenterイベントの際、子要素にもイベントがキャプチャリングされてしまう

kss

総合スコア9

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2023/01/30 12:06

編集2023/01/30 12:54

前提

mouseenterイベントの際に、ターゲットの子要素にカーソルが入った際イベントが発生してしまう。

実現したいこと

カーソルを合わせた際にターゲット要素のみイベントを発生させ、子要素にイベントを伝えないようにしたいです。

発生している問題・エラーメッセージ

.itemにカーソルを合わせたときにその子要素の.menuを表示させることは実現できたのですが、.item1にカーソルを合わせ、その子要素の.pにカーソルを入れると.menuが閉じてしまう。

該当のソースコード

html

1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <title>Document</title> 9 <style> 10 * { 11 box-sizing: border-box; 12 margin: 0; 13 padding: 0; 14 } 15 16 body { 17 width: 100%; 18 height: 100vh; 19 } 20 21 nav { 22 position: relative; 23 background-color: gray; 24 height: 4em; 25 } 26 27 ul { 28 display: flex; 29 flex-direction: row; 30 justify-content: center; 31 align-items: center; 32 gap: 50px; 33 height: 100%; 34 } 35 36 li { 37 list-style: none; 38 border: 2px solid #000; 39 padding-inline: 2em; 40 cursor: pointer; 41 height: 100%; 42 43 } 44 45 li p { 46 background-color: blue; 47 } 48 49 50 .menu { 51 position: absolute; 52 top: 4em; 53 left: 0; 54 width: 100vw; 55 height: 0; 56 opacity: 0; 57 background-color: #ebebeb; 58 animation-name: kf-menu-reverse; 59 animation-duration: 1s; 60 animation-fill-mode: forwards; 61 background-color: red; 62 } 63 64 li.active .menu { 65 animation-name: kf-menu; 66 animation-duration: 1s; 67 animation-fill-mode: forwards; 68 } 69 70 @keyframes kf-menu { 71 0% { 72 height: 0; 73 opacity: 0; 74 } 75 76 100% { 77 height: 400px; 78 opacity: 1; 79 } 80 } 81 82 @keyframes kf-menu-reverse { 83 0% { 84 height: 400px; 85 opacity: 1; 86 } 87 88 100% { 89 height: 0; 90 opacity: 0; 91 } 92 93 } 94 </style> 95</head> 96 97<body class="body"> 98 <header class="header"> 99 <h1 class="title">Title</h1> 100 <nav class="nav"> 101 <ul class="ul"> 102 <li class="item item1">item 103 <div class="menu">menu1</div> 104 <p class="p">ここはpです</p> 105 </li> 106 <li class="item item2">item <div class="menu">menu2</div> 107 </li> 108 <li class="item item3">item <div class="menu">menu3</div> 109 </li> 110 <li class="item item4">item <div class="menu">menu4</div> 111 </li> 112 <li class="item item5">item <div class="menu">menu5</div> 113 </li> 114 <li class="item item6">item <div class="menu">menu6</div> 115 </li> 116 </ul> 117 </nav> 118 </header> 119</body> 120<script> 121 class Menu { 122 constructor() { 123 this.items = document.querySelectorAll('.item') 124 this.excludes = document.querySelectorAll('nav *:not(.item)') 125 this._init() 126 } 127 _init() { 128 this.items.forEach(item => { 129 item.addEventListener( 130 'mouseenter', () => { 131 this.items.forEach(item => { 132 item.classList.remove('active') 133 }) 134 item.classList.add('active') 135 } 136 ) 137 window.addEventListener('mousemove', (e) => { 138 if (!e.target.className.includes('item') && !e.target.className.includes('menu') && !e.target.className.includes('nav')) { 139 item.classList.remove('active') 140 } 141 }) 142 }) 143 } 144 } 145 new Menu() 146</script> 147 148</html>

試したこと

イベントをmouseoutに変更するも効果なし。
addEventListenerの第三引数をfalseにしても特に変わりはありませんでした。

_initメソッドの2つ目のイベントリスナーをを下記のように書きかえたら想定通り機能しました。

html

1window.addEventListener('mousemove', (e) => { 2 if (!e.target.className.includes('item') && !e.target.className.includes('menu') && !e.target.className.includes('nav') && !e.target.parentElement.className.includes('item')) { 3 item.classList.remove('active') 4 } 5 })

ただしこちらはif文がかなり冗長になってしまいます。

かなり初歩的な質問で大変恐縮ですが、お力をお貸しいただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

javascript

1window.addEventListener('mousemove', e=> { 2 const item=e.target.closest('.item'); 3 if(item==null){ 4 document.querySelector('.item.active').classList.remove('active'); 5 }else{ 6 item.classList.add('active'); 7 } 8}) 9

投稿2023/01/30 13:42

yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問