已经自学前端的各方面的知识差不多有一年了,但是,最近辞掉原来的那份工作后,出来找前端的实习工作。没想到遇到互联网寒冬,几个招聘软件所有的前端实习岗位都投了一遍,差不多都石沉大海,只有一间正规的公司叫去面试,特别点名某联招聘软件,已经被一些培训机构占领了。
回到主题,第一个公司叫做一个Euditou的一个插件,但是没有做出来,有教程,但是教程和我在官网下载的文件有一点出入,所以也没有做成功,就没做了,第二个公司叫做就是我现在做的面试题,这个我用javascript原生来做,不用jquery做,这个面试题让我得到了很多的收获,特别对原生javascript方面的知识,毕竟我没有做过项目,还是一个连门都没有的前端。
题目
![](https://img.haomeiwen.com/i16237842/9f115fdeb87a7469.png)
- 如图所示,实现增加行和增加列的功能,点击“增加一行”,应该出现空白行,如图中没有圆圈那个”增加“按钮。
- 点击每行的 “增加” 增加一个圆圈,数字依次为1,2,3... 。
- 点击圆圈时,圆圈被删除(里面的数字同时被删除),后面的圆圈数字重新排列,如删除 3,则后面的 4 补上来并改为3,以此类推。
我的做法
-
先写好页面,要求用flex 布局,html 和 css 的内容太久没有用了,要边差边做,后面说到我是写 js 的时候也改页面,css 的就不贴出来了,写得太差了
<div class="wrap"> <div class="one"> <div class="span"> <span>1</span> <span>2</span> <span>3</span> <span>4</span> </div> <button class="ft_btn">增加</button> </div> <div class="one"> <div class="span"> <span>1</span> <span>2</span> <span>3</span> </div> <button class="ft_btn">增加</button> </div> </div> <!-- wrap end --> <div class="third"> <button id="ad_btn">增加一行</button> </div>
-
开始写 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)
-
添加功能就愉快得实现了,再按照这样的方式来实现删除功能
-
实现删除功能,要用到 事件委托
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)
-
-
问题来了,当我现要实现当 点击 增加每一行 后 ,也要想 实现增加 和 删除 功能,面临的问题是 增加 和 删除 都是 动态生成的 上面的方法 都是页面在加载完毕后就存在的,所以原来的方法不能用了
-
那时候就卡在了这个地方,怎么想都想不出来,那时候的页面结构很乱的 ,后来就想到用事件委托,页面结构修改来修改去,最终变成现在的样子,操作起来都方便多了
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个小时才做出来的,作为一个新手,能做出来已经不错了,所以不抱多大希望,同时也复习了事件委托,兄弟元素,父元素,是怎么获取的。
如有更好的写法,请发一份文件给我 412376353@qq.com
网友评论