ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript DOM イベントのグラフィック コードの詳細な紹介

JavaScript DOM イベントのグラフィック コードの詳細な紹介

黄舟
黄舟オリジナル
2017-03-04 15:40:011189ブラウズ

イベント は、クリック、ダブルクリック、マウスホバーなど、ドキュメントまたはブラウザウィンドウで発生する特定のインタラクティブな瞬間です。

イベント フロー

イベント フローは、ページからイベントを受信する順序、またはページ内でイベントが伝播される順序を記述します。

  • IE のイベント フローは

    イベント バブリング と呼ばれます。イベントは最も具体的な要素から開始して実行され、段階的にウィンドウ オブジェクトまで伝播されます。

  • Netscape チームによって提案されたイベント フローは、

    イベント キャプチャ と呼ばれます。イベントは最も外側のウィンドウ オブジェクトから実行され始め、その後、最も具体的な要素まで徐々に下方に伝播します。

これら 2 つのイベント ストリームの違いを説明するために、小さな実験を行ってみましょう:

// html 文档
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件流 实验</title>
</head>
<body>
  <p id="test" style="font-size:3em;">点我点我,我是p</p>
</body>
</html>
// 事件冒泡
var p = document.getElementById("test");
p.addEventListener("click",function(){
  console.log("i am p");
}, false);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, false);
document.addEventListener("click",function(){
  console.log("i am document");
}, false);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);

JavaScript DOM イベントのグラフィック コードの詳細な紹介

点击p,控制端会打印如下:
i am p
i am body
i am html
i am document
i am window
// 事件捕获
var p = document.getElementById("test");
p.addEventListener("click",function(){
  console.log("i am p");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, true);
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, true);

JavaScript DOM イベントのグラフィック コードの詳細な紹介

写真は 2 回処理されており、少し見苦しいですが、ご容赦ください。

点击p,控制端会打印如下:
i am window
i am document
i am html
i am body
i am p

イベントバブリングとイベントキャプチャは、2つの完全に反対のイベントフローであることがわかります。

通常、イベントバブリングは一般的に使用され、イベントキャプチャは特別な状況でのみ使用されます。

DOM レベル 2 イベントによって指定されるイベント フローには、イベント キャプチャ ステージ、ターゲット ステージ、イベント バブリング ステージの 3 つのステージが含まれます。

// 事件冒泡和事件捕获混合一下
var p = document.getElementById("test");
p.addEventListener("click",function(){
  console.log("i am p");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);    // 改为在冒泡阶段调用事件处理程序
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);    // 改为在冒泡阶段调用事件处理程序

この写真は本から直接抜粋したものです。自分で考えてウィンドウ オブジェクトを追加してください。

JavaScript DOM イベントのグラフィック コードの詳細な紹介

点击p,控制端会打印如下:
i am document
i am html
i am p
i am body
i am window

イベントハンドラー

イベントハンドラー: 特定のイベントに応答する関数を指します

HTMLイベントハンドラー

要素によってサポートされるイベントごとに、HTML属性を指定する1つを使用できます対応するイベント ハンドラーと同じ名前が付けられます。

// 情况一
<button onclick="alert(&#39;I am button!&#39;);">按钮</button>
// 情况二
<button onclick="show();">按钮</button>
<script>
function show(){
  alert("I am button!");
}
</script>

このメソッドは、要素にイベントを追加するために決して使用しないことをお勧めします。このメソッドには、HTML コードと JavaScript コードが密接に結合され、動作と構造の分離に準拠していないという大きな欠点があるためです。ウェブデザイン。

DOM0 レベルのイベント ハンドラー

すべての要素 (ウィンドウやドキュメントを含む) には、onclick、onmouseup などの独自のイベント ハンドラー プロパティ があります。

上記のコードを次のように書き換えます:

<button id="test">按钮</button>
var button = document.getElementById("test");
button.onclick = function(){
  // this 对象指向 button 元素
  console.log(this);
  alert("I am button!");
};
/*  删除指定的事件处理程序  */
button.onclick = null;

DOM2 レベルのイベント ハンドラー

DOM2 レベルのイベント は、イベント ハンドラーの指定と削除の操作を処理する 2 つのメソッド: addEventListener()removeEventListener()

どちらのメソッドにも 3 つのパラメーターがあります。最初のパラメーターはイベント名、2 番目のパラメーターはイベント ハンドラーとしての関数、3 番目のパラメーターはブール値で、バブリング段階にあることを示します。イベント ハンドラーを呼び出します。この値が true の場合、イベント ハンドラーがキャプチャ フェーズ中に呼び出されることを意味します。

引き続き上記のコードを書き直します:

var button = document.getElementById("test");
function show(){
  // this 对象指向 button 元素
  console.log(this);
  alert("I am button!");
}
// 添加事件处理程序
button.addEventListener("click",show, false);
button.addEventListener("click",function(){
  alert("I am second alert!");
},false);
// 删除事件处理程序
button.removeEventListener("click",show, false); // 删除成功
button.removeEventListener("click",function(){   // 删除失败
  alert("I am second alert!");
},false);

DOM2 レベルのメソッドを使用してイベント ハンドラーを追加する主な利点は、1 つの要素に複数のイベント ハンドラーを追加できることです。

addEventListener()で追加したイベントハンドラが匿名関数の場合、このイベントハンドラはremoveEventListener()で削除できません。

IE イベント ハンドラー

IE8 およびそれ以前の IE バージョンは、イベント バブリングのみをサポートし、addEventListener() および RemoveEventListener() をサポートしませんが、これら 2 つのメソッドに似た 2 つのメソッド:

attachEvent() および detachEvent を実装します。 ()。これら 2 つのメソッドには、イベント名 (onclick、not click) とイベント処理関数の 2 つのパラメータしかありません。

addEventListener() とは異なり、attachEvent() メソッドを使用する場合、イベント処理関数はグローバル スコープで実行されるため、これは window と同等となり、特別な注意が必要です。

var button = document.getElementById("test");
button.attachEvent("onclick", function(){
  // this 对象指向了全局作用域,即 window
  console.log(this);
  alert("I am button!");
});
button.attachEvent("onclick",function(){
  alert("I am second alert!");
}); 
// 上面也是为同一个按钮绑定了两个事件处理程序
button.detachEvent("onclick",function(){ // 删除失败
  alert("I am second alert!");
});

プログラムを IE8 ブラウザと互換性を持たせたくない場合は、これら 2 つの関数を使用しないでください。

ブラウザのデフォルト動作

一部の特定のイベントについては、ブラウザにはデフォルトの動作があります。たとえば、リンクをクリックすると指定したページにジャンプし、マウスを右クリックするとブラウザの右クリック メニューが表示され、フォームに入力するときに Enter キーを押すと自動的にサーバーに送信されます。

デフォルトのブラウザの動作とバブリングの動作は独立しています。デフォルトのイベントの動作をキャンセルしてもイベントのバブリングはキャンセルされません。また、その逆も同様です。同じ要素の複数のイベント ハンドラーも互いに独立しています。

<p>
  <a id="test" href="http://baidu.com">点我点我,我是链接</a>
</p>
var link = document.getElementById("test");
// 方法一   event.preventDefault()
link.onclick = function(event){
  console.log("You click!");
  event.preventDefault();
};
// 方法二   return false
link.onclick = function(event){
  console.log("You click!");
  return false;
};

参考:イベント-4. ブラウザのデフォルト動作-Yuqing

イベントオブジェクトevent

DOM上のイベントがトリガーされると、このオブジェクトには関連するすべての情報が含まれます。イベントへ。

event 对象只存在于事件处理程序执行期间,一旦执行完毕,立即被销毁。

<p>
  <a id="test" href="http://baidu.com">点我点我,我是链接</a>
</p>
/* 下列 event 对象的属性和方法都是只读的  */
var link = document.getElementById("test");
link.onclick = function(event){
  // 判断当前事件是否会向 DOM 树上层元素冒泡
  console.log(event.bubbles);

  // 判断是否可以取消事件的默认行为
  console.log(event.cancelable);
  // 使用该方法可以取消事件的默认行为(使用前提是 cancelable 属性的值为 true)
  event.preventDefault();
  // 判断是否已经调用了 preventDefault() 方法(DOM3级事件新增)
  console.log(event.defaultPrevented);

  // 指向事件遍历 DOM 时,识别事件的当前目标对象
  console.log(event.currentTarget);
  // 指向触发事件的对象
  console.log(event.target);

  // 表示事件流当前处于哪一个阶段
  // 值为 1 表示在捕获阶段,值为 2 表示处于目标阶段,值为 3 表示在冒泡阶段
  console.log(event.eventPhase);

  // 返回一个字符串, 表示该事件对象的事件类型
  console.log(event.type);

  // 立即停止当前事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡
  event.stopPropagation();
};

为了进一步说明 event.stopPropagation() 的运行效果,借用前面的代码,更改如下:

// 事件冒泡和事件捕获混合一下
var p = document.getElementById("test");
p.addEventListener("click",function(){
  console.log("i am p");
}, true);
document.body.addEventListener("click",function(){
  console.log("i am body");
}, false);    // 改为在冒泡阶段调用事件处理程序
document.documentElement.addEventListener("click",function(){
  console.log("i am html");
  event.stopPropagation();    // 立即停止事件在 DOM 中的传播
}, true);
document.addEventListener("click",function(){
  console.log("i am document");
}, true);
window.addEventListener("click",function(){
  console.log("i am window");
}, false);    // 改为在冒泡阶段调用事件处理程序
点击p,控制端会打印如下:
i am document
i am html

看到了吧,后面元素的事件就不会被激发了。

事件类型

UI 事件

UI 事件指的是简单的用户界面事件

load 事件:当页面所有资源(比如图像、css文件、js文件等资源)完全加载完毕后,就会触发 window 上面的 load 事件。

当然,我们也可以单独为某个元素设置 load 事件,比如为一个图片绑定这个事件,就可以检测这个图片是否加载完毕了。

<img  id="myImg" src="1.jpg" / alt="JavaScript DOM イベントのグラフィック コードの詳細な紹介" >
var img = document.getElementById("myImg");
img.onload = function(){
  alert("Image loaded!");
};

scroll 事件:在文档被滚动期间,重复触发该事件。

window.onscroll = function(){
  console.log("Scroll!");
};

焦点事件

焦点事件会在页面元素获得或失去焦点时触发。

注意:默认情况下,只有部分 html 元素能获得鼠标焦点(如 input,a),很大一部分 html 元素是不能获得鼠标焦点的(如 p,img),这些能够获得鼠标焦点的元素就是 focusable 元素。

不过,可以通过为这些默认没有焦点事件的元素添加一个 tabindex 属性,从而使它可以支持焦点事件。

  • document.activeElement:返回当前页面中获得焦点的元素,如果没有某个元素获得焦点,则该属性的值为当前页面中的元素

  • document.hasFocus():判断当前文档或者当前文档的子节点是否获得了焦点

  • HTMLElement.focus():使得指定的元素获得焦点(前提是这个元素是一个可以获得焦点的元素)

  • HTMLElement.blur():移除当前元素获得的焦点

上面是一些 HTML5 中添加的焦点管理 API。下面说焦点事件:

  • focus 事件:在元素获得焦点时触发,这个事件不会冒泡

  • blur 事件:在元素失去焦点时触发,这个事件不会冒泡

  • focusin 事件:在元素获得焦点时触发,与 focus 事件等价,但会冒泡

  • focusout 事件:在元素失去焦点时触发,与 blur 事件等价,但会冒泡

<img  id="img" src="1.jpg" tabindex="1" / alt="JavaScript DOM イベントのグラフィック コードの詳細な紹介" >
var img = document.getElementById("img");
document.body.onscroll = function() {
    img.blur();
};
img.onfocus = function() {
    console.log("Img focused!");
};
img.onblur = function() {
    console.log("Img lose focus!");
};
img.onclick = function() {
    console.log(document.activeElement);
    console.log(document.hasFocus());
};

注意: focusin 和 focusout 事件,所有的 Firefox 版本都不支持,看这里。chrome 和 safari 中只有通过 addEventListener 方式绑定这两个事件才能正常使用,其他方式绑定都不行。

说说focus /focusin /focusout /blur 事件(推荐)
(WHATWG)Focus management APIs

鼠标与滚轮事件

DOM3 级事件中定义了9个鼠标事件。

<body>
 <p id="test">
   <button>按钮</button>
 </p>
</body>
// css
p {
    width: 300px;
    height: 300px;
    margin: 50px auto;
    border: 1px solid #aaa;
  }

mouseover 事件:鼠标指针首次进入一个元素边界之内时触发,会冒泡

mouseout 事件:鼠标指针移出这个元素边界时触发,会冒泡

var test = document.getElementById("test");
test.onmouseover = function(event){
  event.target.style.border = "3px solid #666";
};
test.onmouseout = function(event){
  event.target.style.border = "none";
};

mouseenter 事件:鼠标指针首次移动到元素范围之内时触发,不冒泡

mouseleave 事件:鼠标指针移动到元素范围之外时触发,不冒泡

var test = document.getElementById("test");
test.onmouseenter = function(event){
  event.target.style.border = "10px solid #666";
};
test.onmouseleave = function(event){
  event.target.style.border = "none";
};

mousemove 事件:当鼠标在元素内部移动时重复触发,会冒泡

// 这里写一个鼠标在 body 内移动时,背景颜色随机变化的脚本
document.body.onmousemove = function(){
  var r = Math.floor(Math.random() * 256)
      g = Math.floor(Math.random() * 256)
      b = Math.floor(Math.random() * 256);
  document.body.style.background = "rgb("+r+","+g+","+b+")";
};

mousedown 事件:用户通过按下任意鼠标按钮时触发

mouseup 事件:用户释放鼠标按钮时触发

click 事件:用户单击鼠标左键时或按下回车键时触发

dblclick 事件:用户双击鼠标左键时触发

var body = document.body;
body.onmousedown = function(){
  console.log("Mouse down!");
};
body.onmouseup = function(){
  console.log("Mouse up!");
};
body.onclick = function(){
  console.log("One click!");
};
body.ondblclick = function(){
  console.log("Double click!");
};
// 双击 body,控制端打印:
Mouse down!
Mouse up!
One click!
Mouse down!
Mouse up!
One click!
Double click!

只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件,缺一不可。类似地,只有连续触发两次 click 事件,才会触发 dblclick 事件。

获取点击坐标

  • clientX 和 clientY:鼠标指针在视口中的坐标

  • pageX 和 pageY:鼠标指针在页面中的坐标

  • screenX 和 screenY:鼠标指针在屏幕中的坐标

在页面没有滚动的情况下,pageX 和 pageY 的值与 clientX 和 clientY 的值相等。

document.body.onclick = function() {
  console.log("Client: " + "(" + event.clientX + "," + event.clientY + ")");
  console.log("Page: " + "(" + event.pageX + "," + event.pageY + ")");
  console.log("Screen: " + "(" + event.screenX + "," + event.screenY + ")");
};

键盘与文本事件

  • keydown 事件:当用户按下任意键时触发,而且如果按住不放的话,会重复触发此事件

  • keypress 事件:当用户按下任意字符键时触发,而且如果按住不放的话,会重复触发此事件

  • keyup 事件:当用户释放键盘上的按键时触发

在用户按下一个字符键并且立马释放这个按键的过程中,先触发 keydown 事件,再触发 keypress 事件,最后触发 keyup 事件。

window.onkeydown = function() {
  console.log("on key down");
};
window.onkeyup = function() {
  if (event.keyCode === 65) {
    console.log(event.key);
  }
  console.log("one key up");
};
window.onkeypress = function() {
  console.log("one key press");
};

为了知道自己按下的是哪个按键,可以使用 event.which 来获得你按下按键的键码(比如字母 A 的键码为 65)。也可以通过键码属性(event.keyCode)来对特定的按键来进行响应。键码参考表

发生 keypress 事件时,会存在一个 charCode 属性,返回这个按键代表字符的 ASCII 编码。ASCII table

event.which 返回一个 keyCode 或 charCode 值,详情看下面代码

String.fromCharCode() 静态方法可以将 event.which 转化为相应的字符。

// 请自行粘贴复制于浏览器控制端测试
// 分别输入 a 和 A
// A和a 的 ASCII码分别为65,97
window.onkeydown = function(){
  if(event.keyCode === 65){
    console.log("(keydown keyCode)You press &#39;a&#39; or &#39;A&#39;!");
  }
  if(event.charCode === 65){
    console.log("(keydown charCode)You press &#39;A&#39;!");
  }
  console.log("keydown event.which = " + event.which);
  console.log("(keydown:)" + String.fromCharCode(event.which));
};
window.onkeypress = function(){
  if(event.keyCode === 65){
    console.log("(keypress keyCode)You press &#39;A&#39;!");
  }
  if(event.charCode === 65){
    console.log("(keypress charCode)You press &#39;A&#39;,not &#39;a&#39;!");
  }
  console.log("keypress event.which = " + event.which);
  console.log("(keypress:)" + String.fromCharCode(event.which));
};

在 DOM3 级事件中,做了一些变化,不再推荐使用 keyCode、charCode、which 属性,而是出现了两个新属性:key 和 char,用来替代 keyCode 和 charCode 属性。

但是不建议使用 key、char 属性,因为有一部分浏览器对他支持的不是很好。点这里

参考:JavaScript 事件——“事件类型”中“键盘与文本事件”的注意要点

变动事件

变动事件是在 DOM 结构发生变化时触发

在 DOM2 中定义了多个变动事件,但是在 DOM3 中又废除了一些,在这里先简单提一下有这个东西,以后用到再作补充。

HTML5 事件

contextmenu 事件:单击鼠标右键,会触发这个事件并调出页面的上下文菜单。这个事件是鼠标事件的一种,并且支持冒泡。

在上面的例子中,我们演示了利用 contextmenu 事件来设置自定义右键菜单,以及屏蔽右键菜单。

然而,屏蔽右键菜单却难不倒高手,Greasy Fork 上面有一个脚本(网页限制解除),专门来打破对右键菜单有限制的页面。

beforeunload 事件:当浏览器窗口,文档或其资源将要卸载时或者刷新页面时,会触发这个事件【MDN】

下面有几点需要注意一下:

1. 如果处理函数为 Event 对象的 returnValue 属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面。没有赋值时,该事件不做任何响应。

2. 从2011年5月25号开始,HTML5规范指出在此事件处理函数中,对于window.alert(), window.confirm(), 和 window.prompt() 的调用会被忽略。

3. 旧版本的浏览器可能会在提示框里显示返回的信息,但是新版本浏览器都默认采用浏览器内设的提示信息。

// 复制粘贴于浏览器控制端,然后关闭页面,会出现提示框
window.addEventListener("beforeunload", function() {
  var message = "你真的要离开吗?";
  event.returnValue = message;
  return message;
}, false);

DOMContentLoaded 事件:在页面文档形成完整的 DOM 树时触发,不理会图像、js文件、css文件等资源是否加载完毕

这个事件可以为 document 或 window 绑定,但实际目标是 document。这个事件会冒泡。

注意:这个事件与 load 事件是不一样的,正常情况下,会早于 load 事件被触发。

感觉篇幅太长了,事件委托移动设备中的事件事件对内存性能的影响等内容将在以后逐渐写出。

以上就是JavaScript DOM 事件初探的图文代码详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。