イベントは一般的にブラウザとユーザー操作の間のインタラクションに使用されます。ユーザーが特定の操作を実行すると、ブラウザが反応し、バインドされたイベントをトリガーします。イベントフロー
では、イベントが発生すると、要素ノードとルートノードの間で合意された順序で伝播します。イベントが通過するすべてのノードはイベントの影響を受け、この伝播プロセスは DOM イベントフローと呼ばれます。
関数イベント#
イベントは一般的にブラウザとユーザー操作の間のインタラクションに使用されます。ユーザーが特定の操作を実行すると、ブラウザが反応し、バインドされたイベントをトリガーします。
イベントフロー
では、イベントが発生すると、要素ノードとルートノードの間で合意された順序で伝播します。イベントが通過するすべてのノードはイベントの影響を受け、この伝播プロセスは DOM イベントフローと呼ばれます。
true はキャプチャ、false はバブリングで、デフォルトはバブリングイベントです。
1.addEventListener ()--イベントリスナー関数の追加#
要素にイベントを追加します。複数のイベントがある場合、上書きされず、順に実行されます。
<div id="demo">dom</div>
<script>
document.getElementById('demo').addEventListener("click", myfun)
document.getElementById('demo').addEventListener("click", myfun1)
function myfun() {
console.log('イベントリスナー関数')
}
function myfun1() {
console.log('addEventListener')
}
</script>
注意:
1. ここには一つの細部があります。addEventListener () には二つのパラメータがあり、最初はトリガー条件を示し、二つ目はトリガーイベントを示します。
通常、二つ目のパラメータには関数名をそのまま書き、パラメータ()
を付けません。もし()
を付けると、即座に実行され、最初のパラメータが要求する条件をトリガーする必要がありません。
2. ここでイベントをバインドする際、イベント名は定義された変数名と同じにしてはいけません。そうしないと無効になります。
2.removeEventListener ()--イベントリスナー関数の削除#
以下のデモでは、マウスが div 内を移動するとランダムな数が表示され、ボタンをクリックするとイベントリスナー関数が削除されます。
<!-- css -->
<style>
#demo {
width: 100px;
height: 100px;
border: 1px solid #000;
}
</style>
<!-- html -->
<div id="demo"></div>
<input type="button" value="クリックして削除" onclick="remove()">
<div id="show"></div>
<!-- js -->
<script>
document.getElementById('demo').addEventListener("mousemove", myfun)
function myfun() {
document.getElementById('show').innerHTML = Math.random()
}
function remove() {
document.getElementById('demo').removeEventListener("mousemove", myfun)
}
</script>
3. イベントのキャプチャとバブリングを利用して何かをする#
addEventListener () と removeEventListener () は実際には三つのパラメータを持っています。最初はトリガー条件を示し、二つ目はトリガーイベント、三つ目のパラメータは通常省略できますが、その意味を理解しておく必要があります。
ブール値で表現され、true または false で、デフォルトは false です。
- true はキャプチャ段階でイベントハンドラを呼び出すことを示します。
- false はバブリング段階でイベントハンドラを呼び出すことを示します。
画像からわかるように、キャプチャ段階はバブリング段階よりも先に行われるため、true イベントは false イベントよりも先にトリガーされます。複数の true イベントは順にトリガーされ、複数の false イベントは後に書かれたものが先にトリガーされます。
結論:前に書かれた true イベント > 後に書かれた true イベント > 後に書かれた false イベント > 前に書かれた false イベント
したがって、このパラメータを利用して、同じ要素の異なるイベントのトリガー順序を制御できます。
<div id="out">
<p>最外層</p>
<div id="middle">
<div id="inner">最内層</div>
</div>
</div>
<!-- 第一のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:inner-------middle------out
out.addEventListener('click',function(){alert("私は最外層です");},false);
middle.addEventListener('click',function(){alert("私は中間層です");},false);
inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>
<!-- 第二のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:out------middle-------inner
out.addEventListener('click',function(){alert("私は最外層です");},true);
middle.addEventListener('click',function(){alert("私は中間層です");},true);
inner.addEventListener('click',function(){alert("私は最内層です");},true);
</script>
<!-- 第三のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:out------inner-------middle
out.addEventListener('click',function(){alert("私は最外層です");},true);
middle.addEventListener('click',function(){alert("私は中間層です");},false);
inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>
<!-- 第四のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:out-------middle------inner
out.addEventListener('click',function(){alert("私は最外層です");},true);
middle.addEventListener('click',function(){alert("私は中間層です");},true);
inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>
<!-- 第五のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:middle-------inner------out
out.addEventListener('click',function(){alert("私は最外層です");},false);
middle.addEventListener('click',function(){alert("私は中間層です");},true);
inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>
<!-- 第六のケース -->
<script>
var out = document.getElementById('out');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
//innerをクリックすると、トリガー順序は:out-------inner------middle
out.addEventListener('click',function(){alert("私は最外層です");},true);
middle.addEventListener('click',function(){alert("私は中間層です");},false);
inner.addEventListener('click',function(){alert("私は最内層です");},true);
</script>
4. イベントハンドラ#
- HTML イベントハンドラ
<button onclick="test()">テスト</button>
<script>
function test() {
alert("HTMLイベントハンドラ");
}
</script>
1. 利点:イベントハンドラ内のコードは、グローバルスコープ内の任意の変数にアクセスできます。
2. 欠点:時差問題、拡張されたスコープチェーンが異なるブラウザで異なる結果を引き起こす可能性、html コードと js コードの高度な結合。
- DOM0 レベルイベントハンドラ
<button id="btn">テスト</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function test() {
alert("DOM0レベルイベントハンドラ");
}
</script>
1. 利点:コードがシンプルで、ブラウザの互換性が良く、html コードと js コードの高度な結合の問題を解決します。
2. 欠点:一つの要素には一つのイベントハンドラしかバインドできず、イベントバブリング中にのみ実行されます。
- DOM2 レベルイベントハンドラ
このレベルのイベントハンドラは、イベントキャプチャとバブリングメカニズムを利用しています。
<button id="btn">テスト</button>
<script>
var btn = document.getElementById("btn");
// イベントリスニング
btn.addEventListener("click", function() {
alert("DOM2レベルイベントハンドラ、私はキャプチャ段階で実行されます");
}, true);
btn.addEventListener("click", function() {
alert("DOM2レベルイベントハンドラ、私はバブリング段階で実行されます");
}, false);
// イベントリスナーの削除
var fun = function() {
alert("私は削除されます");
}
btn.addEventListener("click", fun, false);
btn.removeEventListener("click", fun, false);
</script>
1. 利点:イベント処理のキャプチャとバブリング段階の両方を同時にサポートし、一つの要素に複数の処理関数をバインドできます。
2. 欠点:IE はサポートしていません。