您的位置:首页 > 其它

一起来啃犀牛书:事件处理

2016-03-15 13:28 281 查看


一起来啃犀牛书:事件处理

发表于 2016-03-14 | 分类于 js
|

《javascript权威指南》这本书就像是js界的圣经,对于大神和新手都应该是必读书。但是这本近千页的书已经厚到让人望而生畏,要通读它不仅要时间也需要毅力。为了提升自己在js语言上的深度,所以抱着工匠精神开始研读,此文包含书中实用性较强的一些知识点和代码,算做读书笔记吧~




这一章参照的是W3C定义的3级DOM事件,现在更名为UI事件了。


文档加载事件


知识点

load。直到文档和所有图片加载完毕时才发生
DOMContentLoaded。当文档加载解析完毕且所有延迟脚本都执行完毕时会出发。优先使用
readystatechange。HTML5标准化的事件,在load事件之前触发。


例题

定义whenReady函数,类似onLoad函数。当文档就绪时,传递给whenReady的函数就会作为Document对象的方法调用。优先使用DOMContentLoaded和readystatechange事件。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

var whenReady = (function(){
var funcs = [], //需要运行的函数
ready = false, //为避免重复执行
i = 0;
function handler(e) {
if(!ready) {
//如果发生readystatechange事件,但状态不是complete则文档未准备好
if('readystatechange'===e.type && 'complete'!==document.readyState) {
return ;
}
for (i=0;i<funcs.length; i++) {
funcs[i].call(document);
}
ready = true;
funcs = null;
}
}
if(document.addEventListener) {
document.addEventListener('DOMContentLoaded', handler);
document.addEventListener('readystatechange', handler);
window.addEventListener('load', handler);
} else if(document.attachEvent) {
document.attachEvent('onreadystatechange', handler);
window.attachEvent('load', handler);
}
return function(f){
if (ready) f.call(document); //若准备完毕则运行
else funcs.push(f);  //否则加入队列
}
}());


鼠标事件


知识点


事件属性

clientX和clientY表示鼠标坐标
altKey、metaKey、ctrlKey、shiftKey
HTML5中元素添加draggable属性之后就可以实现dragstart和dragend事件。


例题

定义drag函数实现文档元素拖动操作。


代码

drag函数绑定到mousedown事件,整个逻辑也是比较简单在mousedown事件开始时记录坐标点,然后在mousemove事件时改变css样式来实现dom元素移动,同时结束时注销事件。不过需要注意的就是dom元素必须是非静态定位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
3031
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

function drag(){
//获取坐标
function getScrollOffsets(w) {
var d = {};
//使用指定窗口或者当前窗口
w = w || window;
//现代浏览器
if (w.pageXOffest != null) {
return {
x: w.pageXOffest,
y: w.pageYOffset
};
}
//标准模式下的IE
d = w.document;
if (document.compatMode === 'CSS1Compat') {
return {
x: d.documentElement.scrollLeft,
y: d.documentElement.scrollTop
};
}
//怪医模式下的浏览器
return {
x: d.body.scrollLeft,
y: d.body.scrollTop
};
}
var scroll = getScrollOffsets();
var startX = event.clientX + scroll.x;
var startY = event.clientY + scroll.y;
var origX = elementToDrag.offsetLeft;
var origY = elementToDrag.offsetTop;
var deltaX = startX - origX;
var deltaY = startY - origY;
//注册鼠标移动和鼠标释放事件
if (document.addEventListener) {
document.addEventListener("mousemove", moveHandler, true);
document.addEventListener("mouseup", upHandler, true)
} else if (document.attachEvent) {
elementToDrag.setCapture();
elementToDrag.attachEvent("onmousemove", moveHandler);
elementToDrag.attachEvent("onmouseup", upHandler);
elementToDrag.attachEvent("onlosecapture", upHandler)
}
if (event.stopPropagation) event.stopPropagation();
else event.cancelBubble = true;
if (event.preventDefault) event.preventDefault();
else event.returnValue = false;
//移动鼠标时移动元素
function moveHandler(e) {
if (!e) e = window.event;
var scroll = getScrollOffsets();
elementToDrag.style.left = (e.clientX + scroll.x - deltaX) + "px";
elementToDrag.style.top = (e.clientY + scroll.y - deltaY) + "px";
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true
}
//拖拽结束,注销事件
function upHandler(e) {
if (!e) e = window.event;
if (document.removeEventListener) {
document.removeEventListener("mouseup", upHandler, true);
document.removeEventListener("mousemove", moveHandler, true)
} else if (document.detachEvent) {
elementToDrag.detachEvent("onlosecapture", upHandler);
elementToDrag.detachEvent("onmouseup", upHandler);
elementToDrag.detachEvent("onmousemove", moveHandler);
elementToDrag.releaseCapture()
}
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true
}
}


文本/键盘事件


知识点

keypress。常用的高级键盘事件。
textinput。时3级DOM事件规范定义的通用事件(来源包括键盘/粘贴/拖放/声音/手写)
textInput。webkit浏览器支持类似textinput的事件。


例题1

写一个过滤键盘输入的函数,当用户输入了不允许字符时显示消息元素,否则隐藏它。


代码1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
3031
32
33
34
35
36
37
38

(function() {
var inputelts = document.getElementsByTagName("input");
for (var i = 0; i < inputelts.length; i++) {
var elt = inputelts[i];
if (elt.type != "text" || !elt.getAttribute("data-allowed-chars")) continue;
if (elt.addEventListener) {
elt.addEventListener("keypress", filter, false);
elt.addEventListener("textInput", filter, false);
elt.addEventListener("textinput", filter, false)
} else {
elt.attachEvent("onkeypress", filter)
}
}
function filter(event) {
var e = event || window.event;
var target = e.target || e.srcElement;
var text = null;
if (e.type === "textinput" || e.type === "textInput") text = e.data;
else {
var code = e.charCode || e.keyCode;
if (code < 32 || e.charCode == 0 || e.ctrlKey || e.altKey) return;
var text = String.fromCharCode(code)
}
var allowed = target.getAttribute("data-allowed-chars");
var messageid = target.getAttribute("data-messageid");
if (messageid) var messageElement = document.getElementById(messageid);
for (var i = 0; i < text.length; i++) {
var c = text.charAt(i);
if (allowed.indexOf(c) == -1) {
if (messageElement) messageElement.style.visibility = "visible";
if (e.preventDefault) e.preventDefault();
if (e.returnValue) e.returnValue = false;
return false
}
}
if (messageElement) messageElement.style.visibility = "hidden"
}
}());


例题2

将输入的字符自动转换为大写


代码2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

function forceToUpperCase(element) {
if (typeof element === "string") element = document.getElementById(element);
element.oninput = upcase;
element.onpropertychange = upcaseOnPropertyChange;

function upcase(event) {
this.value = this.value.toUpperCase()
}
function upcaseOnPropertyChange(event) {
var e = event || window.event;
if (e.propertyName === "value") {
this.onpropertychange = null;
this.value = this.value.toUpperCase();
this.onpropertychange = upcaseOnPropertyChange
}
}
}


事件处理


事件代理

节省内存,适用于表格/列表等重复性dom元素。基本原理就是将事件绑定到祖先元素上,然后判断事件对象target,如果为对应的子元素则执行对应的逻辑。


事件创建/分发

1
2
3
4

var event = document.createEvent('Event');
event.initEvent('click');
var element = document.getElementById('zdl');
element.dispatchEvent(event);


最后

这本书真是内容翔实,枯燥难读。这一章的内容看了几遍才决定以百度脑图和代码实例相结合的方式,如果有更好的建议可以发送邮件给我~感谢阅读
百度脑图下载地址:http://yalishizhude.github.io/subscribe/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: