快手面试官:页面上有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. 动态元素: 适用于动态添加的元素,因为事件监听器绑定在父元素上,新添加的子元素也会受到监听。

效果图片

相关推荐
码农研究僧几秒前
Java或者前端 实现中文排序(调API的Demo)
java·前端·localecompare·中文排序·collator
营赢盈英7 分钟前
OpenAI API key not working in my React App
javascript·ai·openai·reactjs·chatbot
guangzhi063315 分钟前
JVM本地方法栈
java·jvm·面试
吕永强38 分钟前
HTML表单标签
前端·html·表单标签
范特西是只猫1 小时前
echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】
前端·javascript·echarts
麒麟而非淇淋1 小时前
AJAX 进阶 day4
前端·javascript·ajax
图灵苹果1 小时前
【个人博客hexo版】hexo安装时会出现的一些问题
前端·前端框架·npm·node.js
IT-陈2 小时前
app抓包 chrome://inspect/#devices
前端·chrome
hahaha 1hhh5 小时前
Long类型前后端数据不一致
前端