快手面试官:页面上有100个li,你知道怎么实现”点击li能console.log里面的内容“这个功能吗。

Hello everyone~

笔者前段时间参加了快手国际化的面试,一面有一道题目当时做了好久,一直没有做出来,后面事情太多了,自己又比较懒散,就没有整理。这段时间很多事情都告一段落了,我也觉得我可以继续整理题目了。

当时我和面试官的对话 be like:

面试官:"页面上有100个li,你知道怎么实现"点击li能console.log里面的内容"这个功能吗。"

我:"这个应该不难的吧,我对每一个li做监听不就好了,点击直接做展示。"

面试官:"那你在实习的时候会这样写代码吗?"

我当时就汗流浃背了,我说这个方向只是因为我只想到了这个,其他不会啊()

我:"我实习的时候应该不会这样写吧。"

面试官:"为什么?"

我:"因为对100个li做事件监听,一个方面是性能上的开销比较大,第二个是这个写法很笨,扩展能力不强,如果再新增li的话,那我又要重新去绑定。"

面试官:"那你知道还有什么其他的方法吗"

我:"我理解应该可以用事件捕获来做这个事情,但是具体的写法我不太了解"

面试官就去到了下一个问题,没为难我()

最后面完差不多30min就约下一面了,但由于自己的身体原因,后面就直接把面试全部推掉了。

那么我们来聊聊具体的实现方式吧~

实现方法一:

通过document.querySelectorAll('#myList li')获取所有的<li>元素。然后,使用forEach方法为每个<li>元素添加点击事件监听器。当用户点击任何一个<li>元素时,回调函数将打印该元素的内容到控制台。请记得根据你的实际需要修改代码中的<ul>的id和添加更多的<li>元素。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Click LI Example</title>
</head>
<body>

<ul id="myList">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <!-- ... 添加更多的 <li> 元素,总共 100 个 -->
</ul>

<script>
  // 获取所有的 <li> 元素
  var listItems = document.querySelectorAll('#myList li');

  // 为每个 <li> 元素添加点击事件监听器
  listItems.forEach(function(li, index) {
    li.addEventListener('click', function() {
      // 打印点击的 <li> 元素的内容到控制台
      console.log('Clicked on item ' + (index + 1) + ': ' + li.textContent);
    });
  });
</script>

</body>
</html>

问题:

  1. 性能问题: 在有很多元素的情况下,为每个元素都注册一个事件监听器可能会导致性能问题,因为每个监听器都需要占用内存。
  2. 维护困难: 如果你需要更改事件处理逻辑或添加/删除元素,你可能需要在多个地方修改代码。

好处:

  1. 简单直观: 每个元素都有自己的事件处理逻辑,代码结构相对直观,易于理解。
  2. 灵活性: 每个元素的点击事件处理逻辑可以是不同的,更容易定制。

实现方法二:

在下面代码中,我们注册了一个事件监听器,并在事件处理程序中检查点击的目标是否是<li>元素。如果是,就执行相应的操作。这样,无论你有多少个<li>元素,都只需一个事件监听器。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Click LI Example</title>
</head>
<body>

<ul id="myList">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <!-- ... 添加更多的 <li> 元素,总共 100 个 -->
</ul>

<script>
  // 获取 <ul> 元素
  var myList = document.getElementById('myList');

  // 添加点击事件监听器到 <ul> 元素
  myList.addEventListener('click', function(event) {
    // 检查点击的目标是否是 <li> 元素
    if (event.target.tagName === 'LI') {
      // 打印点击的 <li> 元素的内容到控制台
      console.log('Clicked on item: ' + event.target.textContent);
    }
  });
</script>

</body>
</html>

问题:

  1. 目标元素判断: 在事件处理程序中需要判断点击的目标是否是<li>元素,可能会增加一些额外的逻辑。
  2. 事件冒泡: 如果有其他元素嵌套在<li>内,并且也有点击事件,事件可能会冒泡到<ul>上,需要小心处理。

好处:

  1. 性能优化: 只有一个事件监听器,可以减少内存占用,提高性能,特别是在大量元素的情况下。
  2. 维护简便: 无论有多少个元素,只需一个事件监听器,减少了代码的冗余,更容易维护。
  3. 动态元素: 适用于动态添加的元素,因为事件监听器绑定在父元素上,新添加的子元素也会受到监听。

效果图片

相关推荐
m0_748255265 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
长风清留扬26 分钟前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web1478621072339 分钟前
C# .Net Web 路由相关配置
前端·c#·.net
m0_7482478040 分钟前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖43 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
ThisIsClark1 小时前
【后端面试总结】MySQL主从复制逻辑的技术介绍
mysql·面试·职场和发展
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.1 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis