Notes

1、onclick

<button onclick="copyText()">Copy Text</button>

2、removeEventListener

<button>Act-once button</button>
<script>
let button = document.querySelector("button");
function once() {
console.log("Done.");
button.removeEventListener("click", once);
}
button.addEventListener("click", once);
</script>

3、Event objects

<button>Click me any way you want</button>
<script>
let button = document.querySelector("button");
button.addEventListener("mousedown", event => {
if (event.button == 0) {
console.log("Left button");
} else if (event.button == 1) {
console.log("Middle button");
} else if (event.button == 2) {
console.log("Right button");
}
});
</script>

4、stopPropagation

        <p>A paragraph with a <button>button</button>.</p>
<script>
let para = document.querySelector("p");
let button = document.querySelector("button");
para.addEventListener("mousedown", () => {
console.log("Handler for paragraph.");
});
// 左键传播,右键不传播。
button.addEventListener("mousedown", event => {
console.log("Handler for button.");
if(event.button == 2) event.stopPropagation();
});
</script>

5、event.target

        <button>A</button>
<button>B</button>
<button>C</button>
<script>
document.body.addEventListener("click", event => {
if(event.target.nodeName == "BUTTON") {
console.log("Clicked", event.target.textContent);
}
});
</script>

6、Default actions

        <a href="https://developer.mozilla.org/">MDN</a>
<script>
let link = document.querySelector("a");
// 事件处理器在默认行为发生之前被调用
link.addEventListener("click", event => {
console.log("Nope.");
event.preventDefault(); // 例如ctrl+w是无法被prevent的
});
</script>

7、Key events

        <p>This page turns violet when you hold the V key.</p>
<script>
window.addEventListener("keydown", event => {
if(event.key == "v") {
document.body.style.background = "violet";
console.log("repeat"); // 只要按住就会不断触发,而不是仅触发一次。
}
});
window.addEventListener("keyup", event => {
if(event.key == "v") {
document.body.style.background = "";
}
});
</script>

组合按键:

        <p>Press Control-Space to continue.</p>
<script>
window.addEventListener("keydown", event => {
if(event.key == " " && event.ctrlKey) {
console.log("Continuing!");
}
});
</script>

8、Mouse motion

一个可以拖动的进度条:

        <p>Drag the bar to change its width:</p>
<div style="background: orange; width: 60px; height: 20px">
</div>
<script>
let lastX; // Tracks the last observed mouse X position
let bar = document.querySelector("div");
bar.addEventListener("mousedown", event => {
if(event.button == 0) { // 鼠标左键
lastX = event.clientX;
window.addEventListener("mousemove", moved);
event.preventDefault(); // Prevent selection
}
}); function moved(event) {
if(event.buttons == 0) {
// MouseEvent.buttons可指示任意鼠标事件中鼠标的按键情况
// 仅按下左键1 仅按下右键2 仅按下滚轮4 ,同时按下多个则取和
// 这个示例的现象在于,只有在进度条上按下左键才可以开启事件
// 之后快速换鼠标右键(或者n个键)拖动也可以。
window.removeEventListener("mousemove", moved);
} else {
let dist = event.clientX - lastX;
let newWidth = Math.max(10, bar.offsetWidth + dist); // 10是最小宽度
bar.style.width = newWidth + "px";
lastX = event.clientX;
}
}
</script>

9、Touch events

触屏和鼠标点击是不同的,但是触屏仍然默认会触发一些鼠标事件。

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<style>
dot {
position: absolute;
display: block;
border: 2px solid red;
border-radius: 50px;
height: 100px;
width: 100px;
}
</style>
</head> <body>
<p>Touch this page</p>
<script>
function update(event) {
for(let dot; dot = document.querySelector("dot");) {
dot.remove();
}
for(let i = 0; i < event.touches.length; i++) {
let {
pageX,
pageY
} = event.touches[i];
let dot = document.createElement("dot");
dot.style.left = (pageX - 50) + "px";
dot.style.top = (pageY - 50) + "px";
document.body.appendChild(dot);
}
}
window.addEventListener("touchstart", update);
window.addEventListener("touchmove", update);
window.addEventListener("touchend", update);
</script>
</body> </html>

10、Scroll events

监控滚动条的状况:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<style>
#progress {
border-bottom: 2px solid blue;
width: 0;
position: fixed;
top: 0;
left: 0;
}
</style>
</head> <body>
<div id="progress"></div>
<script>
// Create some content
document.body.appendChild(document.createTextNode(
"supercalifragilisticexpialidocious ".repeat(1000))); let bar = document.querySelector("#progress");
window.addEventListener("scroll", () => {
let max = document.body.scrollHeight - innerHeight;
bar.style.width = `${(pageYOffset / max) * 100}%`;
});
</script>
</body> </html>

采用preventDefault不会阻止默认事件(滚动)发生,因为滚动是在调用事件处理器之前执行的。

11、Focus events

注意Focus事件是不会传播的。

<p>Name: <input type="text" data-help="Your full name"></p>
<p>Age: <input type="text" data-help="Your age in years"></p>
<p id="help"></p> <script>
let help = document.querySelector("#help");
let fields = document.querySelectorAll("input");
for (let field of Array.from(fields)) {
field.addEventListener("focus", event => {
let text = event.target.getAttribute("data-help");
help.textContent = text;
});
field.addEventListener("blur", event => {
help.textContent = "";
});
}
</script>

12、Load event

Load事件同样是不传播的。

beforeunload - Event reference | MDN

load - Event reference | MDN

13、Events and the event loop

事件处理器在事件发生的时候就已经被“安排”了,但是也必须等到别的脚本执行完才有机会执行。在有很多或者很耗时的脚本时,页面就有可能被“冻”住,为了解决这个问题,应该把繁重、长时间的计算放在一个单独的线程里。副脚本不会和主脚本共享作用域,只有可以表达为JSON的数据才可以在两者之间传递。

js/squareworker.js↓

addEventListener("message", event => {
postMessage(event.data * event.data);
});

index.html↓

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
let squareWorker = new Worker("js/squareworker.js");
squareWorker.addEventListener("message", event => {
console.log("The worker responded:", event.data);
});
squareWorker.postMessage(10);
squareWorker.postMessage(24);
</script>
</body> </html>

14、Timers

取消setTimeout回调:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
let bombTimer = setTimeout(() => {
console.log("BOOM!");
}, 500); if(Math.random() < 0.5) { // 50% chance
console.log("Defused.");
clearTimeout(bombTimer);
}
</script>
</body> </html>

取消setInterval回调:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
let ticks = 0;
let clock = setInterval(() => {
console.log("tick", ticks++);
if(ticks == 10) {
clearInterval(clock);
console.log("stop.");
}
}, 200);
</script>
</body> </html>

15、Debouncing

某些类型的事件有可能会被连续触发n次(例如“鼠标移动”和“滚动”事件)。处理此类事件时,必须注意不要做太费时间的操作,否则处理程序会占用很多时间,以至于与文档的交互开始变得缓慢。如果你确实需要在这样的处理程序中做一些非常重要的事情,你可以使用setTimeout来降低触发长时操作的频率。这通常被称为Debouncing(去抖动)。有几种略有不同的实现方式。

例子一,持续输入0.5秒输出一个Typed!:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<textarea>Type something here...</textarea>
<script>
let textarea = document.querySelector("textarea");
let timeout;
textarea.addEventListener("input", () => {
clearTimeout(timeout);
timeout = setTimeout(() => console.log("Typed!"), 500);
});
</script>
</body>
</html>

例子二,间隔250ms响应一次鼠标移动:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
let scheduled = null;
window.addEventListener("mousemove", event => {
if(!scheduled) {
setTimeout(() => {
document.body.textContent =
`Mouse at ${scheduled.pageX}, ${scheduled.pageY}`;
scheduled = null;
}, 250);
}
scheduled = event;
});
</script>
</body> </html>

Exercise

① Balloon

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<p>

Eloquent JavaScript #12# Handling Events的更多相关文章

  1. Javascript Madness: Mouse Events

    http://unixpapa.com/js/mouse.html Javascript Madness: Mouse Events Jan WolterAug 12, 2011 Note: I ha ...

  2. Eloquent JavaScript #13# HTTP and Forms

    索引 Notes fetch form focus Disabled fields form’s elements property 阻止提交 快速插入单词 实时统计字数 监听checkbox和rad ...

  3. (4)事件处理——(1)事件处理(Handling Events)

    JavaScript has several built-in ways of reacting to user interaction and other events. To make a pag ...

  4. Eloquent JavaScript #04# Objects and Arrays

    要点索引: JSON More ... 练习 1.补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符 ...

  5. Handling events in an MVVM WPF application

      Posted: June 30, 2013 | Filed under: MVVM, WPF, XAML |1 Comment In a WPF application that uses the ...

  6. [transferred] javascript exception handling.

    my error handling clause: window.onerror = function (errorMessage, scriptURI, lineNumber, columnNumb ...

  7. 从零开始学习前端JAVASCRIPT — 12、JavaScript面向对象编程

    一.构造函数的使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  8. Eloquent JavaScript #11# The Document Object Model

    索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...

  9. Eloquent JavaScript #10# Modules

    索引 Notes 背景问题 模块Modules 软件包Packages 简易模块 Evaluating data as code CommonJS modules ECMAScript modules ...

随机推荐

  1. Python Singleton模式

    注意:在重写__new__方法时,object.__new__(cls)不能传参数 #!/usr/bin/env python # -*- coding: utf-8 -*- class Single ...

  2. mysql相关SQL

    1.mysql分组获取最新数据 sql> select max(column_name) from table group by column_name having count(*) orde ...

  3. 使用 Oracle Data Access Components连接oracel

    使用微软自带的oracle连接类,在framework4.0中被标识为弃用,强行用它开发了Winform程序,发布放到XP上提示: Error System.Data.OracleClient req ...

  4. python 类组合

    场景:有一辆车违章需要通知到车主 定义两个类车辆类和通知类,车辆类和通知类并没有共同点,但是要通知车主这两个类就有了关联,这时候可以把这两个类组合在一起 #!/usr/bin/python3 # -* ...

  5. Tensorflow 搭建神经网络及tensorboard可视化

    1. session对话控制 matrix1 = tf.constant([[3,3]]) matrix2 = tf.constant([[2],[2]]) product = tf.matmul(m ...

  6. Dart async proc

    //dart import 'dart:io';import 'dart:async'; Future printDailyNewsDigest1() { print('A:'); File file ...

  7. LineRenderer组建实现激光效果

    在射击游戏中狙击一般都有一个红外线的效果.比如

  8. Python学习笔记之装饰器原理

    def decorator(fn): def wrapper(): print("询价") fn() print("购买成功!") return wrapper ...

  9. java中二维数组的复制克隆

    https://blog.csdn.net/qq_37232304/article/details/79950022

  10. VC2012+QT新建一个控制台程序

    1.新建一个项目,选择控制台程序 2.下一步.project setting 可以包含模块,可以再这选择也可以之后选择 3.配置工程属性 1)需要源码的话添加VC++目录里的源目录 2)包含头文件   ...