javaScript高级程序设计(第三版)个人笔记
sublimejavascript插件 https://github.com/SublimeCodeIntel/SublimeCodeIntel
在 Sublime Text 直接运行 Javascript 调试控制台 https://blog.netsh.org/posts/sublime-text-javascript-console_1820.netsh.html
array = Array.preototype.slice.call(nodes,0);
hove array.push(nodes[i]);
nextSibing
previousSibling
firstChild
lastChild(no.childrenNodes[no.length-1])
hasChildNodes
ownerDocument不用回溯直接访问文档节点
appendChild最后
如果传入第一个节点到最后,第一个节点不再是第一个节点,二十最后一个节点
insertBefore
replaceChild
removeChild
cloneNode
normalize
document.documentElement指向html
document.body指向body
document.title属性
document.URL
document.domain可以修改,用来访问其他子域框架和内嵌框架
取得来源页面的域名document.referrer通常是空的
getElementsById
getElementsByTagName 第一项
namedItem(对数值索引用item,对字符串索引用namedItem)
getElementByTagName("*")可以取得全部元素
getElementsByName取得所有项,适合比如id不同name相同的项目
document.anchors返回带name的<a>
document.applets
document.forms所有<form>
document.links所有带href的<a>
document.images所有<img>
document.implementation Dom的一致性检测
document.implementation.hasFeature("html","3.0")浏览器是否支持这些功能
document.write字符串参数
document.writeln传且换行
document.open打开网页的输入输出流
document.close
Element类型
元素可以用nodeName属性,也可以用tabName属性
Element节点(type 1)
document.body.nodeName.toLowerCase()常用函数(html始终大写,xml跟函数中间一样)
html元素
举例:div.dir(ltr从左到右) div.className
getAttribute因为不同浏览器版本不一致所以不常使用
setAttribute setget不一定有效果
removeAttribute
document.body.childNodes[1].getAttribute("id")
attributes属性
element.attributes.setNamedItem()
var div = document.createElement("<...>") [268]P287
element.getElementsByTagName("li");
text属性
normalize()
splitText()分割提取文本节点
comment 和CDATASection类型都继承自Text类型
doucu..doctype.name "html"
documentFragment把碎片添加统一放到仓库中,一次渲染
splitText()
script元素插入JavaScript代码
DOM扩展
var ems = document.getElementById("myDiv").querySelectorAll("em");
querySelectorAll()
matchesSelector()
11.2 element元素遍历lastChild浏览器间不一致,所以lastElementCHild
11.3.1 扩充class用法
`1简化类的用法getElementByClassName("selected");
2classList对类名增删替换class="bd user disabled"
div.classList.remove("user") add toggle(切换) classList length
11.3.2焦点管理
document.activeElement属性 focus()方法 hasFocus()方法
11.3.3htmlDocument的变化
document.readyState == “loading”/“complete”
2.兼容模式document.compatMode == "CSS1Compat"标准模式/"BackCompat"混杂模式(兼容古怪老网站)
3.head属性 var head = document.head || document.getElementsByTagName("head")[0];
11.3.4字符集
document.charset/defaultCharset = "UTF-8"
11.3.5自定义数据属性
加data-前缀,<div id = 'd' data-appId='12345'>
自定义属性用dataset访问。div.dataset.appId = 23456;
11.3.6插入标记
1.innerHTML属性:(不用麻烦的创建节点然后手动指定关系)返回调用框内子节点所有(元素、注释、文本),大小写不同浏览器有区别,如果没标签就是纯文本。
div.innerHTML = "hello world"/"<b>asfd</b>"
插入“无作用域的元素”就前置一个有内容的元素比如“_”div.innerHTML = "_<script defer>alert(1);<\/script>";
外部获取安全的HTML就得删除脚本节点及事件处理程序:window.toStaticHTML(text)
比如text = "<a href=\"#\" onclick=\"alert(1);\">123</a>"可去掉onclick函数
2.outerHTML属性 替换
<div>asdf<a>aaa</a></div>
div.outerHTML = "<p>this<p/>";用<p>元素替代<div>元素
3.insertAdjacentHTML()
element.insertAdjacentHTML("beforeBegin","<p>Hello World.</p>")
beforebegin插入为前一个同辈元素 afterbegin插入为第一个子元素 beforeend插入位最后一个子元素 afterend插入为后一个同辈元素
4.内存占用
为了减少页面占用内存,使用以上方法时手动删除元素的所有事件处理程序和JS对象属性;传参时避免频繁操作这些属性,最好是单独构建字符串一次赋值。
11.3.7 scrollIntoView()滚动页面
true或者不传参,窗口滚动后调用元素的顶部会与视口顶部平齐
传入false参数,调用元素尽量全部出现在视口中,可能底部平齐顶部不一定
document.forms[0].scrollIntoView();//让元素可见
11.4 专有扩展(标准缺失某项功能,开发商向DOM中添加,大部分专有DOM扩展还没成为标准)
11.4.1 文档模式(documentMode:什么级别的CSS,那些jsAPI,文档类型)
IE5:默认混杂模式 IE7标准模式 IE8标准模式(如SelectorsAPI,css2,css3部分)IE9模式
<meta http-equiv="X-UA-Compatible" content="IE=IEVersion">
Edge最新的文档模式 EmulateIE9/8/7(看是否有声明) 9/8/7/5(强制IE9875)
如IE=EmulateIE7 IE=7
var mode = document.documentMode;
11.4.2 children属性(HTMLCollection实例)
只包含是元素的子节点,小于等于childNodes如element.children.length; element.children[0]
11.4.3 contains()方法,某节点是不是另一个节点后代
document.documentElement.contains(document.body);//body是不是html后代
DOM Level3 compareDocumentPosition(),确定节点关系——
1无关 2居前 4居后 8包含 16被包含
var result = document.documentElement.compareDocumentPosition(doucument.body);
P319有一段例子
11.4.4插入文本innerText、outerText
1、innerText:读取时由浅入深拼接文本含换行,写入时删除所有替换为文本值
永远只生成当前节点的子文本节点,为了只生成一个就必须对文本编码div.innerText = div.innerText,从而文本节点除掉了HTML标签,还有textContent属性可以set get
2、outerText:删除完全取代调用outerText的元素,无法访问
11.4.5 滚动
scrollIntoViewIfNeeded(alignCenter)当前元素不可见时,让他进入浏览器视口
document。images[0].scrollIntoViewIfNeeded();
scrollByLines(lineCount)滚动行高比如5行-5行
scrollBypages(pageCount)-1就是回滚一页
11.5小结
扩展了1:Selectors API(querySelector()、querySelectorAll())
2:Element Traversal定义额外属性,更方便从一个元素跳转另一个
3:HTML5:属性、管理焦点、设置字符集、滚动页面设置API
12 DOM2和DOM3
DOM1定义了HTML和XML的底层结构,DOM2和DOM3引入了更多交互能力、支持高级XML特性
12.1 DOM变化
var supportsDOM2Core= document.implementation.hasFeature("core","2.0");
core 3.0 HTML 2.0 Views 2.0 XML 2.0
12.1.1 针对XML命名空间
XML命名空间,不同XML文档元素可以混合在一起共同构成格式良好的文档避免命名冲突:
<html xmlns="http://www.w3.org/19999xhtml"></html>其中所有元素视为命名空间元素
<xhtml:html xmlns:xhtml="..."><xhtml:html>为XHTML命名空间定义了一个xhtml前缀,并要求所有XHTML元素以该前缀开头。如果在混合两种语言的命名空间,可以使得内含另一个命名空间的代码也是有效的
1.Node类型变化
localName不带前缀;namespaceURI;prefix默认null
...<body>
<s:svg xmlns:s="http:.../svg" version="1.1" viewBox=...></s:svg>
</body>...
localName是svg,tagName是s:svg,namespaceURI是“”中的内容,prefix是s
DOM3:
document.body.isDefaultNamespace("http://www..../xhtml");//true
svg.lookupPrefix("http://www..../xhtml");//"s"取得关联元素
svg.lookupNamespaceURI("s");//"http://www..../xhtml"
2.Document类型的变化
createElementNS(namespaceURI,tagName)创建新元素
createAttributeNS(namespaceURI,attributeName)创建命名空间的新特性
getElementsByTagNameNS(URI,tagName)返回命名空间明明元素的NodeList
3.Elements类型的变化
DOM2:getAttributeNS()取得特性
getAttributeNodeNS()节点 getElementsByTagNameNS()节点nodelist hasAttributeNS() removeAttributeNS() setAttributeNS()设特性值 setAttributeNodeNS()
4.NamedNodeMap类型变化
getNamedItemNS(URI,localName) remove.. set..
12.1.2其他方面变化
DOM2级核心中发生变化,倾向于确保API可靠性完整性
1、DocumentType类型变化
publicId、systemId、internalSubset
类型声明举例:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"这就是publicId
"http://www.w3.org/TR/html4/strict.dtd"这就是systemId
[<!ELEMENT name (#PCDATA)>]这就是internalSubset>
document.doctype.publicId
2、Doucument类型变化
importNode()从一个文档中取得一个节点导入到另一个文档
var newNode = document.omportNode(oldNode,true);true复制子节点
document.body.appendChild(newNode);
document.defaultView指向拥有指定文档的窗口/document.parentWindowIE中的
var doctype = document.implement.createDocumentType(...)创建新文档类型
var doc = document.implementation.createDocument(..,doctype);
也有创建一个完整HTML文档
var htmldoc = document.implementation.createHTMLDocument("New Doc"); aler(htmldoc.title/body)
3.Node类型的变化
DOM2:document.body.isSupported("HTML","2.0")
DOM3: div1.isSameNode(div2); div1.isEqualNode(div2);
document.body.setUserData("name","Nicholas",function(){}); getUserData()
4.框架变化
DOM2:contentDocument(原有的HTMLFrameElement,HTMLIFrameElement)(IE8:contentWindow.document)
12.2样式
HTML:<link/>包含外部样式表样式 <style/>嵌入式样式 style特性针对特定元素样式
document.implementation.hasFeature("CSS","2.0") CSS2 2.0
12.2.1访问元素的样式
css:background-image style.backgroundImage
color style.color
display style.display
font-family style.fontFamily
myDiv.style.backgroundColor = "red" width "100px" border "1px solid black"
1.DOM样式属性和方法
DOM2:cssText length parentRule getPropertyCssValue getPropertyPriortiy getPropertyValue item removeProperty setProperty
myDiv.style.cssText = "width: 25px;height: 100px;background-color:green";
prop = myDiv.style[i];//myDiv.style.item[i];
value = myDiv.style.getPropertyValue(prop);//alert(prop+":"+value)
value.myDiv.style.getPropertyCSSValue(pro);//alert(prop+":"+value.cssText+"("+value.cssValeuType+")")
2.计算的样式
style不包含被覆盖的样式,DOM2级样式:document.defaultView getComputedStyle(元素,伪元素字符串如:after)
var computeStyle = document.defaultView.getComputedStyle(myView,null);//alert(computeStyle.backgroundColor);
IE浏览器:var computedStyle = myDiv.currentStyle;//alert(..width);
12.2.2操作样式表
CSSStyleSheet类型比较样式表,比HTMLLinkElement HTMLSytleElement更通用(前者只读,后者可修改)
var supportsDOM2StyeleSheets = document.implementation.hasFeature("StyleSheets","2.0");
StyleSheet(link style)属性:disabled其他都只读 href<link>的URL media
ownerNode当前用户表节点不支持导入 parentStyleSheet导入情况下节点 title owner中title属性值 type:"type/css"
cssRules规则集合 ownerRule deleteRule(index) insertRule(rule,index)
举例:documents.stylesheets.length..; sheet = documents.styleSheets[i],alert(sheet.href)
1.CSS规则
CSSRule→CSSStyleRule样式信息:cssText常用 parentRule parentStyleSheet selectorText常用 style常用 type
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
var rule = rules[0]
alert(rule.selectorText);//aleert(rule.style.cssText);//rule.style.backgroundColor = "red";所有元素都影响
2.创建规则insertRule()方法
sheet.insertRule("body: {background-colorL silver}",0);//IE用addRule()
如果添加规则过多,建议用第十章动态加载样式表
3.删除规则
DOM:sheet.deleteRule(0)//IE:sheet.removeRule(0);
12.2.3元素大小
1.偏移offset量dimension
offsetHeight占用的上下空间 offsetWidth占用的左右空间 offsetLeft左边腾出距离 offsetTop腾出的向上距离 offsetParent距离最近具有大小的元素?td的..是table
2.客户区
clientWidth clientHeight 内边距+内容的大小
document.body.clientWidth
document.documentElement.clientWidth(IE7之前)
3.滚动大小
html没有执行任何代码也能自动滚动条,另一些元素需要通过CSS的overflow属性设置滚动
scrollHeight总高 scrollWidth总宽 scrollLeft滚动条左侧隐藏宽 scrollTop上侧隐藏高
document.documentElement.scrollHeight;element.scroll = 0;滚回到顶部
4.确定元素大小
getBoundingClientRect()返回一个对象(包含left top right bottom) 实现:写一个跨浏览器函数
12.3 遍历
DOM2:辅助顺序遍历DOM结构——NodeIterator TreeWalker对DOM结构进行深度优先遍历 document.createNodeIterator()
12.3.1NodeIterator
document.createNodeIterator():root whatToShow位掩码 filter过滤器确定访问哪些节点 entityReferenceExpansion
var whatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
NodeIterator类型两个主要方法nextNode()和previousNode()
var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT,null,false);
var node = iterator.nextNode();
alert node.tagName;//node = node.nextNode();
过滤器方法:var filter = function(){
return node.tagName.toLowerCase() == "li"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
};
var iterator = ...(document,NodeFilter.SHOW_ELEMENT,filter,false);//这样迭代器只返回li元素
12.3.2 TreeWalker
TreeWalker是NodeIterator的高级版本,除了nextNode(),previousNode(),还有:
parentNode() firstChild() lastChild() nextSibling() nextSibling() previousSibling()
var walker = document.createTreeWalker(div,NodeFilter.SHOW_ELLEMENT,filter,false);
这里返回值除了FILTER_ACCEPT FILTER_SKIP,还有FILTER_REJECT(跳过相应节点及其子树),不用过滤器也能定位位置灵活。
12.4 范围range接口
DOM2:range接口,IE专有方式定义
12.4.1DOM中的范围
var supportRange = document.implementation.hasFeature("Range","2.0");
var alsoSupportRange = (typeof document.createRange == "function");
var range = document.createRange();
range实例:startContainer endContainer startOffset endOffset
commonAncestorContainer:startContainer endContainer 共同祖先节点中最深的那个
1.DOM范围实现简单选择
selectNode() selectNodeContents()选择节点的内容,其中的startContainer endContainer startOffset endOffset commonAncestorContainer是什么?
setStartBefore(refNode) setStartAfter() setEndBefore() setEndAfter()其中节点变化有点多需要理解
2.DOM范围实现复杂选择
setStart() setEnd()
var range1 = document.createRange();//选择节点需要用节点在父节点子集的索引
var range2 = document.createRange();//选择内容不用计算什么
range1.setStart(p1.parentNode,p1Index);
range1.setEnd(p1.parentNode,p1Index+1);
range2.setStart(p1,0);
range2.setEnd(p1,p1.childNodes.length);
高级:range.setStart(helloNode,2);range.setEnd(worldNode,3);选择之后就能对选区操作
<p><b>Hello</b>world!</p>
3.操作DOM范围中的内容
range.deleteContents();<p><b>He</b>rld!</p>//1.删除
var fragment = rang.extractContents();//2.不仅可以删除,还能保留插入到文档的其他地方
p1.parentNode.appendChild(fragment);
//<p><b>He</b>rld!</p>
//<b>llo</b>wo
var fragment = rang.cloneContents()//3.创建副本
4.插入DOM范围中的内容
var span = document.createElement("span");
span.style.color = "red";
span.appendChild(document.createTextNode("Inserted Text"));
range.insertNode(span);//4.1内部插入
range.surroundContents(span);//4.2环绕插入,比如范围选区加入黄色背景
5.折叠DOM范围
range.collapse(true);//alert(..~..)折叠到起点,成功,setStartAfter setEndBefore之间什么都没有
6.比较DOM范围
compareBoundaryPoints()
Range.START_TO_START(0)//比较第一个范围、第二个范围的起点
Range.START_TO_END(1)//比较第一个范围的起点和第二个范围的终点
Range.END_TO_END(2)
Range.END_TO_STAET(3)
方法可能的返回值:第一个点在第二个点之前-1 相等0 第一个在第二个点后面1
alert(range1.compareBoundaryPoints(Range.END_TO_END,range2));//1
7.复制DOM范围 range.clondRange();
8.清理DOM范围
range.detach();//从文档中分离 range = null;//解除引用
12.4.2 IE8及更早版本的范围(IE9支持)
IE8及早期版本支持文本范围:var range = document.body.createTextRange();
1.实现简单选择
var found = range.findText("Hello");//true
range.moveToElementText(p1);//类似与selectNode()
alert(range.htmlText);range.parentElement();
2.IE实现复杂的选择
moveStart() moveEnd()
move()会折叠范围起点终点重合,然后移动 expand():任何部分选择的文本全部选中
range.move("character",5);
range.moveStart("word",2);//起点移动2个单词,“character”字符“word”单词
range.moveEnd("character",1);终点移动1个字符“sentence”句子“textedit”移动到当前范围选区的起始位置
3.操作IE范围中的内容
range.findText("Hello");
range.pasteHTML("<em>Howdy</em>");//粘贴
4.折叠 range.collapse(true);
5.比较IE范围
IE:compareEndPoints()类似DOM:compareBoundaryPoints():
"StartToStart"StartToEnd""EndToEnd""EndToStart"
alert(range1.compareEndPoints("StartToStart", range2));
isEqual() a.inRange(b):b在a里面
6.复制IE范围 var newRange = range.duplicate();
12.5 小结
DOM2样式:每个元素都有一个关联的style对象;getComputedStyle();document.styleSheets集合访问样式表
DOM2遍历、范围:NodeIterator前后移动、TreeWalker结构的各个方向上移动;范围是选择DOM相关部分,在执行相应操作的一个手段
13事件
JavaScript与HTML交互事件实现,观察员模式
13.1 事件流
描述从页面中接收事件的顺序
13.1.1事件冒泡
IE:事件冒泡event bubbling,事件由最深节点向上传播
13.1.2事件捕获
不太具体的节点比具体节点更早接收到对象
13.1.3DOM事件流
DOM2级事件:事件捕获阶段、处于目标阶段、事件冒泡阶段
13.2 事件处理程序 响应事件的函数事件侦听器
13.2.1HTML事件处理程序
event变量可以直接访问事件对象:<input type="button" value="Click me" onclick="event.type">
this等同于事件的目标元素:..onclick="this.value"
可以如下扩展作用域:
function(){
with(document){
with(this){//元素属性值}
}
}
..onclick="value";//这样方便访问自己的属性,等价于上面的
如果元素是表单输入
function(){with(document){with(form){with(this){//元素属性值}}}}
onclick="alert(username.value)"//无需引用表单元素就能访问其他表单字段
1.因为加载时差的捕获错误:onclick="try{showMessage();}catch(ex){}"
2.HTML与JavaScript紧密耦合需要改动两个地方,HTML事件处理程序遭到抛弃
13.2.2DOM0级事件处理程序
var btn = document.getElementById("myBtn");
btn.onclick = function(){alert("clicked");};
DOM0级事件处理程序是元素的方法,在作用域运行,也即this引用当前元素:
btn.onclick = function(){alert(this.id)};//"myBtn"
13.2.3DOM2级事件处理程序
DOM2:指定、删除事件处理程序:addEventListener() removeEventListener()
btn.addEventListener("click",function(){alert(this.id);},false);//一
false表明事件在冒泡阶段触发(兼容性考虑一般用这一种),如果true表明在捕获阶段触发
可以添加两个事件处理程序://一
btn.addEventListener("click",function(){alert("Hello World");},false);//二,按照一二的顺序触发
这种添加只能用removeEventListener()移除,由于//二匿名,所以无法移除:
var handler = function(){alert(1)};
btn.addEventListener("click",handler ,false);
btn.removeEventListener("click",handler ,false);//移除
13.2.4 IE事件处理程序
IE:attachEvent() detachEvent()
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick",function(){alert(this.id)});//只用两个参数,只支持冒泡阶段处理//onclick而不是click
重要区别:IE中作用域是全局,DOM中是元素作用域,所以this等于window
btn.attachEvent("onclick",function(alert(this == window);){});//true
btn.attachEvent("onclick",function(alert("clicked!");){});//一
btn.attachEvent("onclick",function(alert("Hello World");){});//二,按照先二后一的反顺序触发
detachEvent用法相同
13.2.5跨浏览器的事件处理程序
可以使用能隔离浏览器差异的JavaScript库,也可以自己开发。要保证代码在大多数浏览器一直运行只需关注冒泡处理阶段
第一个要创建addHandler()方法,其职责是视情况使用DOM0、2、IE方法添加事件。属于EventUtil的对象,与之对应removeHandler()
var EventUtil = {//用能力检测实现跨浏览器的事件处理程序13.2.5
addHandler:function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler,false);
}else if(element.attachEvent){
element.attachEvent("on"+type,handler);
}else{
element["on"+type] = handler;
}
},
removeHandler:function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler,false);
}else if(element.detachEvent){
element.detachEvent("on"+type,handler);
}else{
element["on"+type] = null;
}
}
}
13.3 事件对象
触发DOM事件产生event事件对象,包含所有事件有关的信息
13.3.1 DOM中的事件对象
var btn = document.getElementById("myBtn");//下面会传入到event对象当中
btn.onclick = function(){alert(event.type)};//"click"
btn.addEventListener("click",function(){alert(event.type);},false);//click
event包含的属性方法:bubbles事件是否冒泡、cancelable/currentTarget、defaultPrevented detail eventPhase
preventDefault() stopImmediatePropagation() stopPropagation()
target trusted type被触发事件的类型 view(与事件关联的抽象视图,等同于发生时间的window对象)
.:this始终等于currentTarget的值,target只包含事件的实际目标,如果事件处理程序只给了目标元素,则三者包含相同的值
btn.onclick = function(){
alert(event.currentTarget == this);//true
alert(event.target == this);}
document.body.onclick = function(){
alert(event.currentTarget == document.body);
alert(this == document.body);
alert(event.target == document.getElementById("myBtn"));//true事件处理程序存在于按钮的父节点中,所以这些值不是全相同的
}
var handler = function(event){
switch(event.type){//需要一个函数处理多个事件,可以使用type属性
case "click": alert("clicked");break;
case "mouseOver": event.target.style.backgroundColor = "red";break;
case "mouseOut": event.target.style.backgroundColor = "";break;
}
};
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;
var link = document.getElementById("myLink");
myLink.onclick = function(){
event.preventDefault();//阻止默认方法,前提是cancelable设置为true
};
btn.onclick = function(event){
alert("clicked");
event.stopPropagation();//阻止冒泡触发接下来的事件
};
document.body.onclick = function(event){
alert("body clicked")
};
btn.onclick = function(event){
alert(event.eventPhase);//2 处于目标阶段 按钮上注册
};
document.body.addEventListener("click",function(event){
alert(event.eventPhase);//1 添加(捕获阶段)到body首先被执行
},false);
document.body.onclick = function(event){
alert(event.eventPhase);//3 冒泡最后被触发的事件处理程序
};
13.3.2IE中的事件对象
DOM0级方法添加,作为window对象的一个属性 var event = window.event;
如果用attachEvent()添加,则有一个event作为参数传入,可以直接用
如果用HTML指定可以<input type="button" value="click" onclick="alert(event.type)">
cancelBubble(设置为true等价stoppropagation()) returnValue(设置为false等价于preventDefault())
srcElement(与target相同,比this要安全所以用它) type
btn.onclick = function(){
alert(window.event.srcElement == this)};//true
13.3.3跨浏览器的事件对象
getEvent:function(){
return event?event:window.event;
},
getTarget:function(){
return event.target|| event.srcElement;
},
preventDefault:function(){
if(event.preventDefault){
return event.preventDefault();
}else{
event.returnValue = false;
}
},
stopPropagation:function(){
if(event.stopPropagation){
return event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
13.4 事件类型
DOM3规定了以下事件:
UI,用户与页面元素交互触发 焦点事件 鼠标事件 滚轮事件
文本事件 键盘事件 合成事件,输入法编辑器触发 变动事件mutation,底层DOM触发
13.4.1 UI事件
DOMActive:元素被键鼠激活(除此之外其他时间都被归类为HTML事件)
load:页面加载完毕触发 unload:卸载触发
abort:用户停止下载,潜入的内容没加载完触发
error:JavaScript错误时在window上面触发
select:用户选择文本框text、textArea中一个或多个字符触发
resize:窗口或框架大小变化
scroll:用户滚动带滚动条的内容
是否支持DOM2规定的HTML事件:
var isSupported = document.implementation.hasFeature("HTMLEvents","2.0");
var isSupportedsd = document.implementation.hasFeature("UIEvents","3.0");
1.load事件
EventUtil.addHandler(window, 'load', function(event){alert("loaded");});
<body onload="alert('loaded')"> //第二种办法,其他比如img上面也可以
<img src="smile.gif" onload="alert('loaded')"/>//一
EventUtil.addHandler(window, 'load',function(event){//二,一二等价
var img = document.createElement('img');
EventUtil.addHandler(img, 'load', function(event){
event = EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src);
});
document.body.appendChild(img);
img.src = "smile.gif";
});
script元素也支持load事件
EventUtil.addHandler(window, 'load',function(){//添加一个引用
var link = document.createElement('link');
link.type = "css/text";
link.src = "styleSheet";
EventUtil.addHandler(link, 'load',function(event){
alert('css loaded');
});
link.href = 'example.css';
document.getElementsByTagName("head")[0].appendChild(link);
});
2.unload事件,
EventUtil.addHandler(window, 'unload', function(event){alert("unloaded");});//一切结束之后才会触发,此时操作DOM或元素样式就导致错误
<body onunload="alert('unloaded')">
3.resize事件
实现同上,由于可能不断触发,所以不要在这个事件处理程序中加入大计算量的代码
4.scroll事件 同样可能不断触发
EventUtil.addHandler(window, 'scroll',function(){
if(document.compatMode == "CSS1Compat"){
alert(document.documentElement.scrollTop);
}else{
alert(document.body.scrollTop);
}
});
13.4.2 焦点事件
blur失去焦点,所有浏览器支持,不冒泡 focus元素获得焦点,所有浏览器支持,不冒泡
(DOMFocusIn元素获得焦点,冒泡 DomFocusOut 只有Opera支持,DOM3废弃)
focusin获得焦点,冒泡 focusout
13.4.3 鼠标与滚轮事件
DOM3:click dblclick mousedown任意鼠标按钮
mouseenter光标首次从外部移内 mouseleave mousemove元素内部重复移动
mouseout指针位于元素上方移入另一个外部/子元素 mouseover元素外部首次移入另一个元素边界内 mouseup释放鼠标按钮
mousedown+mouseup才有click;两次触发click才有dblclick(dn up clk dn up clk dbclk)
var isSupported = document.implementation.hasFeature("MouseEvents","2.0");//检测是否支持DOM2事件
var isSupported = document.implementation.hasFeature("MouseEvent","3.0");//检测是否支持所有事件 MouseEvent不是MouseEvents
鼠标还有一类滚轮事件
1.客户区坐标位置:clientX clientY(从event中获取,同样可以用addHandler点击触发)
2.页面坐标位置:pageX pageY 页面没滚动,clientX == pageX y == y
var pagX = event.pageX;//直接能获取吗?。。
if(pagX == undefined){
pagX = event.clientX + (document.documentElement.scrollLeft ||
document.body.scrollLeft);}
3.屏幕坐标位置:event.screenX screenY
注意获取事件的时候跨浏览器event = EventUtil.getEvent(event);
4.修改键
var div = document.getElementById('myDiv');
EventUtil.addHandler(div, 'click', function(event){
event = EventUtil.getEvent(event);
var keys = new Array();
if(event.shiftKey) keys.push('shift');
if(event.ctrlKey) keys.push('ctrl');
if(event.altKey) keys.push('alt');
if(event.metaKey) keys.push('meta');
alert("Keys: " + keys);});
5.相关元素relatedTarget
鼠标从div移动到body,div上mouseout,相关元素是body。body上mouseover,相关元素是div(IE中对应的是fromElement toElement)
var EventUtil = {
getRelatedTarget: function(event){
if(event.relatedTarget){
return event.relatedTarget;
}else if(event.toElement){
return event.toElement;
}else if(event.fromElement){
return event.fromElement;
}else{
return null;}}};
6.鼠标按钮
鼠标按钮按下时触发click事件,mouseup mousedown事件的event对象有一个button属性
DOM:button == 0主按钮 1中间按钮 2次按钮
IE8及其之前:0没按 1主 2次 4中间(0~7都有)
var EventUtil = {
getButtion: function (event) {
if(document.implementation.hasFeature("MouseEvents","2.0")){
return event.button;
}else{
switch (event.button){
case "0":
case "1":
case "3":
case "5":
case "7": return "0";
case "2":
case "6": return "2";
case "4": return "1";}}}};
7.更多事件信息
DOM2:detail属性记录单击多少次,鼠标在dn和up间移动了位置,detail被重置为0
IE:altLeft是否按下了alt键 ctrlLeft offSetX光标相对于目标元素边界的x坐标 offSetY shiftLeft
8.鼠标滚轮事件
mousewheel在任何元素上触发,最终冒泡到document(IE8)或window对象,还有一个wheelDelta属性120的倍数-120表示向后滚动
Operaa 9.5之前的版本中,wheelDelta的值是颠倒的:
var delta = ((client.engine.opera && client.engine.version < 9.5)?
-event.wheelDelta : event.wheelDelta);
Firefox支持DOMMouseScroll的事件,鼠标滚动时触发,滚轮信息保存在detail中,3和-3的倍数
var EventUtil = {
getWheelData: function (event) {
if(event.wheelDelta){
return (client.engine.opera && client.engine.version < 9.5)?
-event.wheelDelta : event.wheelDelta;
}else if(even.detail){
return -even.detail * 40;}}};
9.触摸设备
不支持dblclick
轻击可单击元素会触发mousemove事件,如果内容变化将不会有其他事情发生;如果屏幕没有变化,依次发生mousedown mouseup click事件。轻击不可单击元素不会触发任何事件。
mousemove触发mouseover mouseout事件。两个手指放在屏幕上,页面随手指滚动时触发mousewheel和scroll事件
10.无障碍性问题
不建议使用click以外的其他鼠标事件来展示功能或引发代码执行。
使用click事件执行代码,onmousedown速度虽然快,但是屏幕阅读器无法触发mousedown事件
不要用onmouseover向用户显示新的选项,屏幕阅读器无法触发(click = onmousedown+onmouseup)
不用dblclick触发重要事件,键盘无法触发

浙公网安备 33010602011771号