javascript 解惑

事件委托

<ul id="todo-app">
  <li class="item">Walk the dog</li>
  <li class="item">Pay bills</li>
  <li class="item">Make dinner</li>
  <li class="item">Code for one hour</li>
</ul>
  • 元素绑定事件监听器,更高效的解决方案是将一个事件侦听器实际绑定到整个容器上,然后在实际单击时可以访问每个确切元素。这被称为事件委托,并且它每个元素单独绑定事件处理程序更高效。
document.addEventListener('DOMContentLoaded', function() {

  let app = document.getElementById('todo-app');

  // 事件侦听器绑定到整个容器上
  app.addEventListener('click', function(e) {
    if (e.target && e.target.nodeName === 'LI') {
      let item = e.target;
      alert('you clicked on item: ' + item.innerHTML);
    }
  });

});

在循环内使用闭包(Closures)

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log('The index of this number is: ' + i);
  }, 3000);
}

该函数被执行并且打印出i的值,其在循环结束时都为4

解决方法1. 

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  // 通过传递变量 i
  // 在每个函数中都可以获取到正确的索引
  setTimeout(function(i_local) {
    return function() {
      console.log('The index of this number is: ' + i_local);
    }
  }(i), 3000);
}

解决方法2.

const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
  // 使用ES6的let语法,它会创建一个新的绑定
  // 每个方法都是被单独调用的
  setTimeout(function() {
    console.log('The index of this number is: ' + i);
  }, 3000);
}

函数防抖动(Debouncing)

-函数防抖动(Debouncing) 是解决这个问题的一种方式,通过限制需要经过的时间,直到再次调用函数。一个正确实现函数防抖的方法是:把多个函数放在一个函数里调用,隔一定时间执行一次

// debounce函数用来包裹我们的事件
function debounce(fn, delay) {
  // 持久化一个定时器 timer
  let timer = null;
  // 闭包函数可以访问 timer
  return function() {
    // 通过 'this' 和 'arguments'
    // 获得函数的作用域和参数
    let context = this;
    let args = arguments;
    // 如果事件被触发,清除 timer 并重新开始计时
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}

使用时:

function foo() {
  console.log('You are scrolling!');
}

// 在事件触发的两秒后,我们包裹在debounce中的函数才会被触发
let elem = document.getElementById('container');
elem.addEventListener('scroll', debounce(foo, 2000));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值