zoukankan      html  css  js  c++  java
  • JavaScript的事件概述以及事件对象,事件流

    事件处理程序

    JavaScript 事件对象是由访问 Web 页面的用户引起的一系列操作,例如:用户点击页面上的某个按钮或者鼠标移动到页面的某个图片上而产生一系列的互动的反馈。

    我们通过为指定事件绑定回调函数的形式来处理事 件,当指定事件触发以后我们的回调函数就会被调 用,这样我们的页面就可以完成和用户的交互了。 

    事件一般是用于浏览器和用户操作进行交互。最早是 IE 和 Netscape Navigator 中出现,作为分担服务器端运算负载的一种手段。直到几乎所有的浏览器都支持事件处理。

    JavaScript 有三种事件模型:

    内联模型(通过HTML元素指定事件属性来绑定 )

    脚本模型(通过DOM对象指定的属性来绑定 ,推荐使用的一种方式)

    设置事件监听器(元素对象.addEventListener())

    绑定事件处理程序方式—内联模型

    这种模型是最传统的一种处理事件的方法。在内联模型中,事件处理函数是 HTML标签的一个属性,用于处理指定事件。

    虽然内联在早期使用较多,但它是和 HTML 混写的,并没有与 HTML 分离导致违反了分层的原则

    <script type="text/javascript">
        function box(){
            alert("");
        }
    </script>
    
    </head>
    <body>
        <!--在 HTML 中把事件处理函数作为属性执行 JS 代码  onclick是事件处理函数-->
        <input type="button" value="按钮" onclick="alert('Lee');" />
        
       <!--在 HTML 中把事件处理函数作为属性执行 JS 函数-->
        <input type="button" value="按钮" onclick="box();" /> 
    </body>
    <script type="text/javascript">
        window.onload = function(){
            function box(){
                alert("");
            }
        };
    </script>
    </head>
    <body>
        <input  type="button" value="点我" onclick="box()"/>    <!--如果box函数放在一个匿名函数里面执行不到,会报错:box is not defined 这成了闭包-->
    </body>

    绑定事件处理程序方式—脚本模型

    由于内联模型违反了 HTML 与 JavaScript 代码层次分离的原则。为了解决这个问题,我们可以在 JavaScript 中处理事件。这种处理方式就是脚本模型

    这种写法将HTML代码和JS写在不同的位置,维护 起来更加容易

    <script type="text/javascript">
        window.onload = function(){
            var input = document.getElementsByTagName('input')[0];
            
            //对像.事件处理函数=函数名或者匿名函数
            input.onclick=function(){
                alert("我");
            }
        }
    </script>
    </head>
    <body>
        <input type="button" value="按钮" /> 
    </body>

    通过匿名函数,可以直接触发对应的代码。也可以通过指定的函数名赋值的方式来执行函数(赋值的函数名不要跟着括号)。

    <script type="text/javascript">
        function box(){
            alert("我");
        }
        window.onload = function(){
            var input = document.getElementsByTagName('input')[0];
            
            //对像.事件处理函数=函数名或者匿名函数
            input.onclick=box;
        }
    </script>
    
    </head>
    <body>
        <input type="button" value="按钮" /> 
    </body>

    函数和事件处理函数也可以封装到一起

    <script type="text/javascript">
        window.onload = function(){
            var input = document.getElementsByTagName("input")[0];
            input.onclick= box;
            function box(){
                alert("哈哈");
            }
        };
    </script>
    </head>
    <body>
        <input  type="button" value="点我"/>
    </body>

    绑定事件处理程序方式—设置事件监听器

    前边两种方式都可以绑定事件处理程序,但是它们都有一个缺 点就是都只能绑定一个程序,而不能为一个事件绑定多个程序,详情查看:JavaScript事件的委派与事件的绑定

    可以使用addEventListener()来处理,这个方法需 要两个参数:一个是事件字符串,一个是响应的回调函数。

    <body>
      <input  type="button" value="点我"/>
    </body>
    </html>
    <script type="text/javascript">
      window.onload = function(){
        var input = document.getElementsByTagName("input")[0];
        input.addEventListener('click', function () {
          alert("hello");
        })
      };
    </script>

    但是要注意的是ie8以下的浏览器是不支持上边的方法的,需要 使用attachEvent代替。  也可以使用removeEventListener()和detachEvent()移除事件。

    事件处理中的this

    在事件处理程序内的 this 所引用的对象即 是设定了该事件处理程序的元素

    也就是事件是给那个对象绑定的this就是哪 个对象。

    <body>
      <input  type="button" value="点我"/>
    </body>
    </html>
    <script type="text/javascript">
      window.onload = function(){
        var input = document.getElementsByTagName("input")[0];
        input.addEventListener('click', function () {
          console.log(this) //this就是<input type="button" value="点我">
        })
      };
    </script>

    在一个对象里,由于作用域的关系,this 代表着离它最近对象

    <script type="text/javascript">
        function box(){
            alert(this);             //HTMLInputElement,this 表示 input 对象
        };
        box();                //[object Window]如果是在全局范围调用box()那么this代表window
        window.onload = function(){
            var input = document.getElementsByTagName('input')[0];
            input.onclick = box;
        };
    </script>
    </head>
    <body>
        <input  type="button" value="按钮"/>
    </body>

    事件对象

    在DOM对象上的某个事件被触发时,会产生一个 事件对象Event,这个对象中包含着所有事件有关 的信息。包括导致事件的元素、事件的类型以及其 他与特定事件相关的信息。 

    例如,鼠标操作导致的事件对象中,会包含鼠标位 置的信息,而键盘操作导致的事件对象中,会包含 与按下的键有关的信息。所有浏览器都支持 event 对象,但支持方式不同。

    DOM标准的浏览器会将一个event对象传入到事件的处理程序 当中。无论事件处理程序是什么都会传入一个event对象。 

    那么首先,我们就必须验证一下,在执行函数中没有传递参数,是否可以得到隐藏的参数。

    <script type="text/javascript">
        function box(){
            alert(arguments.length); //0,没有得到任何传递的参数
        };
        box();                
        
    </script>
    </head>
    <body>
        <input  type="button" value="按钮"/>
    </body>
    <body>
      <input  type="button" value="点我"/>
    </body>
    </html>
    <script type="text/javascript">
      window.onload = function(){
        var input = document.getElementsByTagName("input")[0];
        input.addEventListener('click', function (event) {
          console.log(event)
        })
      };
    </script>

    直接接收 event 对象,是 W3C 的做法,IE 6,7,8不支持,IE 6,7,8自己定义了一个 event 对象,直接在 window.event 获取即可。

    <script type="text/javascript">
        window.onload = function(){
            var input = document.getElementsByTagName('input')[0];
            input.onclick = function (evt) {
                var e = evt || window.event; //实现跨浏览器兼容获取 event 对象
                alert(e);
            };
        };
    </script>
    </head>
    <body>
        <input  type="button" value="按钮"/>
    </body>

    Event对象包含与创建它的特定事件有关的属性和方法。触发 的事件类型不一样,可用的属性和方法也不一样。

    Event对象的通用属性/方法 

    <body>
        <a href="http://www.baicu.com">点他</a>
    </body>
    </html>
    <script type="text/javascript">
        window.onload = function () {
            var a = document.getElementsByTagName('a')[0]
            
            a.onclick = function (event) {
                console.log('去百度了')
                event.preventDefault() // 阻止事件的默认行为,这里a标签的默认行为会跳转页面
            }
        }
    </script>

    IE中的事件对象

    与访问 DOM 中的 event 对象不同,要访问 IE 中 的 event 对象有几种不同的方式,取决于指定事件 处理程序的方法。 

    在IE中event对象作为window对象的属性存在的, 可以使用window.event来获取event对象。

    在使用attachEvent()的情况下,也会在处理程序中 传递一个event对象,也可以按照前边的方式使用

    首先第一个我们了解一下 W3C 中的 target 和 IE 中的 srcElement,都表示事件的目标

    <script type="text/javascript">
        function getTarget(evt) {
            var e = evt || window.event;
            return e.target || e.srcElement; //兼容得到事件目标 DOM 对象
        }
        window.onload = function(){
            document.onclick = function (evt) {
                var target = getTarget(evt);
                alert(target);        //点击哪里就可以获取到哪里的DOM元素对象
                alert(target.innerHTML);
            };
        };
    </script>
    </head>
    <body>
        <div id="box" style="100px; height:100px; background-color:#F00">测试Div</div>
    </body>

    鼠标操作导致的事件对象中的特殊属性和方法和键盘操作导致的事件对象中的特殊属性和方法,详情查看:JavaScript的事件对象中的特殊属性和方法(鼠标,键盘)

    事件的传播

    在网页中标签与标签之间是有嵌套关系的,比如这样一个页面

    <html> 
        <body> 
            <div id="foo"> 
                <button id="bar">sample</button> 
            </div> 
        </body> 
    </html>

    如果这时用户点击了sample按钮,则会以该按钮作为事件目标触发一次点击 事件。 这时,事件的处理将会分为捕获阶段、目标阶段、事件冒泡这三个阶段。

    事件的传播流程

    捕获阶段 : 这一阶段会从window对象开始向下一直遍历到目标对象,如果发现有对 象绑定了响应事件则做相应的处理。

    目标阶段 : 这一阶段已经遍历结束,则会执行目标对象上绑定的响应函数。

    事件冒泡阶段 –:这一阶段,事件的传播方式和捕获阶段正好相反,会从事件目标一直向 上遍历,直至window对象结束,这时对象上绑定的响应函数也会执行。

    取消事件传播 

    我们可以使用event对象的两个方法完成: – stopPropagation() – stopImmediatePropagation()

    取消默认行为: – preventDefault()

    事件流
    事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。

    事件流包括两种模式:冒泡(是从里往外逐个触发)和捕获(是从外往里逐个触发)

    那么现代的浏览器默认情况下都是冒泡模型,而捕获模式则是早期的 Netscape 默认情况。而现在的浏览器要使用 DOM2 级模型的事件绑定机制才能手动定义事件流模式。

    <script type="text/javascript">
    
        window.onload = function(){
            document.onclick = function () {
                alert('我是 document');
            };
            document.documentElement.onclick = function () {
                alert('我是 html');
            };
            document.body.onclick = function () {
                alert('我是 body');
            };
            document.getElementById('box').onclick = function () {
                alert('我是 div');
            };
            document.getElementsByTagName('input')[0].onclick = function () {
                alert('我是 input');
            };
        };
        
    </script>
    </head>
    <body>
        <div id="box" style="100px; height:100px; background-color:#F00">
               <input  type="button" value="按钮"/>
        </div>
    </body>

    阻止冒泡

    事件冒泡里面的事件对象是触发事件的那个事件对象,但是里面的this是绑定的那个元素对象

    <body>
    <div id="box" style="100px; height:100px; background-color:#F00">
      <input  type="button" value="按钮"/>
    </div>
    </body>
    </html>
    <script type="text/javascript">
      window.onload = function(){
        document.onclick = function () {
          alert('我是 document');
        };
        document.documentElement.onclick = function () {
          alert('我是 html');
        };
        document.body.onclick = function () {
          alert('我是 body');
        };
        document.getElementById('box').onclick = function () {
          alert('我是 div');
          // 点击这里没有阻止冒泡还会有事件冒泡
        };
        document.getElementsByTagName('input')[0].onclick = function (evt) {
          var e = evt || window.event;
          alert('我是 input');
          // e.stopPropagation()
          e.cancelBubble = true;// 取消事件冒泡,可以将事件对象的cancelBubble设置为true,即可取消冒泡
        };
      };
    </script>
  • 相关阅读:
    MySQL学习笔记
    Git常用命令
    MacBook Pro m1安装swoole PHP版本7.4
    斐波那契数列实现的2种方法
    归纳一些比较好用的函数
    阶乘的实现
    冒泡排序
    PHP上传图片
    PHPStorm常用快捷键
    DataTables的使用
  • 原文地址:https://www.cnblogs.com/LO-ME/p/4591463.html
Copyright © 2011-2022 走看看