http://oshiete.goo.ne.jp/qa/6681276.html
に関連しますが
divの中に、p、ulが同列にあり
div領域からmouseoutしたらイベントが起きるようにしたいと思っています。
イベントは親要素に伝播するということなので
event.cancelBubble = true;
window.event.cancelBubble=true;
をp,ulのイベントに入れました。
又、各要素のマウス状態の履歴をテーブルに残してみました(下にソース)。
(マウスアウトしたら「x」、オーバーで「o」)
その結果、
バブリング防止策を講じたため
pまたはulのマウスアウトはdivに伝わっていません(ただしFirefoxではダメ?)。
ところがよく見ると
div→p
div→ul
と移動する際、div内ではありますが
divは一旦マウスアウトしてから再びマウスオーバーとなっているようです。
まず、ここまでの理解は間違っていないでしょうか?
そして、境界線をまたぐ際、マウスアウトになるのはどうにもならないのでしょうか?
基本的な質問で申し訳ありませんが、よろしくお願いします。
---------------------------------------------------------------------------------------------
<script style="text/javascript">
function divOn() {
document.getElementById('atDiv').innerHTML=document.getElementById('atDiv').innerHTML+'o';
}
function divOff() {
document.getElementById('atDiv').innerHTML=document.getElementById('atDiv').innerHTML+'x';
}
function pOn() {
document.getElementById('atP').innerHTML=document.getElementById('atP').innerHTML+'o';
}
function pOff() {
document.getElementById('atP').innerHTML=document.getElementById('atP').innerHTML+'x';
}
function ulOn() {
document.getElementById('atUl').innerHTML=document.getElementById('atUl').innerHTML+'o';
}
function ulOff() {
document.getElementById('atUl').innerHTML=document.getElementById('atUl').innerHTML+'x';
}
function stopBubbling() {
event.cancelBubble=true;
stopPropagation=true;
}
</script>
<div onMouseover="divOn();" onMouseout="divOff();" style="background:#fee;padding:1em;height:300px;">div
<p onMouseover="pOn();" onMouseout="stopBubbling();pOff();" style="background:#efe;height:100px;">p</p>
<ul onMouseover="ulOn();" onMouseout="stopBubbling();ulOff();" style=";background:#eef;height:100px;">
<li><a>li</a></li>
<li><a>li</a></li>
</ul>
</div>
<table border="1">
<thead>
<tr>
<th>div</th>
<th>p</th>
<th>ul</th>
</tr>
</thead>
<tbody>
<tr>
<td id="atDiv"><br /></td>
<td id="atP"><br/></td>
<td id="atUl"><br/></td>
</tr>
</tbody>
</table>
No.4ベストアンサー
- 回答日時:
バブリング(イベントフロー)を勝手に止めてはいけません。
かつ、イベントフローを停止する正規の手段は event.stopPropagation() であり、event.cancelBubble は(もともと)IE の独自仕様です。マウスオーバーとマウスアウトは、どちらをイベントの発生源とするかという視点の違いに過ぎず、本質的に同じイベントです。
・event.target でマウスオーバーが生じたら、event.relatedTarget にはマウスアウトした要素がセットされる
・event.target でマウスアウトが生じたら、event.relatedTarget にはマウスオーバーした要素がセットされる
・IE8 以下の場合、event.fromElement にマウスアウトした要素、event.toElement にマウスオーバーした要素がセットされる
したがって、どちらか一方を document で監視すれば事足りるのです。
// document で mouseover を監視すれば
function onMouseOver (event) {
// document 内で生じる mouseover と mouseout の両方を全て感知できる
var over = event.target || event.toElement;
var out = event.relatedTarget || event.fromElement;
var tmp;
if (out) {
// ただしウィンドウ外へ出ていった場合は感知できない
for (tmp = out; tmp; tmp = tmp.parentNode) {
if (tmp.id === 'aDiv') break;
}
if (tmp) {
// #aDiv の外に出ていった
}
}
for (tmp = over; tmp; tmp = tmp.parentNode) {
if (tmp.id === 'aDiv') break;
}
if (tmp) {
// #aDiv の中に入った
}
// Selectors API2 を使えばもう少し分かりやすいが割愛
}
もし、どうしても div 自体に onmouseout 属性を書いて「div から出ていった」ことを感知したい場合は、マウスの行き先(mouseout なら event.relatedTarget または event.toElement で分かる)が、div の中にないことをテストすれば良い。この辺は Dreamweaver の吐き出すコードでも昔からやっていることです。
<div onmouseout="
if (mouseIsOutside.call(this, event)) {
// div から出ていった
}
">...</div>
function mouseIsOutside (event) {
var r;
var c;
try { // DOM3 Core (Firefox, Opera10, Safari4)
c = event.currentTarget;
r = event.relatedTarget;
return ! r || ! r.isSameNode(c) && 0 === (r.compareDocumentPosition(c) & Node.DOCUMENT_POSITION_CONTAINS);
}
catch (err) {
try { // MSHMTL (IE, Opera9)
c = this;
r = event.toElement || event.relatedTarget;
return ! r || c !== r && ! c.contains(r);
}
catch (err) { // DOM1 Core (Safari3)
c = event.currentTarget;
r = event.relatedTarget;
while ((r = r.parentNode)) if (r === c) break;
return ! r;
}
}
}
バブリングしない mouseenter、mouseleave(IE 由来で DOM3 Events に収録予定)を使っても良いのですが、いずれにせよバブリングを使えるなら document で一括監視でき、load やノードの挿入を監視してイベントハンドラを付け足す……のような変な作業をせずに済みます。
No.3
- 回答日時:
すみません、訂正します。
>onmouseoutのかわりに、onmouseleaveというフックがあります。
フックではなくハンドラです。
(フックは別の言語、APIの呼び方でした)
No.2
- 回答日時:
>まず、ここまでの理解は間違っていないでしょうか?
その通りです。
ツールチップやプルダウンメニューなどを表示・非表示させる場合によくある問題です。
>そして、境界線をまたぐ際、マウスアウトになるのはどうにもならないのでしょうか?
その問題に対応するために、
onmouseoutのかわりに、onmouseleaveというフックがあります。
onmouseleaveに対応していないブラウザでは、
私はevent.target、event.srcElementからparentNodeを調べていき、
onmouseoutをセットした要素と同じ物があればmouseoutしていないという判断、
同じ要素がなければ完全に外に出たとして、mouseout処理を続行
としています。
内側の要素でさらにonmouseoverやonmouseoutイベントを処理している場合で、イベントバブルを停止させている場合は、
target|srcElementがうまく取得できないこともあるので、
タイマーを使って1ミリ秒後にカーソルの位置を判断する、という方法をよく使っています。
No.1
- 回答日時:
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- JavaScript javascriptでテーブルに追加した項目のid追加してローカルストレージを操作したい 5 2023/01/01 15:52
- HTML・CSS アコーディオンメニューが思うように動作しません。 1 2023/08/20 16:48
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- HTML・CSS HTML & CSS 縦ボックス内の文字の左右センタリング 3 2023/03/25 04:23
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- HTML・CSS html/cssで要素が出てこなくて困ってます 1 2022/12/31 16:59
- JavaScript html5に変えるとスライドショーが消えてしまった。 3 2022/03/26 19:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
HTML:Tableタグに対し、JavaScr...
-
フォーカス移動のタイミング
-
innerHTML実行後のイベント
-
リンクボタンからインラインフ...
-
javascript の 命令文の記述で...
-
[初心者]javascriptのfor文でな...
-
Click回数を数え、規定された回...
-
javascript 特定のタグのidの存...
-
日本語入力の禁止
-
jQueryのload()を使用して外部...
-
google apps scriptの終了のさせ方
-
C#OpenCv V4にのエラーに関する...
-
idを使わずにonclickで自身の要...
-
Linux バイナリ実行できない "...
-
JavaScript window.openで開く...
-
Javaで避けるゲームを作ってい...
-
クリックすると上に開くアコー...
-
【JavaScript】数当てゲームを...
-
C#で、ContextMenuStripに動的...
-
URLの一部をコピーできるブック...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<a>タグのテキストを取得
-
ActiveXobjectが作成できない
-
onchangeイベントを使ってspan...
-
HTML:Tableタグに対し、JavaScr...
-
任意の座標をクリックさせるには
-
モーダルダイアログウィンドウ...
-
innerHTML実行後のイベント
-
Click回数を数え、規定された回...
-
javascript 特定のタグのidの存...
-
[初心者]javascriptのfor文でな...
-
【Tabキー】特定の範囲内だけで...
-
javascriptでスロットゲームを...
-
JavaScriptとcookieを利用して...
-
日本語入力の禁止
-
javascriptで、表示されている...
-
javascriptで編集可能不可能の...
-
画像の一部を表示
-
DIV内のDIV要素を移動する。
-
javascript の 命令文の記述で...
-
重複しないくじの作り方がわか...
おすすめ情報