前端机试题

​ 已经自学前端的各方面的知识差不多有一年了,但是,最近辞掉原来的那份工作后,出来找前端的实习工作。没想到遇到互联网寒冬,几个招聘软件所有的前端实习岗位都投了一遍,差不多都石沉大海,只有一间正规的公司叫去面试,特别点名某联招聘软件,已经被一些培训机构占领了。

​ 回到主题,第一个公司叫做一个Euditou的一个插件,但是没有做出来,有教程,但是教程和我在官网下载的文件有一点出入,所以也没有做成功,就没做了,第二个公司叫做就是我现在做的面试题,这个我用javascript原生来做,不用jquery做,这个面试题让我得到了很多的收获,特别对原生javascript方面的知识,毕竟我没有做过项目,还是一个连门都没有的前端。

题目

1.png
  1. 如图所示,实现增加行和增加列的功能,点击“增加一行”,应该出现空白行,如图中没有圆圈那个”增加“按钮。
  2. 点击每行的 “增加” 增加一个圆圈,数字依次为1,2,3... 。
  3. 点击圆圈时,圆圈被删除(里面的数字同时被删除),后面的圆圈数字重新排列,如删除 3,则后面的 4 补上来并改为3,以此类推。

我的做法

  1. 先写好页面,要求用flex 布局,html 和 css 的内容太久没有用了,要边差边做,后面说到我是写 js 的时候也改页面,css 的就不贴出来了,写得太差了

    1 2 3 4
    1 2 3

  2. 开始写 js 代码了,我是先实现 点击每一行的增加 增加一个圆圈,点击圆圈 删除圆圈并重新排列,然后把可以看得到的先写成方法,在通过调用方法来实现。

    • 1.实现增加一行的功能
        var wrap = document.querySelector(".wrap") //获取容器
    
        var ftBtnALL = document.querySelectorAll(".ft_btn")  //获取所有的class名为 .ft_btn 的 button 标签
        var ftBtn1 = ftBtnALL[0] //获取第一个class名为 .ft_btn 的 button 标签
        var ftBtn2 = ftBtnALL[1] //获取第二个class名为 .ft_btn 的 button 标签
        
        var addRow = document.querySelector("#ad_btn") //获取 id名为 ad_btn 的button 标签 
        
       
        var i = 0  //用来计数的
        addRow.addEventListener("click" , function () {
          var div = document.createElement("div")  //创建一个div
          div.classList.add("one")  //为创建的div 添加一个class 名为 one
          var divspan = document.createElement("div") //创建另一个 div
          divspan.classList.add("span") //为另一个div 添加一个 class 名 为 span
          var btn = document.createElement("button")  //创建一个 button 
          btn.classList.add("btn" + i)  //为创建的button 添加一个 class 名 为btn + i ,i 在这里用上了
          i++
          btn.innerText = "增加" //为创建的button 按钮 增加文本
          div.appendChild(btn) //把创建的 button 添加到 创建的 div 上
          wrap.appendChild(div) //把创建的 div 添加到容器上
        } ,false)
    
    • 2实现 点击每一行的 增加 实现添加圆圈

          var spanAll = document.querySelectorAll(".span") //获取页面上所有的 class 名为 .span 的 div 标签
          var span1 = spanAll[0] //获取第一个class 名 为 .span 的 div 标签
          var span2 = spanAll[1] //获取第二个class 名 为 .span 的 div 标签
      
          var spans1 = span1.getElementsByTagName("span") //获取第一个class 名 为 .span 的 div 标签 下面的 所有标签
          var spans2 = span2.getElementsByTagName("span") //获取第二个class 名 为 .span 的 div 标签 下面的 所有标签
          
          
         function addOne (btnClass, spansClass,spanClass) {
            btnClass.onclick=function(){
             var spanCount = spansClass.length 
             spanCount++
             var span = document.createElement("span");
             span.innerText = spanCount
             spanClass.appendChild(span)
             }
          }
      
          addOne(ftBtn1,spans1,span1)
          addOne(ftBtn2,spans2,span2)
      
  3. 添加功能就愉快得实现了,再按照这样的方式来实现删除功能

    • 实现删除功能,要用到 事件委托

      function removeOne (spanClass, spansClass) {
             spanClass.onclick = function (ev) {
          var ev = ev || window.event;
           var target = ev.target || ev.srcElement;
              if(target.nodeName.toLowerCase() == 'span'){
               this.removeChild(target)
           }
            
               for (let i = 0; i < spansClass.length; i++) {
             spansClass[i].innerText = i + 1
             }
           }
         }
      
         removeOne(span1,spans1)
         removeOne(span2,spans2)
      

  4. 问题来了,当我现要实现当 点击 增加每一行 后 ,也要想 实现增加删除 功能,面临的问题是 增加删除 都是 动态生成的 上面的方法 都是页面在加载完毕后就存在的,所以原来的方法不能用了

  5. 那时候就卡在了这个地方,怎么想都想不出来,那时候的页面结构很乱的 ,后来就想到用事件委托,页面结构修改来修改去,最终变成现在的样子,操作起来都方便多了

    let spansLength=0 //定义一个计数的标记
            wrap.addEventListener("click",function(ev) {
              let e = ev || window.event;
              let target = e.target || e.srcElement;
    
               if(target.nodeName.toLowerCase() == 'button'){  //判断当前点击的对象是不是 button 按钮
                let thisTargetSiblingChild = target.previousElementSibling.children //获取当前点击的按钮的上一个兄弟元素下的所有子元素
                     if (thisTargetSiblingChild.length == 0) { //判断当前 兄弟元素下是否有子元素
                  spansLength = 1; //如果没有,计数标记为1
                     } else {
                         spansLength = target.previousElementSibling.children.length + 1 //如果有,就让计数标志等于兄弟元素的长度加 1
                     }
                 let span = document.createElement("span")
               span.innerText = spansLength
                 target.previousElementSibling.appendChild(span)      
                }
    
             if (target.nodeName.toLowerCase() == 'span') { //判断当前点击的对象是不是 span 标签
                   let parent = target.parentNode //在删除这个 span 标签前,保存他的父节点
                   target.remove() //移除当前的 span 标签
                for (let i = 0; i < parent.children.length; i++) {  //循环剩下的 span 标签,并重新排序其内容
                    parent.children[i].innerText = i + 1 
                 }
               }
             } ,false)
    

总结

这个面试题我用了6个小时才做出来的,作为一个新手,能做出来已经不错了,所以不抱多大希望,同时也复习了事件委托,兄弟元素,父元素,是怎么获取的。

如有更好的写法,请发一份文件给我 [email protected]

你可能感兴趣的:(前端机试题)