Javascript高级程序设计第十三章(事件)

来源:互联网 发布:python 创建嵌套字典 编辑:程序博客网 时间:2024/04/28 16:05

背景:DOM2级规范开始尝试以一种符合逻辑的方式来标准化DOM事件。IE9+、Firefox、Opera、Safari和Chrome全都已经实现了“DOM2级事件”模块的核心部分。IE8是最后一个仍然使用其专有事件系统的主要浏览器。


1.事件捕获和事件冒泡都是以window对象开始或者结束


2.“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

即使“DOM2级事件”规范明确要求捕获阶段不会涉及事件目标,但IE9+、Safari、Chrome、Firefox和Opera 9.5及更高版本都会在捕获阶段触发事件上的事件。结果,就是有两个机会在目标对象上面操作事件。IE8-不支持DOM事件流

背景:“DOM3事件”规定了以下几类事件,如UI事件、焦点事件、鼠标事件、滚轮事件、文本事件、键盘事件、合成事件、变动(mutaion)事件、变动名称事件(IE8-不支持任何变动事件)。DOM3事件模块在DOM2级事件模块基础上重新定义了这些事件,也加入了一些事件。包括IE9在内的所有主流浏览器都支持DOM2级事件。IE9也支持DOM3事件


3.下面这些事件都与window对象或表单控件相关

load:当页面完全加载后在window上面触发、当图像加载完毕时在<img>元素上面触发等

unload:当页面完全卸载后再window上面触发等。下面说说unload和beforeload的区别

onbeforeunload 是正要去服务器读 取新的页面时调用,此时还没开始读取;而onunload则已经从服务器上读到了需要加载的新的页面,在即将替换掉当前页面时调用。

error:当发生Javascript错误时在window上面触发、当无法加载图像时在<img>元素上面触发等

select:当用户选择文本框<input>或<textarea>中的一或多个字符时触发

resize:当窗口或框架的大小时在window或框架上面触发

scroll:当用户滚动带滚动条的元素中的内容,在该元素上面触发

注意:在window上面发生的任何事件都可以再<body>元素中通过相应的特性来指定,因为在HTML中无法访问window元素。实际上,这只是为了保证向后兼容的一种权宜之计。


4.图像元素只要设置了src属性就会开始下载,与图像不同,只有在设置<script>元素的src属性并将该元素添加当文档后,才会开始下载Javascript文件。所以<script>元素中指定src属性和指定事件处理程序的先后顺序就不重要了。同理,<link>元素。


5.unload事件注意点:这个事件在文档被完全卸载后出发,那么在页面加载后存在的那些对象,此时就不一定存在了。利用这个事件最多的情况是清楚引用,以避免内存泄露。


6.focus事件和blur事件都不会冒泡,它们相应冒泡事件分别为:focusin 和 focusout,兼容性没问题


7.click事件:在用户单击主鼠标按钮(一般是左边按钮)或者按下回车键触发,双击主鼠标按钮触发dblclick事件。而mousedown事件是用户按下了任意鼠标按钮时触发


8.背景①:DomContentLoaded事件则在形成完整的DOM树之后就会触发,不理会图像、Javascript文件、CSS文件或其他资源是否已经下载完毕。与load事件不同不同,DOMContentLoaded 支持在页面下载的早起添加事件处理程序,这也就以为着用户能够尽早与页面进行交互。IE9+等主流浏览器都支持这个事件。对于,不支持DOMContentLoaded 事件,我们建议在页面加载期间设置一个事件为0毫秒的超时调用。

setTimeout(function(){

//.....

},0);

上面这段代码的意思:在当前Javascript 处理完成后立即运行这个函数。在页面下载和构建期间,只有一个Javascript 处理过程,因此超时调用会在该过程结束时立即出发。至于这个与DOMContentLoaded 被触发的时间能否同步,主要还是却绝与用户使用的浏览器和页面中的其他代码。为了确保这个方法有效,必须将其作为页面中的第一个超时调用;几遍如此,也还是无法保证在所有环境中该超时调用一定会早于 load事件 触发。

背景②:readystatechange事件。

IE为DOM事件文档中的某些部分提供了readystatechange事件。这个事件的目的是提供与文档或元素(script元素、link元素)的加载状态有关的信息。

每个对象都有一个一个readystate属性,可能包含下列5个值中的一个。

uninitialized(未初始化):对象存在但尚未初始化

loading(正在加载):对象正在加载数据。

interactive(交互):可以操作对象了,但还没有完成加载

complete(完成):对象已经加载完毕。

代码如下:添加事件没有跨兼容性,自行理解

document.addEventListner("readystate",function(){  if(document.readyState == "interactive" || document.readyState == "complete"){    document.removeEventLIstner("readystate".arguments.callee,false);   //.....  }})
当然这事件也可以用到link元素和script元素

代码如下:

EventUtil.addHandler(window, "load", function(){                    //create a new <script/> element.            var script = document.createElement("script");            EventUtil.addHandler(script, "readystatechange", function(event){                event = EventUtil.getEvent(event);                var target = EventUtil.getTarget(event);                if (target.readyState == "loaded" || target.readyState == "complete"){                    EventUtil.removeHandler(target, "readystatechange", arguments.callee);                    alert("Script Loaded");                }            });            script.src = "example.js";            document.body.appendChild(script);                        //create a new <link/> element            var link = document.createElement("link");            link.type = "text/css";            link.rel= "stylesheet";                        EventUtil.addHandler(link, "readystatechange", function(event){                event = EventUtil.getEvent(event);                var target = EventUtil.getTarget(event);                if (target.readyState == "loaded" || target.readyState == "complete"){                    EventUtil.removeHandler(target, "readystatechange", arguments.callee);                    alert("CSS Loaded");                }            });            link.href = "example.css";            document.getElementsByTagName("head")[0].appendChild(link);                    });

要想跨兼容性实现JQUERY中的$(document).ready(function(){}),戳此链接:JS原生方法实现Jquery ready() 方法


9.内存和性能

背景:在Javascript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。导致这一问题的原因是多方面的。首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差。其次,必须实现指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。

解决方法:①事件委托,原理是访问父元素比目标元素快,还有在页面中设置事件处理程序所需的时间更少。只添加一个事件处理程序所需的DOM引用更少,所花的时间更少,整个页面占用的内存也更少,能够提升整体性能

事件委托有两种办法提高性能,一个是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

代码如下:

(function(){        var list = document.getElementById("myLinks");                EventUtil.addHandler(list, "click", function(event){            event = EventUtil.getEvent(event);            var target = EventUtil.getTarget(event);                    switch(target.id){                case "doSomething":                    document.title = "I changed the document's title";                    break;                        case "goSomewhere":                    location.href = "http://www.wrox.com";                    break;                        case "sayHi":                    alert("hi");                    break;            }        });    })();

②某个DOM对象上的多个不同事件指定一个事件处理程序,原理是减少页面占用内存

代码如下:

function handleTouchEvent(event){                        //only for one touch            if (event.touches.length == 1){                        var output = document.getElementById("output");                switch(event.type){                    case "touchstart":                        output.innerHTML = "Touch started (" + event.touches[0].clientX + "," + event.touches[0].clientY + ")";                        break;                    case "touchend":                        output.innerHTML += "<br>Touch ended (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";                        break;                    case "touchmove":                        event.preventDefault();  //prevent scrolling                        output.innerHTML += "<br>Touch moved (" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")";                        break;                }            }        }                document.addEventListener("touchstart", handleTouchEvent, false);        document.addEventListener("touchend", handleTouchEvent, false);        document.addEventListener("touchmove", handleTouchEvent, false);

③移除事件处理程序 原理是:每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的Javascript

代码之间就建立了一个连接。这种连接越多,页面执行起来就越慢。

因此,建议在浏览器卸载页面之前移除页面红的所有事件处理程序。因此,只要是通过onload时间处理程序添加的东西,最后都要通过onunload事件处理程序将它们移除。


0 0