面试官:让你设计一个placeholder的input输入框,你该怎么设计? placeholder知道吗?
我:placeholder? 有点印象,记不清了~~~
面试官:就是占位符文本,起提示作用的,在搜索输入框中经常见到。(注:如下图,这题也是今年的淘宝校招笔试题之一,从每次的面试中都是受益颇多~)
我:大致是用户鼠标点击的时候,占位符文本消失,失去焦点的时候判断文本是否为空,为空的话还原占位符文本。
面试官:很多时候,用户不一定只会用鼠标,他们会用键盘切换。
我:噢,那应该用focus事件,得到焦点占位符文本消失,失去焦点判断。
面试官:对,现在出现个情况,HTML5中对placeholder是原生支持的,既然是原生支持的,我们应该尽量用原生的,自己写的脚本就可以不用了。而为了做到兼容性,对于不支持HTML5的浏览器,我们需要启用我们的脚本,这样的话有什么解决方案吗?
我:(这题就没答好了,·实在么想到好的方法了,嗯了半天)浏览器检测~~~
面试官:有更好的方法吗?
我:判断特性节点的specified属性,如果是内置的话,这个属性是false,非内置的话则是true。
面试官:(似乎没听明白我在说什么- -!不过我也确实答错了,只要在HTML标签内指定了的属性,其对应的特性节点的specified都是true),没有那么复杂,只需要动态创建一个input元素,用in操作法判断placeholder是否在其内就行了,就是 return 'placeholder' in inputElem ,如果返回true的话,就直接使用原生的。
我:这样可以吗?(这里主要没搞明白:即使没有特别指定placeholder属性,在支持这个属性的浏览器中,也会返回true。经过后面自己的测试发现是可行的,前几个星期看的《HTML5揭秘》中也有专门的说明)。
面试官:你等会可以去试试。下一个问题,有用过什么框架么?
我:平常做项目是基于EXT的,主要用其UI组件,JQ有去稍微了解一下,源码看过大约1000行,但没用过JQ。
面试官:说说EXT和JQuery有什么不同
我:(这里JJWW了一大堆啊。。后面面试官也说了他自己的观点,我觉得这样很好啊,属于一个交流过程,从面试官那里聆听他们的看法,此处就省略掉我的看法了,各人有各人的观点,这个也不是一个bool题,这里推荐一篇文章web前端框架比较分析)
面试官:是否知道JQ的链式调用?说说看怎么去实现?
我:(这里也是JJWW了一会,去掉些废话,说重点)内部定义一个构造函数,对这个构造函数原型增加各种方法,每种方法都返回this;构造函数内部根据传入的选择符获得相关的DOM元素,保存为实例对象的属性,最后返回这个实例对象。 (更详细的在这链式调用原理)
面试官:好的,下一个问题,平常我们要在页面加载后执行些脚本,一般会用到window.onload,这样是否会有什么缺点么?
我:如果页面中有图片,或者iframe元素,必须要等到这些元素内容加载完毕后才会执行,而这些内容比较大,载入相对来说是比较缓慢;而很多情况下,执行脚本是不会涉及到这些元素的。
面试官:有什么解决方案么?
我:在支持W3C标准浏览器下,可以使用document的DOMContentLoaded事件,在IE下可以监听document的readystatechange事件(事实上,这个似乎是不对的,我测试了下,在document的readyState为complete的情况下,img和iframe的资源已经加载完毕了,期待有权威的同学帮忙讲解下这个事件的触发时机和作用。 这里应该答用document.write动态添加一个带defer属性的script标签,监听该标签的readystatechange事件的)。
面试官:(这里似乎没指明我答错了``)有时候onload会在readystatechange之前触发,这该怎么办?
我:打个完成标记就行了。
面试官:嗯,这种方式还是有缺点的,知道是什么吗?
我:页面中有iframe的情况下,会等待iframe的内容加载完毕后才执行(这里测试了下,如果但是document的readystate会等待img加载完毕后才变成complete,而动态添加defer属性的script则不会被img阻塞,但会被iframe阻塞)。
面试官:有什么解决办法么?
我:JQuery中是用doScrol, 这个方法我当时搜了下MSDN,不过具体用途我忘记了。(原理可以看这里:http://javascript.nwbox.com/IEContentLoaded/)
面试官:嗯,正好你的小框架中没有ready函数,你可以去添加一下。(注:发简历的时候,顺便把自己以前积累的一个1000多行的小框架和3个组件发过去了。),JQ的ready函数其实是有BUG的,当然也是在比较极端的情况下,你知道是什么吗?
我:。。这个我就不大清楚了,没有去细看。
面试官:这个不要紧,是这样的,如果在ready绑定的函数中继续调用ready,那么第二次的ready中的代码不会在文档加载完毕后执行。
我:额。。。(对JQ的ready的这个情况,我对面试官的回答做保留意见,其实我觉得这个不应该算BUG,好比onload的事件只触发一次,在onload的函数中再对onload绑定函数一样不会触发)。
面试官:最后一个问题,关于设计模式的,对装饰模式有什么理解?
我:(这个我没答好,设计模式需要长期实践才好理解啊=- =!! 当然面试官很NICE的说了他自己的理解,我这里就省略对话了)。
面试官:好的,我的问题问完了,你有什么问题要问我么?
我:(这里省略XX字)。
小结:
这里集中了2个主要问题,一个组件的实现和一个功能函数的实现,placeholder的设计在淘宝上海站中的笔试题中也出现了,准备把代码在应聘淘宝经历中写进去,这里就先不写出来了。下面贴出自己实现的ready函数代码- -!!
/* *DOM内容加载完毕后执行脚本代码 * fn:待执行的函数 * scope: fn的执行作用域 */ XX.domReady = function(fn, scope){ var doc = document, readyFn = null; if(doc.addEventListener){//W3C标准 readyFn = function(){ doc.removeEventListener('DOMContentLoaded', readyFn, false); fn.apply(scope); }; doc.addEventListener('DOMContentLoaded', readyFn, false); } /*IE下*/ if(doc.attachEvent){ readyFn = function(){ if(doc.readyState == 'complete' && !readyFn.done){ readyFn.done = true; fn.apply(scope); doc.detachEvent('onreadystatechange', readyFn); window.detachEvent('onload', readyFn); } }; doc.attachEvent('onreadystatechange', readyFn); window.attachEvent('onload', readyFn); void function(){ if(readyFn.done){ return; } try { document.documentElement.doScroll("left"); } catch(e) { setTimeout( arguments.callee, 1 ); return; } readyFn.done = true; fn.apply(scope); }(); } };
<!DOCTYPE html> <head> <title></title> <script type="text/javascript" src="xx.base.js"></script> <script> XX.domReady(function(){ alert(document.compatMode) alert("ready"); }); </script> </head> <body> <iframe width="200" height="300" src="frame.php"></iframe> <img alt="test" src="test.php" width="200" height="300" /> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> <p>aaaaaaaaaaaaaaaaa</p> </body> </html>
<?php sleep(5); echo "<p>frame loaded</p>"; ?>测试页面中img标签的test.php内容:
<?php sleep(3); echo file_get_contents("test.jpg"); ?>