第三に、JavaScriptイベントモデル



第三章JavaScriptイベントモデル
一、事件の概要(原理、説明は標準ではない):
(一)キーボード、マウスなどの周辺機器にイベントが発生した場合、電気信号をホストに転送する
(二)OSが駆動によりイベントを取得する
(3)各種アプリケーション(JVM、ブラウザ)はOSにフック(hook)が存在し、イベントはフックを通じてアプリケーションに伝達される
(四)アプリケーション内部でイベントをeventオブジェクトにカプセル化し、対応する操作を実行する
 
二、JavaScriptでイベント傍受を確立する手順:
(一)イベントをカプセル化する(このステップはアプリケーションが完了した)
(二)イベントソースを探す
(三)傍受者に通知する
 
三、イベントフロー(連座類似)
(一)イベントキャプチャ(イベントソースを探し、外部から内部へ):この段階IEはない
(二)イベントバブル(すなわち、イベントの伝達、内から外へ)
コード:(FF中運転、IE非サポート)
<style type="text/css">
#outer{
width:200px;
height:200px;
background:red;
}
#inner{
margin-left:300px;
width:100px;
height:100px;
background:green;
}
</style>
<div id="outer">
<div id="inner"></div>
</div>
<script type="text/javascript">
function out(){
alert("outer");
}
function inn(){
alert("inner");
}
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
inner.addEventListener("click",inn,true);
outer.addEventListener("click",out,true);
</script>
 
 
上記のコードはinner divをクリックすると、まずouterをポップアップしてからinnerをポップアップします.リスニングを追加するとき、DOMリスニング方式を使用します.リスニング段階はキャプチャ段階(外から内)であり、同時にイベントフローは連座方式で、innerをクリックして、トリガ順序は外から内までイベントソースを探して、先にouterを見つけてinnerを見つけます.
 
四、イベント傍受の割り当て方法
(一)従来のイベントハンドラ割り当て方法(欠陥:同じイベントソースで1つのリスナーしかサポートできない)
1.動的バインディング(すなわちJSにおけるバインディング傍受)
function msg(){alert("yes")} document.getElementById("test").onclick = msg;
 
ここでonclick=msgはmsg()を使用できません.msgは関数ポインタがこの関数を指すため、イベントが発生したときにこの関数を実行します.msg()は実行結果を表し、解釈器はこの行を実行するとalertを実行します.
2.静的バインディング(HTMLコード要素でのバインディングリスニング)
<input id="test" type="button" onclick="msg()"/>
 
ここでのonclick="msg()はdocumentに等しい.getElementById("test").onclick  =  function(){msg()};
したがって、動的バインドと静的バインドのthisオブジェクトは異なります.次のコードを参照してください.
function msg(){ 
var t = document.getElementById("test");
alert(this===t);//  true
} 
document.getElementById("test").onclick = msg;
function msg(){ 
alert(this===window);//  true
} 
<input id="test" type="button" onclick="msg()"/>
 
3.動的バインドの場合は、XHTML要素がDOMに追加される前に
1)windowを使用できます.onload
window.onload = function(){
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
outer.onclick = out;
inner.onclick = inn;
};
 
2)バインドスクリプトをオブジェクト要素の後に配置
 
(二)現代イベントハンドラの割り当て方法
1.IEブラウザ
Object.attachEvent(「イベントハンドラ名(onclick)」、関数ポインタ);//追加
Object.detachEvent(「イベントハンドラ名(onclick)」、関数ポインタ);//削除
2.DOMブラウザシリーズ
Object.addEventListener(「イベント名(click)」、関数名、フェーズ(trueはキャプチャフェーズ、falseはバブルフェーズ);
Object.removeEventListener(「イベント名(click)」、関数名、フェーズ(trueはキャプチャフェーズ、falseはバブルフェーズ);
 
五、戻り値
<form id="form" method="get" accept="#" onsubmit="return tt()">
<input id="name" name="name" type="text" />
<input type="submit"/>
</form>
<script type="text/javascript">
function tt(){
var name = document.getElementById("name");
if(name.value.length<6){
alert("wrong");
return false;
}
}
</script>
 
上記のコード:onsubmit=「returntt()」はonsubmit=function(){returntt()}に等価である.
六、eventオブジェクトの難点:keydownは押すキーを表し、keypressは入力した値を表してaを入力する場合は下表を見てください
keyCode
charCode
IE
keydown
65
x
keypress
97
x
FF
keydown
65
0
keypress
0
97
<input id="name" name="name" type="text" onkeypress="return tt(event)"/>
<script type="text/javascript">
function tt(e){
var name = document.getElementById("name");
if(window.event){//IE
var key = window.event.keyCode;
}else{
var key = e.charCode;
}
if(key==65||key==97){return false;}//   a  A          
}
</script>
 
七、実例
divをドラッグします.
この動作を分解します:onmousedown、onmousemove、onmouseup
<style type="text/css">
#block {
width: 100px;
height: 100px;
background-color: Red;
}
</style>
</head>
<body>
<div id="block" style="position:absolute;left:0px;top:0px;" onmousedown="beginDrag(event);"
 onmousemove="drag(event);" onmouseup="endDrag();" onmouseout="dragable=false;"></div>
<script type="text/javascript">
var dragable = false;
var div = document.getElementById("block");
var tmpX;
var tmpY;
function beginDrag(e){
dragable = true;
if(!e) e = window.event;
var mX = e.clientX;
var mY = e.clientY;
var x = parseInt(div.style.left);
var y = parseInt(div.style.top);
tmpX = mX - x;
tmpY = mY - y;
}
function drag(e){
if(dragable){
if(!e) e = window.event;
var mX = e.clientX;
var mY = e.clientY;
div.style.left = (mX - tmpX) + "px";
div.style.top = (mY - tmpY) + "px";
}
}
function endDrag(){dragable = false;}
</script>