2014阿里前端线上笔试题解答
2013-10-08 18:11
393 查看
No. 1
题目:
下图绿色区域的宽度为100%,其中有三个矩形,第一个矩形的宽度是200px,第二个和第三个矩形的宽度相等。请使用CSS3中的功能实现它们的布局。已知HTML结构是:
<div class="box"> <div class="item">column 1</div> <div class="item">column 2</div> <div class="item">column 3</div> </div>
解答:
.box { background-color: #619B99; display: -webkit-box; height: 40px; padding: 10px 0px 10px 210px; width: 100%; } .box>div { height: 40px; background-color: #EEEEEE; margin-right: 10px; } .box div:first-of-type { width: 200px; margin-left: -200px; } .box div:nth-of-type(n+2) { -webkit-box-flex: 1.0; }
这个题目感觉十分有趣,让在div中显示三个框,第一个宽度固定,后面两个宽度一致。自然
4000
想到了使用
margin-left,让框1脱离出来,使外部box真正的宽度仅仅为框2和框3的宽度,使之便于均分。但是在均分框2和框3的问题上我百思不得其解,因为如果要使用
width: 50%的话,一旦采用
margin的方法使之产生边距,就会把框3挤下去,不可能实现图中的效果。
这里看了原帖发现
-box-flex的属性,去查了一下发现不得了,这是css3的一个属性(请忽略我的无知),查了一下mdn,里面有句话说:
Content elements that have the same flex grow by the same absolute amounts.
这个并不是设定元素的绝对宽度,而是一个相对的概念,而我个人理解,
width: a%实际上仅仅是继承了上层元素宽度的百分比而已。使用了flex后,这个题目就得以良好的显示了。
由于盒子中的元素css属性并不相同,而其类名却都是一样的,因此有必要通过css选择器的方式来确定不同框之间的样式。这里就要提到css3里面新增的nth选择器(可以参见一下W3Cschool中的CSS选择器),在本例中使用的
div:first-of-type就是用来选取父元素box中的div子元素,当然也可以使用
item:first-child来代替,效果是一样的。但是这里的
div:nth-of-type(n+2)就比较玄幻了,这里n是一个计数器,从0开始记,而其内部的序号又是从1开始的,也就是说框1对于box来说,是第一个,框2是第二个。这里的n+2的意思,就是从第二个开始算,直到最后一个元素。所以就把2、3的样式调整的一致了。当然,也可以使用
nth-child(n+2)来代替。将上述的type-of转变为普通的nth,也即使用item类的代码如下:
.box { background-color: #619B99; display: -webkit-box; height: 40px; padding: 10px 0px 10px 210px; width: 100%; } .item { height: 40px; background-color: #EEEEEE; margin-right: 10px; } .item:first-child { width: 200px; margin-left: -200px; } .item:nth-child(n+2) { -webkit-box-flex: 1.0; }
No.2
题目:
有两个盒子 A、B,B 在 A 盒子中,它们的 CSS 是这么定义的:.A { position: relative; width: 500px; height: 500px; background-color: green; } .B { position: absolute; max-width: 300px; max-height: 300px; background-color: blue; }
如何实现 B 在 A 中水平方向和垂直方向居中?
解答:
作者在原文里表示可以使用CSS3的box-align和
box-pack的方法(W3C链接如下box-align,box-pack),但是在实际测试中发现,如果B的定位不是
absolute(而是
relative或者
static)那么如下追加的代码是有效的:
.A { display: -webkit-box; -webkit-box-align: center; -webkit-box-pack: center; }
但是当B的定位是绝对定位时,使用CSS3的box进行定位就起不到应有的效果。这里我们可以简单的看以下CSS的四种定位的原理(可参见mdn的解释:css position 以及quicksmode的这篇博文:the
position declaration)。
static:默认定位,不可使用
top
right
bottom
left四种属性(以下简称TRBL);
relative:相对定位,指的是针对默认定位的位置而产生偏移,可以使用TRBL调整定位的偏移量,但是元素本身还在文档流中占据位置;
absolute:绝对定位,指针对上一级非默认定位的位置(即上一级非
static定位的父元素的位置)而产生的偏移,可用TRBL调整偏移量,与相对定位不同的是,元素本身漂出文档流,不再占据位置;
fix:固定定位,锚定浏览器窗口的一种定位方式,可用TRBL调整偏移量。
这里B元素使用了绝对定位,也就是其偏移是针对A元素而计算的,可以使用TRBL进行调整。所以说莫非这里出题人是想让我们采用原始的div居中方法?
在CSS2的时代,要将div水平垂直居中也算是个挺让人头疼的问题,其大致的方法有如下几种:
外层元素宽度不固定,内层元素宽度固定:使用自动外边距或负值外边距两种方式;
自动外边距,这里要求内层元素不能采取绝对定位:
.B { width: 100px; margin: 0 auto; }
负值外边距,用到了TRBL属性,要求内层元素采取绝对定位:
.B { width: 200px; position: absolute; left: 50%; margin-left: -100px; }
外层元素宽度固定,内层元素宽度不固定,采用表格法,要求内部元素不能采取绝对定位:
A. { display: table; } .B { display: table-cell; vertical-margin: center; }
增添HTML元素、使用Hack、使用JS等,不详述之。
然而观察上面的方法,题目中的限定条件是:外部元素宽度固定、内部元素宽度变动且绝对定位,这样就导致上述的方法没有一个可以满足所需要求的。我认为如果不改变题目中的限定,可以使用负值外边距的方法,用JS设置内层元素的margin值;或者直接在后面的CSS中修改内层元素的定位(设置为非绝对定位),然后使用CSS3的
box-align和
box-pack来实现,而这也是目前我认为实现效果最好,实现代码最为简洁的实现方式。
其中如果附加JS,代码如下:
<script> var b = document.getElementsByClassName('B')[0] , l = b.offsetWidth , h = b.offsetHeight b.style.marginLeft = -l/2 + 'px'; b.style.marginTop = -h/2 + 'px'; </script>
No.8
题目:
现有代码如下:var foo = 1; function main(){ console.log(foo); var foo = 2; console.log(this.foo) this.foo = 3; }
请给出以下两种方式调用函数时,输出的结果,并说明原因。
var m1 = main(); var m2 = new main();
如果想要
var m1 = main()产生的m1和前面的m2完全一致,又该如何改造main函数?
解答:
看到全局变量与函数内局部变量重名时,一定要先想到 hoisting (变量声明提升规则)!在第一种调用方式里,函数内部声明了局部变量
foo,因此其声明被提升至最前。因此该段代码等价于:
function main(){ var foo; console.log(foo); foo = 2; console.log(this.foo) this.foo = 3; }
在调用的时候,第一次输出为undefined,因为局部变量
foo还没有被赋值,第二次输出为1,因为此时在非严格模式下
this指代
window对象。
this.foo即为全局变量的
foo。
在第二种调用方式里,使用了原型链继承的方法,可以参见我的这篇文章:JavaScript原型继承工作原理,其中
new运算符的作用等价于如下函数:
function New (f) { var n = { '__proto__': f.prototype }; return function () { f.apply(n, arguments); return n; }; }
则在进行
new运算时,函数中的
this实际上指代的是运算符后面所跟的构造函数的原型链。因为在
new运算的时候,实际上执行构造函数的是这一步:
f.apply(n, arguments);也就是说在构造函数中的
this实际上指向的是变量
n,而
n是一个除了原形链指向
f的原形链之外一无所有的空对象,所以这里的
this实际上是指向了构造函数
f的原形链。
所以这里的输出也就不难理解:因为构造函数
main()本身的原形链为空,所以输出
this.foo的结果为
undefined。
然后是第二问:使m1与m2的结果完全一致。我们知道m2所得到的是类
main的一个实例化对象,这里要使得达到题目中的要求,就只能手工编写原形链继承,使
main函数的返回结果为一个继承自其本身的对象。这里可以参考上面代码中
new运算符的具体实现,编写
main函数如下:
function main(){ console.log(foo); var foo = 2; console.log(this.foo) this.foo = 3; //返回一个main的实例化对象 var n = {'__proto__': main.prototype}; //main.apply(n, arguments); n.foo = 3; return n; }
这里因为在
main函数里有
this.foo = 3这一项,为原型添加了成员变量,但如果在这里使用
apply的方式为n添加这一属性的话,将进行无限递归导致栈溢出。而采取其他的方式都不可避免的会带来一些问题,所以直接给返回值n的属性foo进行了赋值,也起到了同样的效果。
No.9
题目:
实现如下图所示的布局,要求:sidebar 固定宽度200px,content和header宽度自适应;
当window宽度小于600px时,变成三行布局。
默认如下
宽度小于600px时如下
下面是html结构:
<div class='header'> <h1>header</h1> </div> <div class="sidebar> <h1">sidebar"</h1> </div> <div class="content"> <h1>content</h1> </div>
请写出其css代码:(提示,可以使用media query来检测浏览器窗口宽度)
解答:
这里涉及到CSS的media query检测,这里有篇文章详细介绍了其中的参数类型,而这篇文章则饶有性质的探讨了不同设备下应该如何编写mediaquery,有兴趣的读者可以详细看一下。针对这个题来说,只要用到
screen and (min-width)即可。代码如下:
h1 { margin: 0; } section div{ height: 100px; } section div:nth-of-type(n+2) { margin-top: 20px; } .header { background-color: red; } .sidebar { background-color: green; } .content { background-color: blue; } @media screen and (min-width: 600px) { .sidebar { width: 200px; position: absolute; } .content { margin-left: 220px; } }
这里还需要注意一个问题:sidebar的宽度固定,而content填充剩余的全部。针对这种一边固定而一边液态的情况,最好的解决办法就是将固定的部分浮动出来,然后将液态的部分使用margin来填充固态部分浮动而产生的空隙。这里使用了绝对定位,以满足题目中的要求。
No.10
题目:
写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1), 依次类推。解答:
起初做这个题目的时候简单的认为所有链接应该指的就是<a>,所以很快写出了代码如下:
var body = document.getElementsByTagName("body")[0] , links = document.getElementsByTagName("a") , len = links.length , foo = function(e){ if (e.target.tagName.toLowerCase() !== 'a') //注意这里的tagName是大写 return for (var i = 0; i < len; i++) { if (links[i] === e.target) alert(i + 1) } } body.addEventListener('click', foo, false)
但是后来看到网上有一个本题的解答:最英俊的程序员 阿里巴巴2013年校园招聘前端工程师笔试题详解,解答中使用了
document.links的方法,查了一下发现这个数组返回的是所有有
href的和标签,才知道链接不止有一种,那么可以把代码改成如下的样式:
var body = document.getElementsByTagName("body")[0] , links = document.getElementsByTagName("a") , len = links.length , foo = function(e){ var tagName = e.target.tagName.toLowerCase() if ((tagName === 'a' || tagName === 'area') && e.target.href) { for (var i = 0; i < len; i++) if (links[i] === e.target) { alert(i + 1) } } } body.addEventListener('click', foo, false)
当然也可以采用网上最英俊的程序员的解答,在页面中每一个链接都绑定事件监听,只不过这样显得有些效率不高,特别是在页面链接过多的情况下。个人认为相同效果的事件监听还是在父级元素上绑定为好,要不就可惜了JS冒泡的监听机制啊。
No.14
题目:
(new Date).getTime()和
+new Date()都可以取到当前时间戳,它们的实现原理是什么,哪个效率更高?
解答:
这个题目挺有趣,起初我认为应该是第二个写法的效率更高……因为写起来更容易,但是经过实际的检验我意识到了我的错误,第一种写法所耗的时间基本上只有第二种写法的一半。后来查阅了MDN:Date.getTime 发现这个函数本身实际上等价于valueOf,那么结论也呼之欲出了。因为第一种方法实际上直接调用了
valueOf,而第二种方法涉及到JS内部的类型转换(可以参见我的这篇文章:【WEB前端】百度前端面试经历小研究1——JavaScript
类型转换),尽管最终的结果也是调用了
valueOf函数,但是毕竟有个转换的过程,所以效率理应比前者要来的低下吧。
No.16
题目:
请写一个 getParents 方法让它可以获取某一个 DOM 元素的所有父亲节点。解答:
第一反应就是想到jQuery里面的getParents(),自己想了一下JS中可以获取
parentNode,所以应该循环获取就可以了。解答如下:
function getParents(ele) { var matched = [] // 防止获取 document while ( (ele = ele.parentNode) && ele.nodeType !== 9) { matched.push(ele) } return matched }
No.20
题目:
有一个数组,其中保存的都是小写英文字符串,现在要把它按照除了第一个字母外的字符的字典顺序(字典顺序就是按首字母从a-z顺序排列,如果首字母相同则按第二个字母……)排序,请编写代码例:["abd","cba","ba",],排序后["ba","cba","abd"]
解答:
这个题目是专门凸显JS函数式编程特点的题目,结果原作者居然用C语言解答了……捂脸。这里给出JS的写法,十分简洁明了。var bySecLetter = function(x, y) { if (typeof x === 'string' && typeof y === 'string') { var a = x.slice(1) , b = y.slice(1) if (a > b) return 1 if (a < b) return -1 } return 0 } var a = ["abd","cba","ba"] a.sort(bySecLetter)
这里只需要调用sort的比较函数,大于返回正数,小于返回负数,等于返回0即可。而作为字符串,本身的比较顺序就是字典顺序,所以只需要截取从第二个字符开始的字串进行比较,就可以得出比较结果。更多关于sort函数的信息可以参见MDN的链接。
转自:http://www.ituring.com.cn/article/56881#
http://www.ituring.com.cn/article/57466#
相关文章推荐
- 2014阿里前端线上笔试题
- 阿里2014前端线上笔试题
- 阿里巴巴2014前端线上笔试题
- 2014阿里巴巴前端在线笔试题及自己所做解答
- 阿里前端线上笔试题以及答案总结
- 2014阿里前端线上笔试题
- 美团笔试2014-美团网举行女子羽毛球比赛,前端组、后短租、手机组各派了三名运动员参加。比赛前,4名程序员在一起预测比赛结果。
- 百度2014研发类校园招聘笔试题解答
- 2014阿里巴巴WEB前端实习生在线笔试题
- BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
- 阿里前端笔试题2
- BAT及各大互联网公司2014前端笔试面试题:HTML/CSS/JAVASCRIPT
- 各大互联网公司2014前端笔试面试题–JavaScript篇
- 美团网2014校招笔试题及解答(长沙站+哈尔滨站)
- 百度2014校园招聘研发类笔试题解答
- 2014阿里前端实习生在线测试题目
- BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇
- BAT及各大互联网公司2014前端笔试面试题--Html,Css篇
- 百度2014前端笔试题
- BAT及各大互联网公司2014前端笔试面试题:HTML/CSS篇