《javascript权威指南》这本书就像是js界的圣经,对于大神和新手都应该是必读书。但是这本近千页的书已经厚到让人望而生畏,要通读它不仅要时间也需要毅力。为了提升自己在js语言上的深度,所以抱着工匠精神开始研读,此文包含书中实用性较强的一些知识点和代码,算做读书笔记吧~
这一章参照的是W3C定义的3级DOM事件,现在更名为 UI事件 了。
定义whenReady函数,类似onLoad函数。当文档就绪时,传递给whenReady的函数就会作为Document对象的方法调用。优先使用DOMContentLoaded和readystatechange事件。
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); //否则加入队列 }}());
定义drag函数实现文档元素拖动操作。
drag函数绑定到mousedown事件,整个逻辑也是比较简单在mousedown事件开始时记录坐标点,然后在mousemove事件时改变css样式来实现dom元素移动,同时结束时注销事件。不过需要注意的就是dom元素必须是非静态定位。
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 }}
写一个过滤键盘输入的函数,当用户输入了不允许字符时显示消息元素,否则隐藏它。
(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" }}());
将输入的字符自动转换为大写
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,如果为对应的子元素则执行对应的逻辑。
var event = document.createEvent('Event');event.initEvent('click');var element = document.getElementById('zdl');element.dispatchEvent(event);
这本书真是内容翔实,枯燥难读。这一章的内容看了几遍才决定以百度脑图和代码实例相结合的方式,如果有更好的建议可以发送邮件给我~感谢阅读
百度脑图下载地址: http://yalishizhude.github.io/subscribe/
博客: http://yalishizhude.github.io
作者:亚里士朱德