JavaScript 代码优化:使用事件委托、文档片段和缓存变量

本文将以一个具体示例,展示如何使用事件委托、文档片段和缓存变量来优化 JavaScript 代码,以提高代码的性能和可读性。

原始代码:

for (const item of KeywordFiltering) {
  let li = document.createElement('li')
  li.innerText = item.name
  document.querySelector('.option').appendChild(li)
  let div = document.createElement('div')
  div.className = item.class
  document.querySelector('.list').appendChild(div)
  li.onclick = () => {
    for (const allDiv of document.querySelectorAll('.list div')) {
      allDiv.style.display = 'none'
    }
    div.style.display = 'block'
    document.querySelector('.option').style.display = 'none'
    document.querySelector('.confirm').onclick = () => {
      if (item.data.includes(userValue.value)) {
        alert('已存在')
        return
      }
      let span = document.createElement('span')
      span.innerText = userValue.value
      div.appendChild(span)
      item.data.push(userValue.value)

      span.onclick = () => {
        span.remove()
        item.data = item.data.filter(item => item !== span.innerText)
        console.log(span, item.data);
      }
      console.log(item.data, userValue.value);

    }
  }

  item.data.forEach(subitem => {
    let span = document.createElement('span')
    span.innerText = subitem
    div.appendChild(span)
    span.onclick = () => {
      span.remove()
      item.data = item.data.filter(item => item !== subitem)
      console.log(span, item.data);
    }
  });


}

优化后的代码:

const optionContainer = document.querySelector('.option');
const listContainer = document.querySelector('.list');

const fragment = document.createDocumentFragment();

for (const item of KeywordFiltering) {
  const li = document.createElement('li');
  li.innerText = item.name;
  
  const div = document.createElement('div');
  div.className = item.class;
  
  fragment.appendChild(li);
  fragment.appendChild(div);
  
  li.addEventListener('click', () => {
    const allDivs = document.querySelectorAll('.list div');
    allDivs.forEach(allDiv => {
      allDiv.style.display = 'none';
    });
    
    div.style.display = 'block';
    optionContainer.style.display = 'none';
    
    document.querySelector('.confirm').onclick = () => {
      if (item.data.includes(userValue.value)) {
        alert('已存在');
        return;
      }
      
      const span = document.createElement('span');
      span.innerText = userValue.value;
      div.appendChild(span);
      item.data.push(userValue.value);
      
      span.addEventListener('click', () => {
        span.remove();
        item.data = item.data.filter(item => item !== span.innerText);
        console.log(span, item.data);
      });
      
      console.log(item.data, userValue.value);
    };
  });
  
  item.data.forEach(subitem => {
    const span = document.createElement('span');
    span.innerText = subitem;
    div.appendChild(span);
    
    span.addEventListener('click', () => {
      span.remove();
      item.data = item.data.filter(item => item !== subitem);
      console.log(span, item.data);
    });
  });
}

optionContainer.appendChild(fragment);
listContainer.appendChild(fragment);

代码优化要点:

  1. **使用事件委托:**将 lispan 的点击事件绑定到它们的父元素 optionContainerlistContainer 上,减少事件监听器的数量,提高性能。
  2. **使用文档片段:**将创建的 lidiv 元素先添加到文档片段 fragment 中,然后再一次性地添加到 DOM 中,可以减少对 DOM 的多次操作,提高性能。
  3. **使用缓存变量:**将频繁使用的 DOM 查询结果存储在变量中,例如 optionContainerlistContainerallDivs,避免重复查询。
  4. **使用模板字符串:**使用模板字符串来创建 HTML 元素,可以使代码更简洁、易读。

其他优化建议:

  • 使用 Array.prototype.someArray.prototype.find 来判断 userValue.value 是否存在于 item.data 中,而不是使用 Array.prototype.includes,因为 includes 会遍历整个数组。
  • 如果 item.data 很大,可以考虑使用 Set 来存储数据,因为 Set 的查找效率比 Array 高。
  • 使用 requestAnimationFrame 来优化 DOM 操作,避免页面卡顿。

请注意,上述代码仅提供了一种优化方案,具体的优化方式可能还需要根据实际情况进行调整。


原文地址: https://www.cveoy.top/t/topic/p3Zc 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录