Heim > Web-Frontend > js-Tutorial > Hauptteil

Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen

黄舟
Freigeben: 2017-03-04 15:40:01
Original
1156 Leute haben es durchsucht

Ereignisse sind bestimmte interaktive Momente, die in einem Dokument oder Browserfenster auftreten, wie z. B. Klicken, Doppelklicken, Mauszeiger usw.

Ereignisfluss

Der Ereignisfluss beschreibt die Reihenfolge, in der Ereignisse von der Seite empfangen werden, oder die Reihenfolge, in der Ereignisse auf der Seite verbreitet werden.

  • Der Ereignisfluss von IE heißt Ereignisblasen (Ereignisblasen) : Das Ereignis beginnt beim spezifischsten Element und breitet sich dann bis zum Fensterschritt aus für Schrittobjekt.

  • Der vom Netscape-Team vorgeschlagene Ereignisfluss heißt Ereigniserfassung (Ereigniserfassung) : Ereignisse werden vom äußersten Fensterobjekt aus ausgeführt und breiten sich dann schrittweise aus nach unten zum spezifischsten Element.

Lassen Sie uns ein kleines Experiment durchführen, um den Unterschied zwischen diesen beiden Ereignisströmen zu veranschaulichen:

// 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>
Nach dem Login kopieren
// 事件冒泡
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);
Nach dem Login kopieren

Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen

点击p,控制端会打印如下:
i am p
i am body
i am html
i am document
i am window
Nach dem Login kopieren
// 事件捕获
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);
Nach dem Login kopieren

Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen

Das Bild wurde zweimal bearbeitet und ist etwas hässlich, bitte verzeihen Sie mir!

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

Es ist ersichtlich, dass Ereignisblasen und Ereigniserfassung zwei völlig gegensätzliche Ereignisströme sind.

Normalerweise wird das Ereignis-Bubbling im Allgemeinen verwendet, und die Ereigniserfassung wird nur unter besonderen Umständen verwendet.

Der durch Ereignisse auf DOM2-Ebene spezifizierte Ereignisfluss umfasst drei Phasen: Ereigniserfassungsphase, Zielphase und Ereignisblasenphase.

// 事件冒泡和事件捕获混合一下
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);    // 改为在冒泡阶段调用事件处理程序
Nach dem Login kopieren

Dieses Bild stammt direkt aus dem Buch. Erstelle einfach dein eigenes Gehirn und füge das Fensterobjekt selbst hinzu!

Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen

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

Ereignishandler

Ereignishandler: bezieht sich auf eine Funktion, die auf ein Ereignis reagiert

HTML-Ereignishandler

Jedes von einem Element unterstützte Ereignis kann mithilfe eines HTML-Attributs mit demselben Namen wie der entsprechende Ereignishandler angegeben werden.

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

Es wird empfohlen, diese Methode niemals zum Hinzufügen von Ereignissen zu Elementen zu verwenden, da diese Methode einen großen Nachteil hat, nämlich dass sie HTML- und JavaScript-Code eng miteinander verknüpft, was nicht den Anforderungen entspricht Trennung von Verhalten und Struktur des Webdesigns.

Ereignishandler auf DOM0-Ebene

Jedes Element (einschließlich Fenster und Dokument) hat sein eigenes Ereignishandlerattribut, wie z. B. onclick, onmouseup usw.

Schreiben Sie den obigen Code wie folgt um:

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

Ereignishandler auf DOM2-Ebene

Ereignis auf DOM2-Ebene ist zwei definiert Methoden werden verwendet, um den Vorgang des Festlegens und Entfernens von Ereignishandlern abzuwickeln: addEventListener() und removeEventListener().

Beide Methoden haben drei Parameter. Der erste Parameter ist der Ereignisname, der zweite Parameter ist die Funktion als Ereignishandler und der dritte Parameter ist ein boolescher Wert, der das Ereignis bedeutet Der Handler wird während der Bubbling-Phase aufgerufen. Wenn dieser Wert wahr ist, bedeutet dies, dass der Event-Handler während der Capture-Phase aufgerufen wird.

Schreiben Sie den obigen Code weiter um:

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);
Nach dem Login kopieren

Der Hauptvorteil der Verwendung der DOM2-Ebenenmethode zum Hinzufügen von Ereignishandlern besteht darin, dass Sie mehrere Ereignishandler für ein Element hinzufügen können.

Wenn der von addEventListener() hinzugefügte Event-Handler eine anonyme Funktion ist, kann dieser Event-Handler nicht von removeEventListener() gelöscht werden.

IE-Ereignishandler

IE8 und frühere IE-Versionen unterstützen nur das Event-Bubbling und nicht addEventListener() und removeEventListener(), aber es implementiert zwei Methoden, die diesen beiden Methoden ähneln: attachEvent() und detachEvent(). Diese beiden Methoden haben nur zwei Parameter, einen Ereignisnamen (onclick, nicht click) und eine Ereignisbehandlungsfunktion.

Im Gegensatz zu addEventListener() wird die Ereignisbehandlungsfunktion bei Verwendung der Methode attachmentEvent() im globalen Bereich ausgeführt, sodass dies dem Fenster entspricht, was besondere Aufmerksamkeit erfordert.

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!");
});
Nach dem Login kopieren

Verwenden Sie diese beiden Funktionen nicht, es sei denn, Sie möchten Ihr Programm mit dem IE8-Browser kompatibel machen.

Standardverhalten des Browsers

Für bestimmte Ereignisse hat der Browser sein Standardverhalten. Beispiel: Wenn Sie auf einen Link klicken, wird zur angegebenen Seite gesprungen. Wenn Sie mit der rechten Maustaste klicken, wird das Rechtsklickmenü des Browsers angezeigt. Wenn Sie beim Ausfüllen eines Formulars die Eingabetaste drücken, wird es automatisch an den Server gesendet usw.

Das Standardverhalten des Browsers und das Bubbling-Verhalten sind unabhängig voneinander. Durch das Abbrechen des Standardereignisverhaltens wird das Bubbling des Ereignisses nicht abgebrochen und umgekehrt. Auch mehrere Event-Handler für dasselbe Element sind unabhängig voneinander.

<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;
};
Nach dem Login kopieren

Referenz: Ereignis-4. Browser-Standardverhalten – Yu Qing

Ereignisobjektereignis

Wenn ein Ereignis im DOM ausgelöst wird, wird ein Ereignisobjekt generiert. Dieses Objekt enthält alle mit dem Ereignis verbundenen Informationen.

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();
};
Nach dem Login kopieren

为了进一步说明 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);    // 改为在冒泡阶段调用事件处理程序
Nach dem Login kopieren
点击p,控制端会打印如下:
i am document
i am html
Nach dem Login kopieren

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

事件类型

UI 事件

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

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

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

<img  id="myImg" src="1.jpg" / alt="Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen" >
var img = document.getElementById("myImg");
img.onload = function(){
  alert("Image loaded!");
};
Nach dem Login kopieren

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

window.onscroll = function(){
  console.log("Scroll!");
};
Nach dem Login kopieren

焦点事件

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

注意:默认情况下,只有部分 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="Eine detaillierte Einführung in den grafischen Code von JavaScript-DOM-Ereignissen" >
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());
};
Nach dem Login kopieren

注意: 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;
  }
Nach dem Login kopieren

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";
};
Nach dem Login kopieren

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";
};
Nach dem Login kopieren

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+")";
};
Nach dem Login kopieren

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!");
};
Nach dem Login kopieren
// 双击 body,控制端打印:
Mouse down!
Mouse up!
One click!
Mouse down!
Mouse up!
One click!
Double click!
Nach dem Login kopieren

只有在同一个元素上相继触发 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 + ")");
};
Nach dem Login kopieren

键盘与文本事件

  • 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");
};
Nach dem Login kopieren

为了知道自己按下的是哪个按键,可以使用 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));
};
Nach dem Login kopieren

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

但是不建议使用 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);
Nach dem Login kopieren

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

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

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

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

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

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!