JavaScript之事件操作

一、事件流   
    1.含义:事件流描述的是从页面中接收事件的顺序
    2.事件冒泡:是有ie提出的,即事件开始时是由具体的元素接受,然后逐步向上传播到不具体的元素
    3.事件捕获:是有NC提出的,即事件开始是有不具体的元素接受,然后逐步向下传播到具体的元素上
    4.DOM事件流:“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
二、事件处理程序
    1.HTML事件处理程序
        a.在标签中直接定义
        <script type="text/javascript">
        function showMessage(){
        alert("Hello world!");
        }
        </script>
        <input type="button" value="Click Me" onclick="showMessage()" />
        b.缺陷    
            ①存在一定的时差 
            ②这种事件的作用链在不同的浏览器中会造成不同的结果
    2.DOM0级事件处理程序
        var btn = document.getElementById("myBtn");
        btn.onclick = function(){
            alert("Clicked");
        };
    3.跨浏览器
        var EventUtil = {
            // 添加事件监听
            addEvent : function (element, type, handler) {
                if (element.addEventListener)
                {
                    element.addEventListener(type, handler, false);
                } else if (element.attachEvent)
                {
                    element.attachEvent("on" + type, handler);
                }
            },
            // 解除事件监听
            delEvent : function (element, type, handler) {
                if (element.removeEventListener)
                {
                    element.removeEventListener(type, handler, false);
                } else if (element.detachEvent)
                {
                    element.detachEvent("on" + type, handler);
                }
            }
        }
三、事件对象
    var EventUtil = {
        // 获取event对象
        getEvent : function (event) {
            return event ? event : window.event;
        },
        // 获取事件源
        getTarget : function (event) {
            return  event.target || event.srcElement;
        },、
        // 阻止默认行为
        stopDefault : function (event) {
            if (event.preventDefault)
            { 
                event.preventDefault();
            } else {
                event.returnValue = false;
            }
        },
        // 阻止冒泡
        stopBubble : function (event) {
            if (event.stopPropagation)
            {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }
    }
四、事件类型
    1.UI事件,是指那些不一定和用户操作有关的事件,如load  unload  DOMActivate  error等
        ①判断浏览器是否支持DOM2 HTML事件和DOM3UI事件
            var isSupported = document.implementation.hasFeature("UIEvent", "3.0"); 
        ②load事件,当页面加载完成后(img js css)触发的事件
            a.加载img
                EventUtil.addHandler(window, "load", function(){
                    var image = document.createElement("img");
                    EventUtil.addHandler(image, "load", function(event){
                        event = EventUtil.getEvent(event);
                        alert(EventUtil.getTarget(event).src);
                    });
                    document.body.appendChild(image);
                    image.src = "smile.gif";
                });
            b.加载JS
                EventUtil.addHandler(window, "load", function(){
                    var script = document.createElement("script");
                    EventUtil.addHandler(script, "load", function(event){
                        alert("Loaded");
                    });
                    script.src = "example.js";
                    document.body.appendChild(script);
                });
            c.加载CSS
                EventUtil.addHandler(window, "load", function(){
                    var link = document.createElement("link");
                    link.type = "text/css";
                    link.rel= "stylesheet";
                    EventUtil.addHandler(link, "load", function(event){
                        alert("css loaded");
                    });
                    link.href = "example.css";
                    document.getElementsByTagName("head")[0].appendChild(link);
                });
        ②Unload事件,当从一个页面切换到另一个页面,就会被调用,常常用于清除引用,避免内存泄露
            EventUtil.addHandler(window, "unload", function(event){
                alert("Unloaded");
            });
        ③Resize事件,当窗口大小发生改变时触发的事件
            EventUtil.addHandler(window, "resize", function(event){
                alert("size changed");
            });
        ④Scroll事件,表示页面元素的变化,会在文档被滚动的时候触发。
            EventUtil.addHandler(window, "scroll", function(event){
                if (document.compatMode == "CSS1Compat"){
                    alert(document.documentElement.scrollTop);
                } else {
                    alert(document.body.scrollTop);
                }
            });
    2.焦点事件,主要为Blur()和focus()方法
        ①判断浏览器是否支持焦点事件
            var isSupported = document.implementation.hasFeature("FocusEvent", "3.0");
        ②获焦与失焦
            EventUtil.addHandler(txt, "focus", function(event){
                alert("focus");
            });
            EventUtil.addHandler(txt, "blur", function(event){
                alert("blur");
            });
    3.鼠标与滚轮事件
        ①判断浏览器是否支持鼠标事件
            var isSupported = document.implementation.hasFeature("MouseEvents", "3.0");
        ②客户区坐标位置
            var div = document.getElementById("myDiv");
            EventUtil.addHandler(div, "click", function(event){
                event = EventUtil.getEvent(event);
                alert("Client coordinates: " + event.clientX + "," + event.clientY);
            });
        ③页面坐标位置
            var div = document.getElementById("myDiv");
            EventUtil.addHandler(div, "click", function(event){
                event = EventUtil.getEvent(event);
                var pageX = event.pageX,
                pageY = event.pageY;
                if (pageX === undefined){
                    pageX = event.clientX + (document.body.scrollLeft ||
                    document.documentElement.scrollLeft);
                }
                if (pageY === undefined){
                    pageY = event.clientY + (document.body.scrollTop ||
                    document.documentElement.scrollTop);
                }
                alert("Page coordinates: " + pageX + "," + pageY);
            });
        ④屏幕坐标位置
            var div = document.getElementById("myDiv");
            EventUtil.addHandler(div, "click", function(event){
                event = EventUtil.getEvent(event);
                alert("Screen coordinates: " + event.screenX + "," + event.screenY);
            });
        ⑤修改键
            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.join(","));
            });
        ⑥相关元素。例如,将鼠标的光标放在一个div上,那么当他触发事件mouseout时,它的主元素时div,而相关元素则是body;当他触发的事件为mouseover时,它的主目标是body,而相关元素时div。
            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;
                    }
                }
            }
        ⑦鼠标按钮
            var EventUtil = {
                getButton : 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;
                        }
                    }
                }
            }
        ⑧滚轮事件
            var EventUtil = {
                getWheelDelta : function (event) {
                    if (event.wheelDelta)
                    {   // opera 9.5以下
                        return (client.engine.opera && client.engine.opera < 9.5) ?
                            - event.wheelDelta : event.wheelDelta;
                    } else {
                        // 火狐
                        return - event.detail * 40;
                    }
                }
            }
    4.键盘与文本事件   keydown   keyup  keypress 和textInput事件
        ①键码,就是按键的码号。用keyCode表示
            var textbox = document.getElementById("myText");
            EventUtil.addHandler(textbox, "keyup", function(event){
                event = EventUtil.getEvent(event);
                alert(event.keyCode);
            });
        ②字符编码
            var EventUtil = {
                getCharCode : function (event) {
                    if (typeof event.charCode == "number")
                    {
                        return event.charCode;
                    } else {
                        return event.keyCode;
                    }
                },
            }
        ③DOM3中添加了一个textInput事件,它不同于keyPress中的textInput事件,它有一个data属性,用于专门识别字符。
            var textbox = document.getElementById("myText");
            EventUtil.addHandler(textbox, "textInput", function(event){
                event = EventUtil.getEvent(event);
                alert(event.data);
            });
    5.事件变动,在DOM结构树发生变化时,会触发一系列的事件
        eg: <body>
                <ul id="myList">
                    <li>Item 1</li>
                    <li>Item 2</li>
                    <li>Item 3</li>
                </ul>
            </body>
        ①删除节点
            EventUtil.addHandler(window, "load", function(event){
                var list = document.getElementById("myList");
                EventUtil.addHandler(document, "DOMSubtreeModified", function(event){
                    alert(event.type);
                    alert(event.target);
                });
                EventUtil.addHandler(document, "DOMNodeRemoved", function(event){
                    alert(event.type);
                    alert(event.target);
                    alert(event.relatedNode);
                });
                EventUtil.addHandler(list.firstChild, "DOMNodeRemovedFromDocument", function(event){
                    alert(event.type);
                    alert(event.target);
                });
                list.parentNode.removeChild(list);
            });
        ③插入节点
            EventUtil.addHandler(window, "load", function(event){
                var list = document.getElementById("myList");
                var item = document.createElement("li");
                item.appendChild(document.createTextNode("Item 4"));
                EventUtil.addHandler(document, "DOMSubtreeModified", function(event){
                    alert(event.type);
                    alert(event.target);
                });
                EventUtil.addHandler(document, "DOMNodeInserted", function(event){
                    alert(event.type);
                    alert(event.target);
                    alert(event.relatedNode);
                });
                EventUtil.addHandler(item, "DOMNodeInsertedIntoDocument", function(event){
                    alert(event.type);
                    alert(event.target);
                });
                list.appendChild(item);
            });
    6.html5事件
        ①ContextMenu事件,用于何时应该显示上下文菜单,以供开发人员自定义菜单
            <body>
                <div id="myDiv">Right click or Ctrl+click me to get a custom context menu.
                Click anywhere else to get the default context menu.</div>
                <ul id="myMenu" style="position:absolute;visibility:hidden;background-color: silver">
                    <li><a href="http://www.nczonline.net">Nicholas’site</a></li>
                    <li><a href="http://www.wrox.com">Wrox site</a></li>
                    <li><a href="http://www.yahoo.com">Yahoo!</a></li>
                </ul>
            </body>
            EventUtil.addHandler(window, "load", function(event){
                var div = document.getElementById("myDiv");
                EventUtil.addHandler(div, "contextmenu", function(event){
                    event = EventUtil.getEvent(event);
                    EventUtil.preventDefault(event);
                    var menu = document.getElementById("myMenu");
                    menu.style.left = event.clientX + "px";
                    menu.style.top = event.clientY + "px";
                    menu.style.visibility = "visible";
                });
                EventUtil.addHandler(document, "click", function(event){
                    document.getElementById("myMenu").style.visibility = "hidden";
                });
            });
        ②Beforeunload事件,在页面卸载之前调用的事件,其中的event.returnValue表示请求留下的语句
            EventUtil.addHandler(window, "beforeunload", function(event){
                event = EventUtil.getEvent(event);
                var message = "I'm really going to miss you if you go.";
                event.returnValue = message;
                return message;
            });
        ③DOMContentLoaded事件表示DOM被加载完后触发
        ④Pageshow和pagehide事件
            当页面再次load一个page时,页面会从缓存bfcache中调用内容中的数据、js文件等,这是会触发一个pageshow的事件。该事件的目标元素随时document,但是要添加到window中去。在单击浏览器的前进和后退的按钮时,可以被调用,此现象被称为往返缓存。
            (function(){
                var showCount = 0;
                EventUtil.addHandler(window, "load", function(){
                    alert("Load fired");
                });
                EventUtil.addHandler(window, "pageshow", function(){
                    showCount++;
                    alert("Show has been fired " + showCount +
                    " times. Persisted? " + event.persisted);
                });
            })();
五、内存和性能
    1.事件委托,只指定一个事件处理程序,就可以管理某一类型的所有事件
        eg: <ul id="myLinks">
                <li id="goSomewhere">Go somewhere</li>
                <li id="doSomething">Do something</li>
                <li id="sayHi">Say hi</li>
            </ul>
            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;
                }
            });

    2.移除事件处理程序   当某些特定的事件处理程序没有必要存在的时候,我们可以解除它的绑定事件函数。
        <div id="myDiv">
            <input type="button" value="Click Me" id="myBtn">
        </div>
        <script type="text/javascript">
            var btn = document.getElementById("myBtn");
            btn.onclick = function(){
                //先执行某些操作
                btn.onclick = null; //移除事件处理程序
                document.getElementById("myDiv").innerHTML = "Processing...";
            };
        </script>
六、模拟事件,即通过javascript来触发事件,而不是通过用户点击操作浏览器触发
    ①步骤
        a.document.createEvent(字符串),创建并返回一个event对象
        b.在创建并返回event对象后,要为其函数进行初始操作
        c.触发事件,用btn.dispatchEvent(event);
    ②模拟单击按钮事件
        // DOM中
        var btn = document.getElementById("myBtn");
        //创建事件对象
        var event = document.createEvent("MouseEvents");
        //初始化事件对象
        event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
        false, false, false, false, 0, null);
        //触发事件
        btn.dispatchEvent(event);
        // Less IE8中
        ar btn = document.getElementById("myBtn");
        //创建事件对象
        var event = document.createEventObject();
        //初始化事件对象
        event.screenX = 100;
        event.screenY = 0;
        event.clientX = 0;
        event.clientY = 0;
        event.ctrlKey = false;
        event.altKey = false;
        event.shiftKey = false;
        event.button = 0;
        //触发事件
        btn.fireEvent("onclick", event);

你可能感兴趣的:(事件流,事件处理程序,事件类型,事件对象,事件委托与事件模拟)