由浅入深JavaScript11进阶-事件1

来源:互联网 发布:avmoo.com新域名 编辑:程序博客网 时间:2024/06/04 19:01
什么是事件
    JavaScript与HTML之间是通过事件来交互。
    事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
    事件一般分为DOM事件(文档对象模型事件)和BOM事件(浏览器对象模型事件)。

事件流
    事件流描述了在页面中接受事件的顺序。
    比如:在页面里有三个嵌套的DIV,最大的DIV在下面,最小的在上面
    eg:
        <script type="text/javascript">
            window.onload = function(){
                document.getElementById('div1').onclick = function(){
                    alert('div1');
                }
                document.getElementById('div2').onclick = function(){
                    alert('div2');
                }
                document.getElementById('div3').onclick = function(){
                    alert('div3');
                }
            }
        </script>
        <div id="div3" style="width:900px;height:900px;background:red;z-index: 1;" >
            <div id="div2" style="background:green;width:600px;height:600px;z-index: 2;">
                <div id="div1" style="background:yellow;width:300px;height:300px;z-index: 3;">
                </div>
            </div>
        </div>
    如果我们点击div1那么事件该怎么算呢?
    点击了div1,事实上也点击了div2,点击了div3。
    会依次弹出alert('div3'),alert('div2'),alert('div1');
    可是我们的本意是只点击div3,这就需要事件冒泡了。

事件冒泡

    在IE中事件流被称为时间冒泡:事件由最先直接的元素接受然后逐级向上传递,
    直到html-document。
    如图:
    
事件处理程序
    什么是事件处理程序,说白了就是响应事件的的函数。
    比如,发生了click点击事件那么onclick就是事件处理程序。
    比如,发生鼠标移动mousemove事件那么onmousemove就是事件处理程序
    
事件捆绑

    将事件当做HTML属性,捆绑在HTML元素上称之为事件捆绑。
    有时候也叫行间事件或HTML级事件处理程序
    但是我们不推荐使用行间事件,这是因为行间事件有三个弊端。
    弊端一:在html元素上捆绑了JavaScript事件后,这个值应当是
    JavaScript值,因此不许与未经转义的HTML语法字符。比如,&
    "",<,>。经转义分别使用:&amp,&quot,&lt,&gt.
    eg:
        <input type="button" value="点击" onclick="alert(&quot hello &quot)" />
    当然我们也可以在行间事件中引用定义好的函数。只需事件的值处写上函数名。
    弊端二:
    eg:
        <input type="button" value="点击" onclick="showName('js')" />
            ddddddddddddddddddddd
            ddddddddddddddddddddd
            ddddddddddddddddddddd
            ddddddddddddddddddddd
            1万行其他元素需要渲染
        <script>
            function showName(name){
                    alert(name);
            }
        </script>
    上述例子,按钮添加行间事件,事件独立,按钮上是调用函数,并传入参数。但是这样会有一些瑕疵。
    我们试想一下。如果把JavaScript代码放到最下面,而中间又有很多元素需要渲染,那么
    当用户点击了按钮(手速快@_@),可能还未执行到函数处,解释器会报错误。
    当然这个解决办法也有很多,移动js位置,或使用try块都可以。但是行间事件
    最大的弊端其实是耦合。
    
    弊端三:行间事件将交互和表现混在一起,耦合严重,改js代码需要改HTML代码。
    现代web前端我们讲,结构(HTML),表现(CSS),行为(js)分离。
    
DOM0级事件处理程序

        Dom0级事件处理程序是最传统的事件处理方式,将一个函数
        赋值给一个事件处理程序属性上。每个元素都有自己的事件处理属性。
        这些属性通常全小写。
        比如:btn.onclick = function(){}
        将一个匿名函数绑定到 元素btn的事件处理程序的属性onclick上。
        使用DOM0级事件处理程序,this指代事件发生的对象。
        eg:
        <script>
            window.onload = function(){
                var btn1 = document.getElementById('btn1');
                btn1.onclick = function(){
                    alert('dom0级时间处理程序');
                    alert(this.value);//按钮
                }
            }
        </script>
        </head>
        <body>
            <input  type="button" value="按钮" id="btn1"/>
        </body>

DOM2级事件处理程序
        使用条件IE9+
        在DOM2级事件里定义了两个新方法。
        addEventListener,removeEventListener。其好处是可以添加多个事件处理程序。
        执行顺序为顺序执行。
        其中this与DOM0级传统方式一致,也是指事件发生的对象。
        addEventListener为添加事件,里面有三个参数,第一个参数为事件名称,
        第二个参数为处理程序,第三个参数一般为false表示在事件冒泡阶段处理程序。
        addEventListener('click',function(){},false);
        亦可以
        function showName(){};
        addEventListener('click',showName,false);
        其区别在于前者不能够取消事件,后者可以取消事件。
        因为,removeEventListener('click',showName,false);
        取消事件需要名字,前者的事件添加是一个匿名函数,没有函数名字,没法取消。
        eg:
            同一元素添加同一事件多个处理程序,并且两种处理方式。
            以及删除事件。
        <script>
            window.onload = function(){
                function showName(){
                    alert(this.id);//btn1
                }
                var btn1 = document.getElementById('btn1');
                btn1.addEventListener('click',function(){
                    alert(this.id);//btn1
                },false);
                btn1.addEventListener('click',showName,false);    
                
                btn1.removeEventListener('click',function(){//无效
                        alert(this.id);
                },false);
                btn1.removeEventListener('click',showName,false);//有效
            }
        </script>
        </head>
        <body>
            <input type="button" id="btn1" value="按钮" />
        </body>
        最后弹出btn1一次。
IE事件处理程序
    只支持IE浏览器并且是5-10。最新的11也不支持
    IE时间处理程序使用attachEvent和detachEvent两个函数。
    与DOM2级事件处理程序相比,attachEvent和detachEvent只有两个参数,
    事件名称,事件函数。由于IE是事件流只支持事件添加到冒泡阶段,所以
    省略了最后一个参数,此外,函数名称加on,比如onclick
    attchEvent('onclick',function(){});
    也可以
    attchEvent('onclick',showName);
    区别在于前者是匿名函数无法删除事件。后者可以。
    还需要注意的是,事件处理程序在全局作用域中运行,this指代window
    eg:
        <script>
            window.onload = function(){
                function showName(){
                    alert(this);//;window
                }
                var btn1 = document.getElementById('btn1');
                btn1.attachEvent('onclick',function(){
                    alert(this);//window
                });
                btn1.attachEvent('onclick',showName);
                
                btn1.detachEvent('onclick',function(){//无效
                    alert(this);
                });
                btn1.detachEvent('onclick',showName);//有效
            }
        </script>

       

总结:具体用哪一种事件处理程序,大家根据实际情况来选择

说在最后的话:

本博会开一个JS专栏:《大神前端:JavaScript板块》长期更新,由浅入深带大家系统的学习JavaScript,
做出多彩的JS特效。
如果对你有用就关注一下专栏吧,我会不断的更新,后期还有其他版块。
http://blog.csdn.net/column/details/15918.html

想深入,系统全面的学习JS,博友们可以在CSDN搜索我的课程《多彩JavaScript》@_@。
http://edu.csdn.net/course/detail/5619

限于文章篇幅原因,这里仅仅介绍冰山一角。由于笔者的水平有限,编写时间也很仓促,
文中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正