事件委托,call apply bind用法

call apply bind

1.用法

1)call

用法

fn.call(thisArg, arg1, arg2, arg3, ...)

call方法会改变this指向,指向第一个参数thisArg,将后面的参数传入给fn,并立即执行函数fn。

let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    obj.sayHello('程序员', '看美女'); // 我叫xiaoming,今年24岁。我的工作是: 程序员,我的爱好是: 看美女。


    let obj1 = {
        name: "lihua",
        age: 30
    }
    // obj1.sayHello(); // Uncaught TypeError: obj1.sayHello is not a function
    obj.sayHello.call(obj1, '设计师', '画画'); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。

上面的代码中,我们obj1对象也想使用obj对象中的sayHello方法;我们就可以使用call方法调用obj.sayHello, 并将obj.sayHello中的this修改为obj1,把 ‘设计师’, ‘画画’ 这两个参数出给obj.sayHello。

2)apply

apply(thisArg, [argsArr])

fn.apply作用和call相同,改变this指向并立即执行fn,区别在于传参不同,apply传两个参数,第一个参数指向this指向,第二个参数是一个数组,数组元素会被展开传入fn,作为fn的参数

let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    obj.sayHello('程序员', '看美女'); // 我叫xiaoming,今年24岁。我的工作是: 程序员,我的爱好是: 看美女。


    let obj1 = {
        name: "lihua",
        age: 30
    }
    
    obj.sayHello.apply(obj1, ['设计师', '画画']); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。

3)bind

bind(thisArg, arg1, arg2, arg3, ...)

fn.bind的作用是只修改this指向,但不会立即执行fn;会返回一个修改了this指向后的fn。需要调用才会执行:bind(thisArg, arg1, arg2, arg3, …)()。bind的传参和call相同。

    let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    // obj.sayHello('程序员', '看美女'); // 我叫xiaoming,今年24岁。我的工作是: 程序员,我的爱好是: 看美女。

    let obj1 = {
        name: "lihua",
        age: 30
    }
    
    obj.sayHello.bind(obj1, '设计师', '画画'); // 无输出结果
    obj.sayHello.bind(obj1, '设计师', '画画')(); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。



2.区别

1)相同点

三个都是用于改变this指向;
接收的第一个参数都是this要指向的对象;
都可以利用后续参数传参。

2)不同点

call和bind传参相同,多个参数依次传入的;
apply只有两个参数,第二个参数为数组;
call和apply都是对函数进行直接调用,而bind方法不会立即调用函数,而是返回一个修改this后的函数

事件委托

简介

利用 JS 事件冒泡动态为元素绑定事件的方法称为事件委托(也称为“事件代理”)。
事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。

好处

在 JavaScript 中,页面内事件处理程序的个数会直接影响页面的整体性能,因为每个事件处理程序都是对象,对象会占用内存,内存中的对象越多,页面的性能则越差。此外,事件处理程序需要与 DOM 节点进行交互,访问 DOM 的次数越多,引起浏览器重绘和重排的次数也就越多,从而影响页面的性能。

使用for循环会导致浏览器缓存过多,使用事件委托可以解决这个问题

html

<ul id="myLinks">
  <li id="goSomewhere">Go somewhere</li>
  <li id="doSomething">Do something</li>
  <li id="sayHi">Say hi</li>
</ul>

js

    var item1 = document.getElementById("goSomewhere");
    var item2 = document.getElementById("doSomething");
    var item3 = document.getElementById("sayHi");
 
    document.addEventListener("click", function (event) {
      var target = event.target;
      switch (target.id) {
        case "doSomething":
          document.title = "事件委托";
          break;
        case "goSomewhere":
          location.href = "http://www.baidu.com";
          break;
        case "sayHi": alert("hi");
          break;
      }
    })

1.冒泡与捕获

冒泡:由子到父
捕获:由父到子

在这里插入图片描述
三个盒子的顺序是d1 d2 d3

1)冒泡

如果点击d1,则控制台只会报d1
在这里插入图片描述
如果点击d2
在这里插入图片描述

2)捕获

在捕获事件触发的前提,我们需要使用事件监听 document.addEventListener(‘event’,funciton(){},true)

这里的true是布尔值判断是否为捕获事件,当为true时,这里为捕获事件,如果为false时,这里就是冒泡事件。

用代码给大家解释一下:
在这里插入图片描述
当我们点击d1时,打印d1.但是当我们点击d3时,打印结果依次为d1 d2 d3

在这里插入图片描述

结果由父级传递向子级,这个过程称为捕获事件。
e.stoppropagation()阻止冒泡

onclick和addEventListener的区别

1.为一个按钮绑定多个点击事件

1)使用onclick(不行)

    <button id="btn">点击</button>
    <script>
        btn.onclick = function(){
            console.log('第一次点击');
        }
        btn.onclick = function(){
            console.log('第二次点击');
        }
    </script>

在这里插入图片描述

2)addEventListener

  <button id="btn">点击</button>
    <script>
        btn.addEventListener('click',()=>{console.log('第一次点击');},false);
        btn.addEventListener('click',()=>{console.log('第二次点击'),false});
    </script>

在这里插入图片描述

2.决定触发顺序

1)使用冒泡

  <div id="div1">
        <button id="btn">点击</button>
    </div>
    <script>
        div1.onclick = function(){
            console.log('div1的事件');
        }
        btn.onclick = function(){
            console.log('btn的事件');
        }
    </script>

在这里插入图片描述

2) 使用捕获

   <div id="div1">
        <button id="btn">点击</button>
    </div>
    <script>
        btn.onclick = function(){
            console.log('btn的事件');
        }
        div1.addEventListener('click',()=>{console.log('div1的事件');},true);
    </script>

在这里插入图片描述

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值