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. [py]__name__ 属于哪个文件

    name: 属于哪个文件 文件的 main 类的 class Person(object): """ 定义一个类 """ count = 1 ...

  2. 【LeetCode每天一题】Find First and Last Position of Element in Sorted Array(找到排序数组中指定元素的开始和结束下标)

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  3. svn ignore 的用法

    一个很简单的需求,我想在add一个文件时忽略里面某种格式的文件,怎么弄? 选中文件夹,然后tortoiseSvn->setting-> global ignore pattern:是客户端 ...

  4. cycript使用

    cycript的原理是动态库注入,但是其动态库注入的原理,与我们常见的通过LC_LOAD_DYLIB在可执行文件中注入动态库不同. cycript的操作是 : 抓取到要挂载的应用, 由于越狱机上拥有权 ...

  5. HTML+css+html5基础+css3须知

    1.定位四种 静态定位(static):文档流默认的定位方式:一般不用写.      如果没有指定元素的position属性值,元素也就是静态定位.static是position属性的默认值,它表示块 ...

  6. Linux.超级管理员root-密码破解

    Linux.超级管理员root-密码破解 环境: 我是在虚拟机中安装的Linux,然后进行破解的.实体机,应该也是可以的,但我没有尝试过.如果你有实体机,试试吧... 又不要钱~ 在系统启动的时候,会 ...

  7. c#之如何计算哈希值字符串

    代码如下: /// <summary> /// 计算哈希值字符串 /// </summary> public static string ComputeHash(byte[] ...

  8. wordpress学习(五)----插件

    wordpress加载顺序:首先加载插件,再加载主题中的functions.php,初始化一些数据之类的,最后加载模板了!!! update_option("hc_copyright_tex ...

  9. 转 VS2010 RDLC 横向合并时“未正确设置 tablix“Tablix1”的 FixedData 属性”错误解决方法 .

    最近在使用Rdlc做报表打印,有些报表的表头需要合并表头.Rdlc本身提供了横向合并的工具,但是在实际合并的时候,会出现“未正确设置 tablix“Tablix1”的 FixedData 属性.除非在 ...

  10. Pycharm学习python路

    import 模块之后是灰色的表明没有被引用过 lxml找不到的话用anaconda prompt :pip uninstall lxml 重新安装 用request时,写的reg无法正确解析网页,先 ...