Eloquent JavaScript #12# Handling Events
索引
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
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的更多相关文章
- Javascript Madness: Mouse Events
http://unixpapa.com/js/mouse.html Javascript Madness: Mouse Events Jan WolterAug 12, 2011 Note: I ha ...
- Eloquent JavaScript #13# HTTP and Forms
索引 Notes fetch form focus Disabled fields form’s elements property 阻止提交 快速插入单词 实时统计字数 监听checkbox和rad ...
- (4)事件处理——(1)事件处理(Handling Events)
JavaScript has several built-in ways of reacting to user interaction and other events. To make a pag ...
- Eloquent JavaScript #04# Objects and Arrays
要点索引: JSON More ... 练习 1.补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符 ...
- 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 ...
- [transferred] javascript exception handling.
my error handling clause: window.onerror = function (errorMessage, scriptURI, lineNumber, columnNumb ...
- 从零开始学习前端JAVASCRIPT — 12、JavaScript面向对象编程
一.构造函数的使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Eloquent JavaScript #11# The Document Object Model
索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...
- Eloquent JavaScript #10# Modules
索引 Notes 背景问题 模块Modules 软件包Packages 简易模块 Evaluating data as code CommonJS modules ECMAScript modules ...
随机推荐
- (转)EOSIO开发(一)使用Docker构建本地环境
前言 一直想学习EOS开发,但是不知道怎么入门.最近从GitHub上下载了源码,发现官方已经提供了完整的EOSIO开发入门教程,既然如此赶紧开始行动.今天是系列文章的第一篇,介绍如何使用Docker搭 ...
- js抽红包分配
将 50000元随机分给10个人,其中3个人必须分到百位数,4个人分到千位数,3个人分到万位数,每个人所得金额 <!DOCTYPE html> <html lang="zh ...
- c# 利用MailKit.IMap 收取163邮件
最近我要做一个爬虫.这个爬虫需要如下几个步骤: 1 填写注册内容(需要邮箱注册) 2 过拖拽验证码(geetest) 3 注册成功会给邮箱发一封确认邮箱 4 点击确认邮箱中的链接 完成注册 我这里就采 ...
- zip()
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以 ...
- python date time
//test.py import time ticks = time.time()print tickslocaltime = time.localtime(time.time())print loc ...
- Linux:系统文件目录
目录结构 bin:命令类目录 命令 系统操作 清屏:clear.ctrl+L 进程: # $(ps -ef | grep hnlinux) //方法一 过滤出hnlinux用户进程 #kill -u ...
- .Net拾忆:CodeDom动态源代码生成器和编译器
代码文档模型CodeDom命名空间下主要有两个,很明显第一个代码逻辑分析,第二个负责代码的编译 using System.CodeDom; using System.CodeDom.Compiler; ...
- 软件测试常用Linux命令
有些技能可以事半功倍,有些命运掌握在我们手中.熟练的掌握和使用这些命令可以提高工作效率,并且结合这些命令对测试过程中遇到的问题进行一些初步的定位. 1 目录与文件操作 1.1 ls(初级) 使用权限: ...
- iOS LeftMenu抽屉效果与ScrollView共存时的手势冲突
公司有个项目,需要做左侧滑动,首页是ScrollView嵌套TableView.首页是一个ScrollView,所以当contentOffset是0.0的时候,无法直接滑动出抽屉效果,用户体验感非常差 ...
- spring 对jdbc的简化
spring.xml <!-- 加载属性配置文件 --> <util:properties id="db" location="classpath:db ...