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

lastChildno.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标准模式(如SelectorsAPIcss2css3部分)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实例)

只包含是元素的子节点,小于等于childNodeselement.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插入文本innerTextouterText

1innerText:读取时由浅入深拼接文本含换行,写入时删除所有替换为文本值

  永远只生成当前节点的子文本节点,为了只生成一个就必须对文本编码div.innerText = div.innerText,从而文本节点除掉了HTML标签,还有textContent属性可以set get

2outerText:删除完全取代调用outerText的元素,无法访问

11.4.5 滚动

scrollIntoViewIfNeededalignCenter)当前元素不可见时,让他进入浏览器视口

documentimages[0].scrollIntoViewIfNeeded();

scrollByLineslineCount)滚动行高比如5-5

scrollBypagespageCount-1就是回滚一页

11.5小结

扩展了1Selectors APIquerySelector()、querySelectorAll()

2Element Traversal定义额外属性,更方便从一个元素跳转另一个

3HTML5:属性、管理焦点、设置字符集、滚动页面设置API

12 DOM2DOM3

DOM1定义了HTMLXML的底层结构,DOM2DOM3引入了更多交互能力、支持高级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不带前缀;namespaceURIprefix默认null

...<body>

<s:svg xmlns:s="http:.../svg" version="1.1" viewBox=...></s:svg>

</body>...

localNamesvgtagNames:svg,namespaceURI是“”中的内容,prefixs

 

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类型的变化

DOM2getAttributeNS()取得特性 

getAttributeNodeNS()节点 getElementsByTagNameNS()节点nodelist hasAttributeNS() removeAttributeNS() setAttributeNS()设特性值 setAttributeNodeNS()

4.NamedNodeMap类型变化

getNamedItemNS(URI,localName) remove.. set..  

12.1.2其他方面变化

DOM2级核心中发生变化,倾向于确保API可靠性完整性

1DocumentType类型变化

publicIdsystemIdinternalSubset

类型声明举例:<!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

2Doucument类型变化

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类型的变化

DOM2document.body.isSupported("HTML","2.0")

DOM3: div1.isSameNode(div2);  div1.isEqualNode(div2);

      document.body.setUserData("name","Nicholas",function(){});  getUserData()

4.框架变化

DOM2contentDocument(原有的HTMLFrameElement,HTMLIFrameElement(IE8:contentWindow.document)

12.2样式

HTML:<link/>包含外部样式表样式  <style/>嵌入式样式 style特性针对特定元素样式

document.implementation.hasFeature("CSS","2.0")   CSS2 2.0

12.2.1访问元素的样式

cssbackground-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样式属性和方法

DOM2cssText 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");

StyleSheetlink style)属性:disabled其他都只读 href<link>URL media 

ownerNode当前用户表节点不支持导入 parentStyleSheet导入情况下节点 title ownertitle属性值 type:"type/css"

cssRules规则集合 ownerRule deleteRule(index) insertRule(rule,index)

举例:documents.stylesheets.length..; sheet = documents.styleSheets[i],alert(sheet.href)

1.CSS规则

CSSRuleCSSStyleRule样式信息: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);//IEaddRule()

如果添加规则过多,建议用第十章动态加载样式表

3.删除规则

DOM:sheet.deleteRule(0)//IE:sheet.removeRule(0);

12.2.3元素大小

1.偏移offsetdimension

offsetHeight占用的上下空间 offsetWidth占用的左右空间 offsetLeft左边腾出距离 offsetTop腾出的向上距离 offsetParent距离最近具有大小的元素?td..table

2.客户区

clientWidth clientHeight  内边距+内容的大小

document.body.clientWidth

document.documentElement.clientWidth(IE7之前)

3.滚动大小

html没有执行任何代码也能自动滚动条,另一些元素需要通过CSSoverflow属性设置滚动

scrollHeight总高 scrollWidth总宽 scrollLeft滚动条左侧隐藏宽 scrollTop上侧隐藏高

document.documentElement.scrollHeight;element.scroll = 0;滚回到顶部

4.确定元素大小

getBoundingClientRect()返回一个对象(包含left top right bottom) 实现:写一个跨浏览器函数

12.3 遍历

DOM2:辅助顺序遍历DOM结构——NodeIterator TreeWalkerDOM结构进行深度优先遍历 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

TreeWalkerNodeIterator的高级版本,除了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接口

DOM2range接口,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 相等第一个在第二个点后面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范围

IEcompareEndPoints()类似DOMcompareBoundaryPoints():

"StartToStart"StartToEnd""EndToEnd""EndToStart"

alert(range1.compareEndPoints("StartToStart", range2));

isEqual() a.inRange(b):ba里面

6.复制IE范围  var newRange = range.duplicate();

12.5 小结

DOM2样式:每个元素都有一个关联的style对象;getComputedStyle();document.styleSheets集合访问样式表

DOM2遍历、范围:NodeIterator前后移动、TreeWalker结构的各个方向上移动;范围是选择DOM相关部分,在执行相应操作的一个手段

 

13事件

JavaScriptHTML交互事件实现,观察员模式

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.HTMLJavaScript紧密耦合需要改动两个地方,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事件处理程序

IEattachEvent() 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()方法,其职责是视情况使用DOM02IE方法添加事件。属于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/currentTargetdefaultPrevented 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:用户停止下载,潜入的内容没加载完触发

errorJavaScript错误时在window上面触发

select:用户选择文本框texttextArea中一个或多个字符触发

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 鼠标与滚轮事件

DOM3click  dblclick mousedown任意鼠标按钮

mouseenter光标首次从外部移内 mouseleave mousemove元素内部重复移动 

mouseout指针位于元素上方移入另一个外部/子元素 mouseover元素外部首次移入另一个元素边界内 mouseup释放鼠标按钮

mousedown+mouseup才有click;两次触发click才有dblclickdn 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移动到bodydivmouseout,相关元素是bodybodymouseover,相关元素是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属性

DOMbutton == 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.更多事件信息

DOM2detail属性记录单击多少次,鼠标在dnup间移动了位置,detail被重置为0

IEaltLeft是否按下了alt键 ctrlLeft offSetX光标相对于目标元素边界的x坐标 offSetY shiftLeft

8.鼠标滚轮事件

mousewheel在任何元素上触发,最终冒泡到documentIE8)或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事件。两个手指放在屏幕上,页面随手指滚动时触发mousewheelscroll事件

10.无障碍性问题

不建议使用click以外的其他鼠标事件来展示功能或引发代码执行。

使用click事件执行代码,onmousedown速度虽然快,但是屏幕阅读器无法触发mousedown事件

不要用onmouseover向用户显示新的选项,屏幕阅读器无法触发(click = onmousedown+onmouseup

不用dblclick触发重要事件,键盘无法触发

posted @ 2016-04-04 17:11  miaomiaotab  阅读(172)  评论(0)    收藏  举报