分享一道简单的前端面试题

2016-12-20 17:29:17 +08:00
 Lothar
<ul id="list" class="foo">
  <li>#0</li>
  <li><span>#1</span></li>
  <li>#2</li>
  <li>#3</li>
  <li><ul><li>#4</li></ul></li>
  ...
  <li><a href="//v2ex.com">#99998</a></li>
  <li>#99999</li>
  <li>#100000</li>
</ul>

最近又来了个资深工程师面试,结果现场写代码环节写不出上面类似的题目。🌚

讲道理这题真的不难啊,就是简单的 DOM 操作,没有任何奇技淫巧,现场写:一台 MBP / 30 分钟 / 允许 Google ,只要基本功够扎实应该都能写出来吧。

其实现场考的版本比这个还简单,这个是为了发帖稍微整理后的版本,大家来喷一波。


(顺便补个广告,招前端,薪资对标阿里 P6 ,可年后入职,年前入职可以补偿年终奖,因为不是招聘结点我就不放邮箱了,有兴趣私我哈)

15752 次点击
所在节点    程序员
108 条回复
wungqiang
2016-12-21 10:24:48 +08:00
考察点:
- 会考虑到特性检测吗 if ('querySelectorAll' in xxx) {}
- 选择器会用 id selector 还是 class selector
- 闭包实现,深入问其它方法
- DOM 基本操作
- 性能及其它
hanyang
2016-12-21 10:30:32 +08:00
不管用什么库 这些操作 DOM 的基本知识都是要掌握吧
homfen
2016-12-21 10:31:48 +08:00
贵公司的资深工程师要求好低
hanyang
2016-12-21 10:37:03 +08:00
@homfen 这不是公司资深的要求吧 楼主标题也说了是 一道简单的前端面试题 是有个`资深工程师` 来面试而已
henryxie2093
2016-12-21 10:49:36 +08:00
帖子标题本来就说明白了,为什么大家还要说这题没难度
chemzqm
2016-12-21 10:55:03 +08:00
@Septembers 最后写错了, e.target 会找到 li 下的 span
Lothar
2016-12-21 11:29:47 +08:00
@haocity 有些小问题,插入的文字内容不对。后面一次绑定 10 万个事件监听不太好吧...😂
haocity
2016-12-21 11:34:08 +08:00
@lynth
额 审题不严 当时在上别的课 就看了一遍题目 记不清了 写了直接发上来来了
ul.className+=' foo';这里也写错了 应该是加上 bar ul.className+=' bar';
li 改成这样方法来取
var li=[];
for (var i = ul.childNodes.length - 1; i >= 0; i--) {
if(ul.childNodes[i].nodeName=='LI')
{
li.push(ul.childNodes[i])
}
}
hoosin
2016-12-21 11:36:48 +08:00
居然没有一个人封装一下

```js

var $ = document.querySelector.bind(document)

```
ZoomZhao
2016-12-21 11:41:50 +08:00
echol
2016-12-21 11:43:36 +08:00
不是很懂

(function(){
const rootNode = document.querySelector('#list');
/*#1*/
rootNode.classList.add('bar');
rootNode.querySelectorAll('ul').classList.add('bar');
/*#2*/
const delindex = 10, addindex = 500;
const liNodes = rootNode.querySelectorAll('li');
rootNode.removeChild(liNodes[delindex - 1]);
/*#3*/
const escapeHtml = function(string) {
var entityMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': '&quot;',
"'": '&#39;',
"/": '&#x2F;'
};
return String(string).replace(/[&<>"'\/]/g, function (s) {
return entityMap[s];
});
}
const addnode = document.createElement('li');
addnode.innerHTML = escapeHtml('<v2ex.com />');

if(liNodes[addindex -1].nextElementSibling == null){
liNodes[addindex -1].parentElement.appendChild(addnode);
}
else{
liNodes[addindex -1].nextElementSibling.insertBefore(addnode);
}
/*#4*/
for(let i = 0, max = liNodes.length; i < max; i++){
liNodes[i].setAttribute('data-index', i);
}
rootNode.addEventListener('click', (e) => {
if(e.target.nodeName !== 'LI') return;
alert(e.target.getAttribute('data-index'));
}, false);
})
echol
2016-12-21 11:45:29 +08:00
@echol #1 忘了应该 for....然后再加上了=。=
Septembers
2016-12-21 12:13:48 +08:00
@chemzqm event.target.closest('li') 就对啦 不过没有考虑深度嵌套
Septembers
2016-12-21 12:16:08 +08:00
GeoffZhu
2016-12-21 12:17:30 +08:00
@chemzqm 他那个答案,细看错的好多
Septembers
2016-12-21 12:17:55 +08:00
@ZoomZhao see http://mdn.io/closest

@echol escapeHtml 用不着这样
textContent 就好啦
see http://mdn.io/textContent
ahkxhyl
2016-12-21 12:21:06 +08:00
jquery 可以搞搞 纯 js 查资料可以~~ 非前端人员 打酱油后端 php 路过~~
exoticknight
2016-12-21 12:52:35 +08:00
后悔没去饿了么校招……
1. classList.add 或者 className
2. children[9] 或者 nth-of-type(10), removeChild
3. insertAdjacentElement('afterend', '<li>&lt;v2ex.com /&gt;</>'),不想转码就老老实实 createElement + innerText / textContent ,再 insertAdjacentElement
4. 事件委托大家都会了……重点代码就是 [].slice.call(ul.children).indexOf(e.target),不过 indexOf 可能有兼容问题,换 for 循环也可以
Anshi
2016-12-21 13:08:10 +08:00
会这道题不代表满足这个职位的其他要求啊。。。囧
echol
2016-12-21 13:14:27 +08:00
@Septembers 印象里有这个作用的 api 就是没想到,多谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/328943

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX