zoukankan      html  css  js  c++  java
  • html中事件处理中的this和event对象

    在用js编写页面事件处理代码时,会经常涉及到this和event对象,但有时在采用不同的事件处理,尤其是在与自定义的对象关联时,这些对象的指向变的有些复杂。

    本文来详细介绍下各种场景下 这些对象 真正指向。

    一、事件直接写在html标签中

    1、案例1:

    <button onclick="clickBtn()">测试</button>

    处理代码如

    function clickBtn(){
            alert(this.location.href);
        }

    这时的 this 是指向全局 Window对象。 

    2、案例2:

    <button onclick="clickBtn(this)">测试</button>

    处理代码如

    function clickBtn(obj){
            alert(obj.innerHTML);
        }

    这时的 上述方法中的 obj指向的是按钮本身。也就是在 onclick="clickBtn(this)"传入的this对象指向事件触发的按钮。

    3、冒泡

    <div onclick="clickBtn(this)"><button >测试</button></div>

    因为html事件的冒泡特性,虽然上面的onclick事件写在div上,这时无论是点击按钮还是div区域,都会触发div上绑定的事件。

    但无论点击的是哪个,会发现 事件响应传入的 this指向的是 div,不是button.

    在这种方式下,我们除了可以将this对象传给事件处理函数外,还可以将event对象传给事件处理函数。event对象包含了触发事件的各种信息。

    <button onclick="clickBtn(event)">测试</button>

    4、事件响应函数为对象的方法

    我们看下,如果事件响应的函数为对象的方法,会出现什么变化。

    <button onclick="handleDemo.clickBtn(this)">测试</button>

    代码如下

    <script>
        function HandleDemo(){
            this.msg="good";
        }
        HandleDemo.prototype.clickBtn=function(obj){
            alert(obj.innerHTML);
            alert(this.msg);
        }
        var handleDemo = new HandleDemo();
    </script>

    这时会发现 clickBtn 方法中的 this 指向的是 handleDemo 对象。 参数obj因为是传入的,指向的是button对象,这个没变。

    说明:直接在html标签中绑定事件,是一件非常不好的编码习惯,强烈不建议推荐。下面我们介绍用jquery进行事件处理。

    二、利用jquery绑定事件

    1、方式一:

    <button id="btn">测试</button>

    脚本代码

    <script>
        $("#btn").click(clickBtn);
        function clickBtn(event){
            alert(this.innerHTML);
            alert(event.currentTarget.innerHTML);
        }
    </script>

    上面代码 通过调用jquery对象的 click方法,参数就是事件响应处理函数。
    这个函数可以带一个参数,jquery会把事件对象event传入。参数名可以是任意的,不一定叫event。

    如果不定义参数,在函数中也可直接使用event。但一般如果需要用到event对象,最好显式定义下。

    这时我们会发现,在函数体中直接使用的this指向的是 button对象。 我们可以不显示的定义对象,采用匿名函数的方式,如:

    <script>
        $("#btn").click(function(ev){
            alert(this.innerHTML);
            alert(ev.currentTarget.innerHTML);
        });
    </script>

    这个代码与上面代码的效果完全一样。

    我们再来看下,如果传给click方法的是对象的方法呢?

    <script>
        function HandleDemo(){
            this.msg="good";
        }
        HandleDemo.prototype.clickBtn=function(ev){
            alert(this.innerHTML);
            alert(ev.currentTarget.innerHTML);
        }
        var handleDemo = new HandleDemo();
        
        $("#btn").click(handleDemo.clickBtn);
    </script>


    这时,我们发现clickBtn中的 this指向的依然是 button对象,并不是我们想象中的 handleDemo对象。

    这样就带来一个很大的问题,因为clickBtn方法是handleDemo对象的成员,如果我们想要在clickBtn方法中访问handleDemo对象的其它成员,却没办法了。

    除非直接使用全局变量,而这是很不推荐的。

    下面我们介绍jquery的另外一种事件绑定方法。

    2、方式二:bind方法

    html代码依然不变

    <button id="btn">测试</button>

    脚本代码

    <script>
        function clickBtn(ev){
            alert(this.innerHTML);
            alert(ev.currentTarget.innerHTML);
        }
        $("#btn").bind("click",clickBtn);
    </script>

    这时,事件处理方法依然有一个参数指向event对象。

    我们发现 clickBtn中的 this 指向的是 button对象。
    bind函数,有三个参数,第一个是代表事件类型;第二个是传递给事件处理的额外信息对象(会赋值给event的data属性);第三个是事件处理函数。

    上面例子我们只使用了第1个和第3个。下面我们看下例子:

    <script>
        function clickBtn(ev){
            alert(this.innerHTML);
            alert(ev.currentTarget.innerHTML);
            alert(ev.data.msg);
        }
        $("#btn").bind("click",{msg:"hello"},clickBtn);
    </script>

    采用这种方式,我们传递了额外的对象给事件处理函数。这在某些场景下还是能用到的。

    下面我们看下这种方式下传入的事件处理函数是对象的方法:

    <script>
        function HandleDemo(){
            this.msg="good";
        }
        HandleDemo.prototype.clickBtn=function(ev){
            alert(this.innerHTML);
            alert(ev.currentTarget.innerHTML);
            alert(ev.data.msg);
        }
        var handleDemo = new HandleDemo();
    
        $("#btn").bind("click",handleDemo,handleDemo.clickBtn);
    </script>

    我们可以将对象本身作为bind方法的第二个参数传入。以解决在方法中无法访问对象其它成员的问题。

    注意:采用jquery的事件绑定,无论是用bind方法,还是上一种方法。 如果调用多次,会绑定多次,而不会后面的覆盖前面的,事件触发时,事件函数会被多次执行。

  • 相关阅读:
    PHP用curl发送get post put delete patch请求
    ubuntu中设置php7.0-fpm开机自启动
    对计算机领域中间层的理解
    后端程序猿怎能不会的linux命令
    查看磁盘空间和目录大小的命令
    Http协议详解
    supervisor使用总结
    vmware中扩充磁盘
    HDU 4946 共线凸包
    Codeforces_GYM Flight Boarding Optimization
  • 原文地址:https://www.cnblogs.com/51kata/p/5307490.html
Copyright © 2011-2022 走看看