一道面试题--面向对象维护列表

今天看到一道面试题,题目很简单,不过考察的东西很多。特地记下来,留作练习。

题目

使用面向对象的方式维护一个列表,每个列表都有一个删除按钮,点击删除按钮移除当前行。

思路

既然题目要求是使用面向对象的方式,那么我认为,使用ES6的class来声明一个类,然后维护这个类,这样是最好的方法。

在类中获取DOM元素,添加点击事件,在事件中进行移除DOM操作。

代码及分析

有了思路就来写代码吧。在线实例点我

<body>
  <ul class="list">
    <li> %%%%% 第一行<span class="del">x</span></li>
    <li> %%%%% 第二行<span class="del">x</span></li>
    <li> %%%%% 第三行<span class="del">x</span></li>
    <li> %%%%% 第四行<span class="del">x</span></li>
    <li> %%%%% 第五行<span class="del">x</span></li>
    <li> %%%%% 第六行<span class="del">x</span></li>
    <li> %%%%% 第七行<span class="del">x</span></li>
    <li> %%%%% 第八行<span class="del">x</span></li>
    <li> %%%%% 第九行<span class="del">x</span></li>
  </ul>
  <ul class="list">
    <li> ##### 第一行<span class="del">x</span></li>
    <li> ##### 第二行<span class="del">x</span></li>
    <li> ##### 第三行<span class="del">x</span></li>
    <li> ##### 第四行<span class="del">x</span></li>
    <li> ##### 第五行<span class="del">x</span></li>
    <li> ##### 第六行<span class="del">x</span></li>
    <li> ##### 第七行<span class="del">x</span></li>
    <li> ##### 第八行<span class="del">x</span></li>
    <li> ##### 第九行<span class="del">x</span></li>
  </ul>
</body>
</html>
    class List {
      constructor(sel) {
        this.el = Array.from(document.querySelectorAll(sel))
        console.log(this.el)
        let self = this
        this.el.forEach(item => {
          item.addEventListener('click', function(e) {
            if(e.target.className.indexOf('del') > -1) {
              self.removeItem.call(self, e.target)
            }
          })
        })
      }
      removeItem(target) {
        let self = this
        let findParent = function(node) {
          let parent = node.parentNode
          let root = self.el.find(item => item === parent)
          if (root) {
            root.removeChild(node)
            console.log("remove")
          } else {
            findParent(parent)
          }
        }
        findParent(target)
      }
    }
    window.addEventListener('DOMContentLoaded', function() {
      new List('.list')
    })

首先声明一个list类,在list类中,声明一个构造函数并传入一个选择器作为参数。使用document.querySelectorAll()api返回一个符合选择器节点的对象。然后使用Array.from()api以符合选择器要求的对象创建一个新数组。之后对这个数组进行遍历操作,给这个数组的每个item添加click事件,在回调中判断该元素是否是del类, 若是则用call()来进行事件绑定。

removeItem函数作为这个list类的一个属性,专门来管理删除DOM结构。因为list实例输入的是一个.list的节点,而点击的是一个.del的span标签,故我们需要通过递归来查找父级元素。如果该元素是root元素,则移除点击的这个node元素。

最后当稳中求稳,在HTML文档被完全加载后再执行new List('.list')

本文参考