JS-事件及监听知识点

来源:互联网 发布:java常用设计模式leo 编辑:程序博客网 时间:2024/05/30 19:34

一、页面加载事件

主要两种类型:

1、window 的load 事件

页面载入完成时触发

    jQuery(window).bind("load",function() {        $("#signinForm").submit(checkForm);    });


2、DOMContentLoaded

DOM构建完成时触发这个事件,这是图片和样式可能还未完成加载。也就是说这个时间一定会在用户和页面交互之前触发。
并不是所有浏览器都支持DOMContentLoaded,因此jQuery将它融入到了ready()函数,这个函数兼容各个浏览器。
    jQuery.ready(function($)){        $("#myForm").bind("submit", function(){            /*...*/        });    });

更简洁的写法,可以不用ready()函数而直接将回调函数写入jQuery 对象。

    jQuery(function($){        //当页面内容可用时调用    });



二、切换上下文

调用事件回调函数时上下文会发生切换,从局部上下文切换成目标元素上下文:

    new function(){        this.appName = "wem";        document.body.addEventListener("click", function(e){            // 上下文发生改变,因此appName 是undefined            alert(this.appName);        }, false);    };


要想保持原有的上下文,需要将回调函数包装进一个匿名函数,然后用一个引用指向它。

jQuery中提供的proxy函数可解决:

    new function(){         this.appName = "wem";        $("#btnSubmit").click($.proxy(function(){             //这里的this指向proxy函数参数中的this            alert(this.appName);         }, this));    }; 

proxy函数的大致实现方式:

    var proxy = function(func, thisObject){         return (function() {            return func.apply(thisObject, arguments);         });    };

三、委托事件

直接给父元素绑定事件监听,用来检测在其子元素内发生的事件。
能减少事件监听的数量,改善代码性能

所有为元素动态添加的子元素都具有事件监听。

    // 不要这样做,这样会给每个li 元素都添加事件监听(非常浪费)    $("ul li").click(function(){ /* ... */ });

1、原生js的做法:

    // 在ul 列表上做了事件委托    list.addEventListener("click", function(e){        if (e.target.tagName == "LI") {            /* ... */            return false;        }    }, false);

2jquery的实现:

    // 这样只会添加一个事件监听    // 在页面载入完成后添加的li 节点同样可以触发点击事件的回调    $("ul").delegate("li", "click", function(e){        /* ... */        return false;    });

四、自定义事件


自定义事件是很好的解耦代码的处理方法,jQuery 的很多插件都是利用自定义事件来实现。

和内置事件一样,自定义事件同样会沿着DOM 树做冒泡。

1、原生js的做法:

    var myEvent = {};    //创建事件    myEvent.createEvent = function (eventStr, datatype, data) {        var e;        if ( document.createEvent) {            e = document.createEvent('Events'); //W3C创建新事件的写法            e.initEvent(eventStr, true , false);        } else if (document.createEventObject) {            e = document.createEventObject(); //IE的创建新事件的写法        } else {            return null;        }        e.datatype = datatype;        e.data = data;        return e;    };    //触发事件    myEvent.send = function (target, eventStr, datatype, data) {        if ( typeof target == 'string') {            target = document.getElementById(target);        }        var e = this.createEvent(eventStr, datatype, data);        if(e == null) {            return;        }        if (target.dispatchEvent) {            target.dispatchEvent(e);        } else if (target.fireEvent) {            target.fireEvent('on' + eventStr, e);        }    };    //绑定事件    myEvent.receive = function (target, eventStr, handler) {        if (typeof target == 'string') {            target = document.getElementById(target);        }        if (target.addEventListener) {            target.addEventListener(eventStr, handler, false);        } else if( target.attachEvent) {            target.attachEvent('on' + eventStr, handler); //IE        }    };

        myEvent.receive("menuList", "event.chen.menuClick", function(e) {            alert(e.data + "被点击!");        });
        $("#menuList").click(function(e) {            if (e.target.tagName == "LI") {                myEvent.send("menuList", "event.chen.menuClick", "string", e.target.innerHTML);            }        });


2jquery的实现:

        $("#menuList").bind("event.chen.menuClick", function(e, data){            alert(data.menuName + "被点击!");        });
        $("#menuList").delegate("li", "click", function(e){            $("#menuList").trigger("event.chen.menuClick", {menuName:e.target.innerHTML});        });

事件并不是只能被绑定到DOM元素上,我们可以将其绑定到自定义的对象上,从而开发出类似于JAVA的事件驱动框架,又称为发布/订阅模式。

发布者向某个信道发布一条消息,订阅者绑定这个信道,当有消息发布至信道时就会接收到一个通知。发布者和订阅者是完全解耦的,甚至彼此可以并不知晓对方的存在。


0 0