掌握面试——弹出框的实现
这道面试题,当初我面试的时候被问过两次,因此比较深,此外,我记得还有设计模式的考察,所以,有深刻的体会。
面试题主要考察什么
面试不是个轻松的活,不管是对面试官还是面试者都一样。对于面试官来说,别的先不管,首先一点技术要过关,对候选人的基本要求就是基础扎实,有相关项目经验,有解决问题的能力,思路清晰,易于沟通。而对于面试者来说要技术扎实,知识面要广,要有技术闪光点,对于各种技术提起来都知道点,但经不起深层次的询问,这种‘一瓶子水不满,半瓶子水晃地’现象很不受面试官的喜欢。
虽然,我工作的时间不长,但被面试过,也面试过别人。所以,将这道题被问的情况和自己的体会理解分享给大家。
注:面试公司 去哪儿,360
用 html + css 实现一个弹出框
注:这是按照面试官的预想可能出现的情况设定的,不同的面试者临场发挥不一样,面试官可能问的问题也有所变化,但归根结底,这个系列的问题大致如下。
这里你在回答前需要问清楚实现有什么限制没,如果没有,你可以以任意的方式来实现;如果有,问清楚限制,一般限制有如下情况,一种定宽定高,另一种不定宽高(补丁宽高一般用js控制),但是使用css3亦可实现,如果你回答出一种,面试官往往会问有没有其他的实现方法,如果面试管这样问了,你如果,回答没有,会被扣分的。面试会进入下一个环节。
弹出框垂直水平居中
html:
<div class="box-default box-wh box-vc-mar">this is a pop-up box</div>
css:
.box-default {
position: fixed;
top: 50%;
left: 50%;
z-index: 99;
padding: 20px;
background-color: white;
border: 1px solid #ccc;
border-radius: 8px;
}
.box-wh {width: 200px;height: 200px;
}.box-vc-mar {margin-left: -100px;margin-top: -100px;
}
JSFiddle效果演示
如果弹出窗的宽高不定
html:
<div class="box-default">this is a pop-up box</div>
css:
.box-default {position: fixed;top: 50%;left: 50%;z-index: 99;padding: 20px;background-color: white;border: 1px solid #ccc;border-radius: 8px;
}.box-vc-mar {margin-left: -100px;margin-top: -100px;
}
js:
var $box = $('.box-default'),bw = $box.width(),bh = $box.height();
$box.css({marginLeft: - bw/2 + 'px',marginTop: - bh/2 + 'px',
});
JSFiddle效果演示
有没有其他方式实现不定宽高的弹出窗
答案:有
html:
<div class="box-default box-vc-trf">this is a pop-up box that only html+css</div>
css:
.box-default {position: fixed;top: 50%;left: 50%;z-index: 99;padding: 20px;background-color: white;border: 1px solid #ccc;border-radius: 8px;
}.box-vc-trf {-webkit-transform: translate(-50%, -50%);-ms-transform: translate(-50%, -50%);-o-transform: translate(-50%, -50%);transform: translate(-50%, -50%);
}
JSFiddle效果演示
4.如果给弹出窗加一个遮罩层该如何实现
html:
<div class="box-default box-vc-trf">this is a pop-up box that only html+css</div>
<div class="mask"></div>
css:
.box-default {position: fixed;top: 50%;left: 50%;z-index: 99;padding: 20px;background-color: white;border: 1px solid #ccc;border-radius: 8px;
}
.box-vc-trf {-webkit-transform: translate(-50%, -50%);-ms-transform: translate(-50%, -50%);-o-transform: translate(-50%, -50%);transform: translate(-50%, -50%);
}
.mask {position: fixed;top: 0;right: 0;bottom: 0;left: 0;z-index: 98;background-color: #000;opacity: 0.75;filter: alpha(opacity=75);
}
JSFiddle效果演示
下面的问题就问的比较深了,牵涉到了一些简单业务实现
触发按钮实现弹窗
根据是之前实现的结果,如果在页面中有一个按钮,通过触发钮如何实现弹出窗以及实现关闭弹出窗
示例代码如下:
html:
<div class="box-default box-vc-trf">this is a pop-up box that only html+css</div>
<div class="mask"></div><button id="btn">click it</button>
css:
.box-default {position: fixed;top: 50%;left: 50%;z-index: 99;display: none;padding: 20px;background-color: white;border: 1px solid #ccc;border-radius: 8px;
}.box-in {display: block;
}.box-vc-trf {-webkit-transform: translate(-50%, -50%);-ms-transform: translate(-50%, -50%);-o-transform: translate(-50%, -50%);transform: translate(-50%, -50%);
}.mask {position: fixed;top: 0;right: 0;bottom: 0;left: 0;z-index: 98;display: none;background-color: #000;opacity: 0.75;filter: alpha(opacity=75);
}.mask-in {display: block;
}
js:
var $box = $('.box-default'),$mask = $('.mask'),$btn = $('#btn');$btn.on('click', function(event) {event.preventDefault();$box.addClass('box-in');$mask.addClass('mask-in');
});$mask.on('click', function(event) {event.preventDefault();$(this).removeClass('mask-in');$box.removeClass('box-in');
});
JSFiddle效果演示
这个只是我的实现,每个人的实现都会有所不同。
此外,像这里如何关闭弹出窗的实现方式,并不一定要通过触发遮罩层来实现,我们常见的实现是在弹出窗中加一个关闭按钮。像在这里这种模棱两可的地方,往往存在陷阱,我建议在你给出答案前先问清楚这个关闭弹出窗要如何实现,并给出自己的方案,因为在实际的项目开发的过程有些细节问题产品经理并不会面面俱到,会有疏漏的地方,而作为一个前端你要及时的提出来,进行沟通确认,这里可能会考察你的观察,判断和沟通能力。但有些时候你问过后,面试官会对你笑笑,让你自由发挥,你这时就会明白,这是一处坑。但有时候不是这样,所以,面试时要主动与面试官沟通,避免因细节问题在面试过程中被降分。
如果在页面中有多个按钮,那么这个弹出窗要如何实现
同上,根据之前的建议在回答问题之前要问清楚问题中模棱两可的地方。
1.多个按钮是不是成百上千个,或者就是几个。
2.是否触发不同按钮弹出的窗口现实的内容不同。
同时也可以不问,你只要明白要考察的知识点即可,问只是让你更清楚的知晓面试官的考察点。
html:
<div class="box-default box-vc-trf">this is a pop-up box that only html+css</div>
<div class="mask"></div><button class="btn">click</button>
<button class="btn">click2</button>
<button class="btn">click3</button>
<button class="btn">click4</button>
<button class="btn">click5</button>
<button class="btn">click6</button>
css:
css 同上个示例
js:
$(function(){var $box = $('.box-default'),$mask = $('.mask');$mask.on('click', function(event) {event.preventDefault();hideMask();});$('.btns').forEach(function(el, i) {el.on('click', function(event) {event.preventDefault();var content = getText($(this));showMask(content);}});function getText(obj) {return obj.text()}function showMask(content) {$box.addClass('box-in').html(content);$mask.addClass('mask-in');}function hideMask(obj) {$mask.removeClass('mask-in');$box.removeClass('box-in');}
});
这里主要考察了两点:
1.js基础是否扎实
- 表现和行为的分离
- 可维护性
- 可扩展性
2.是否使用了事件代理
代码修改如下:
$(function(){...$(document.body).on('click', '.btn', function(event) {event.preventDefault();var content = getText($(this));showMask(content);});...
});
JSFiddle效果演示
有时候面试官会让你用原生js来实现事件代理,那么我们应该如何回答呢?
由于事件委托可以实现目标对象的隐藏,在开发这对于我们保护一些核心的对象非常有用,不过实话来说,在JavaScript中就是call,apply的使用,因为js中只有这两个方法提供了改变当前函数内部this作用域的功能。当然这只是对象的委托,而要实现对类的委托则要相对复杂些,对类的实现大家有兴趣的可以参考以下Prototype.js或Jquery中的相应实现。
事件代理就要改变侦听器的位置,或者说改变事件绑定的对象。得益于js的事件传播机制,实现起来非常容易。
下面这个例子大家都可能见过:
html:
<ul id="nav"><li><a href="http://blog.csdn.net/weixin_41559723?ref=toolbar/">CSDN</a></li><li><a href="https://segmentfault.com/u/birenyangguangcanlan">Segmentdefault</a></li><li><a href="https://github.com/lvzhenbang">github</a></li><li><a href="https://juejin.im/user/58b83c66128fe100642f5297/">稀土掘金</a></li><li><a href="https://home.cnblogs.com/u/1309794/">博客园</a></li>
</ul>
js:
window.onload = function(){var nav = document.getElementById("nav");nav.onclick = function () {var e = arguments[0] || window.event,target = e.srcElement ? e.srcElement : e.target;if (target.nodeName.toLowerCase() === 'a')alert(target.innerHTML);return false;}
}
JSFiddle效果演示
var addEvent = (function () {if (document.addEventListener) {return function (el, type, fn) {el.addEventListener(type, fn, false);};} else if (document.attachEvent) {return function (el, type, fn) {el.attachEvent('on' + type, fn);}} else {el['on' + type] = fn}})();
上面这个事件监听的兼容性代码片段,是面试官问我是否对jQuery源码有所了解,我当然说有,就让我说一下如何实现。
好了,关于事件代理的问题就不深入讨论了,我们接着了解关于弹出窗的其他问题。
遮罩层的共用问题
同一个页面我们可以考虑,直接在页面中加一个表示遮罩层的div,
但是对于不同的页面我们最好用js来控制。
问题:这里面试管会问,如何实现遮罩层的共享?
我们通常会写下面的一个代码片段:
function createMask() {return $(document.body).append($('<div>').addClass('mask'));
}
虽然,这样添加一个遮罩层,在隐藏的时候可以使用remove()移除它,但显然这样在页面中频繁的添加,删除dom元素不合理。
问题:有没有什么方法可以对它进行优化?
我们可能会考虑对它进行优化,先在全局创建一个这个遮罩层div,用一个变量来引用它。代码如下:
var mask = $(document.body).append($('<div>').addClass('mask'));
这样页面就只会创建一个遮罩层div,但是可能出现,我们在使用的过程中不会用到这个div,这样我们就会造成资源的浪费,dom的节点就会平白多出一个无用的div。
这时我们可以借助一个变量来判断是否创建过div。代码如下:
var mask;
function createMask() {if (mask) {return mask;} else {mask = $('<div/>').addClass('mask').appendTo($(document.body));return mask;}
}
细心的你是否发现这是一个单例?
当你在面试前对这个问题有研究,你说用一个单例模式来解决,面试官会让你先实现,然后让你说说单例模式的理解,最后询问相关的问题。如:什么是单例模式,单例模式有何优缺点,如何使用单例模式。
但是也有时候面试官会让你直接使用一个设计模式来对它进行优化?
在这里,面试官的询问方向跟面试官的知识面和掌控度有关。所以,面试大厂或者面试中/高级工程师的童鞋还是把自己的所学知识技能系统化比较好。
你发现上面那段代码实现有哪里不妥吗?对了,你在函数体内改变了函数外的变量mask的引用,在多人协作的项目中,你写的createMask是一个不安全的函数,此外我们开发中应尽量避免像mask这样的全局变量使用,用一个局部变量如何来解决这个问题呢,我想很多同学会想到闭包,修改后的代码如下:
function createMask() {var mask;return function() {if (mask) {return mask;} else {mask = $('<div/>').addClass('mask').appendTo($(document.body));return mask;}}
}
好吧,到了这里你可能在心里想‘这下总算完了吧’,是的,我想说的是这道题你答成这个样子,对于中级工程师来说已经过关了,但是对于高级工程师来说,你还需要对这个代码进行优化,如果经常研究源码的童鞋会见到这样写的代码片段:
function createMask() {var mask;return function() {return mask || mask = $('<div/>').addClass('mask').appendTo($(document.body)); }
}
对于那些开发框架,常用库或插件的大牛来说,同样的功能,同样的性能,不会多浪费一个字符。
如果是面试高级工程师,可能还会被问到,如何多个功能都要用到单例模式,该如何解决?
function singleton(fn) {var res;return function() {return res || (res = fn.apply(this, arguments))}
}var createMask = singleton(function () {return $('<div/>').addClass('mask').appendTo($(document.body));
});
其实,这里又用到了另一种设计模式——桥接模式。
面试到这里一般就算完了。通过上面的代码我们发现,设计模式也不是什么洪水猛兽,只不过是设计模式的使用灵活多变,但要想真正完全掌握设计模式,不是看两篇文章就行的最重要的还是要多想,多实践。
更多面试问题请关注我的github
掌握面试——弹出框的实现相关推荐
- 4.下拉选择框,弹出框。滚动条,(frame切换、多窗口切换,很重要,常用)等等,面试重要
文章目录 target 下拉选择框 弹出框-- driver.switch_to.alert 滚动条 frame切换-- 重要 多窗口切换 截屏 验证码 cookie target 下拉选择框--se ...
- js的三种弹出框(alert、confirm、prompt)简单介绍
一.具体内容 1.alert() alert 方法有一个参数,就是用户想弹出的内容,弹出框很简单,就一个显示功能.你可以点击确认关闭这个弹出框. 例如:alert("hello wo ...
- php使用popover,php中bootstrap框架.popover弹出框,鼠标移动到上面自动显示,离开自动消失...
$(function(){//显示弹出框 $("[rel=name]").popover({ trigger:'manual', placement : 'bottom', //p ...
- android h5弹窗,Android嵌套html5页面中alert 弹出框问题
最近项目中遇到一个头疼的问题,那就是在安卓里嵌套html5的时候发现alert弹出框出现了问题 那就是弹出的时候会出现串 来自http://xxxxx 网页的提示 然后下面出来具体的弹出信息,还有更奇 ...
- IOS8中SWIFT 弹出框的显示
弹出框不管是在网页端,还是在手机APP端,都是常用的控件.在网页中实现个简单的弹出框只需要调用alert,在IOS中,也不是那么复杂,也是容易使用的. 我先用xcode6创建一个名为iOS8Swift ...
- QTP的那些事---页面弹出框的处理,页面等待加载的处理
处理方法:先判断父类对象是否存在,如果存在,判断相关的static文本对象是否存在,如果存在,则点击弹出框中的按钮即可: 例如如下的代码: 设置循环判断dialog对象是否存在,如果存在,就去点击相关 ...
- php ajax弹出框传值,PHP_Yii2.0 模态弹出框+ajax提交表单,如题 我们使用模态弹出框+ajax - phpStudy...
Yii2.0 模态弹出框+ajax提交表单 如题 我们使用模态弹出框+ajax提交表单 首先我们把index视图的create按钮添加data-toggle 和 data-target. 代码如下: ...
- Bootstrap方法为页面添加一个弹出框
<!DOCTYPE html> <html> <head><meta charset="utf-8"> <title>B ...
- 基于layer mobile手机端弹出框,询问框(PC端推荐layer和artDialog:http://download.csdn.net/download/cometwo/9437895)...
layer mobile是为移动设备(手机.平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选 ...
最新文章
- 卷积神经网络中用1*1 卷积有什么作用或者好处呢?
- Python 面向对象编程基础
- 代码单元测试工具:gmock
- class(一)--类的创建
- gitbook mysql_使用Gitbook做笔记
- linux 6.8 多网卡绑定,Linux6.1/6.5 双网卡绑定
- LoRa协议在Arduino上的应用——原理及代码分析(二)
- 《第一行代码》完结篇
- 实时渲染学习(六)延迟渲染(Deferred Rendering)
- 计算摄影——自动构图
- java is alphabetic_Unicode字符类\p{IsAlphabetic}
- 仪表研发工程师所需要了解的蓝牙和WiFi知识
- 企业实战之部署Solarwinds Network八部众
- python大游戏_Python开发【项目】:大型模拟战争游戏(外星人入侵)
- pandas - 时间天数计算-实现excel中IF(ROUNDDOWN(),,)函数
- hypixel服务器显示无法登录,我的世界hypixel服务器盗版可以登录?
- 关于 window.open() referer 非法请求的问题
- Cool Edit之生成.pk文件问题
- ssm基于jsp高校选课系统毕业设计源码291627
- 各国通货膨胀率(1961-2019年)