本文背景
作为一个Web前端从业者,资深B/S架构的应用开发,通常我们负责的内容都是侧重的浏览器端比较多,即便目前Vue、React等各种框架库流行的年代,核心实现也依然是JS API操作DOM;如果资历更深一些的同学,还会熟知jQuery,更是因为各浏览器API不统一作为其解决的问题痛点。
在长期担任Web前端面试官的过程中,我归纳沉淀了一些有趣的面试题目,今天来聊其中一个与DOM操作相关的题,可以用于考察一个前端工程师的逻辑条理性、问题分析解决能力、纯Web前端(浏览器端)JS技术基础情况等。
面试原题描述
如图,红色矩形是网页中的一个DOM元素(比如是个普通DIV)。
需求:当用户鼠标在该DOM元素上移动时,判定光标相对于灰色对角线所处位置状态(左上、右下、刚好在线上)。
粗略解答思路
相信你一定已经看懂是个啥需求,需要做些啥了吧?
所以不需要赘述了,直接上解法:!!!
首先,我们需要确定判定方法,以及需要传入的参数。
然后,再通过DOM行为监听、事件&DOM属性读取,得到参数具体数值,传入上面实现的方法。
很简单对不对?让我想到了经典的“怎么画好一匹马”。
别急,具体处理方式容我再慢慢道来。
一点面试的心得感受
被我面试时聊过这个问题的人,不上几千肯定也过几百了。
所以,技术问题之外,也会有一些心得感悟。
比如我经常对新参加面试工作的同事说的一句话:“切记:面试不是拿你自己准备好的、或者熟悉的问题,创造出一个不公平的沟通场景,然后再跟被面试者比谁更聪明;面试官的职责是通过针对特定话题的沟通,来检验其过往经历的真实性、判定这个人特定方向的能力边界。”
如果一个被面试者,第一次遇到这个非纯知识考查的怪异问题,还能做到冷静思考、清晰表述思路,那么我们完全可以判定这个人的基本素质:临场应变、抽象变通都不错。
如果接下来还能提供代码实现过程的表述,那更是这个方向上,问题分析解决能力、编程经验丰富了。
能达到上述表现的,对心理抗压、临场应变、相关技能储备是个不小的挑战,往往是凤毛麟角。
而在我面试他人的经历中,还有两种非常有趣的极端情况会经常遇到:
- 看完不假思索、或稍微思考一会,直接选择放弃的。
- 缺乏思考或没有清晰的思路,强拉硬扯一通,然后提供一些牵强附会的结论。
当我作为面试官遇到上述极端情形时的感受往往是:
- 是不是没太大必要继续浪费时间了。
- 这个同学任用可一定得慎重。
当然,感受归感受,现实里面我并不会这么武断的定下结论。此时需要再回顾一下前文加粗的那点感想。
如果一个人的临场应变能力不是非常优秀,也不一定就是能力问题。
谁也难免会有紧张、脑筋卡壳的时候。我自己就经常这样啊 ----- 往往晚上睡觉时趟在床上,回想一天的过往,“嘿,我那个想法、那句话,简直就是SB至极”。
所以遇到上述两种极端情况,换到应聘者角色又或者是这样呢:
- 问我这些?简直是羞辱,我不屑回答。
- 怎么办,怎么办,好紧张,可我不能不要面子啊:“巴拉巴拉巴拉...”
所以如果我作为面试官遇到不太能给出思路的同学,会试图引导一下,强调“面试不一定非得纯问答题,也是个相互沟通、相互学习的过程,想到啥都可以说说看”。
而作为面试官通过进一步沟通,也可以更可靠、清晰的确认一下对被面试者能力范围的判定。
学霸式解题方法思路
如果面试中遇到数学基础不错的学霸,往往会直接甩出向量
方案。
像下图三种状态代表性的点 P1
、P2
、P3
,求其点坐标到对角线的向量值,根据正、负、零自然也就映射到要判定的状态了。
但是,像我这种连“向量:具有大小和方向的量
”的基础概念都忘光光的学渣,肯定不会啊。
所以引导他人解题时候,更是不敢聊向量
这个话题了,我经常用逻辑推理的方式。
逻辑推理式解题思路之一
毕竟是引导别人,我也要面子嘛:通常会先建议再想一想、确定一下参照坐标系、画一画辅助线试试。
比如,我们假设任意光标点为P1
,DOM元素左下角为二维坐标系原点P0
呢?有没有想到啥思路?
还没有思路的话,将P1-P0
连线呢?跟对角线比较是啥关系,能不能映射到题目需求状态上?
对嘛,斜线P0-P1
与底边的夹角如果大于、等于、小于对角线与底边或左边的夹角,不就判定出来了。
不过要计算角的大小好像也会很麻烦(我三角函数都忘光光了,太难了、不会啊)....
其实,刚刚我们已经不知不解决的假定了底边是x轴、左边是y轴(原点P0
嚒 ლ(′◉❥◉`ლ)),也就形成了一个二维坐标系。
在这个坐标系里,P1
到左边的距离X、到底边的距离Y,跟矩形宽度boxWidth、boxHeight的比例关系刚好也可以映射到题目需求的三个位置状态上诶!!
即:
X/Y === boxWidth/boxHeight
那么点在对角线上。X/Y < boxWidth/boxHeight
那么点在对角线左上。X/Y > boxWidth/boxHeight
那么点在对角线右下。
到这里判定方法确定了,剩下就是怎么去获取这些参数值了。
必要参数值获取
现在我们需要获取4个数值:X、Y、boxWidth、boxHeight。
我就知道,你一定会觉得很简单,没错,这是算是基本JS API基础了。
事件处理及对应值获取
回到题目“当用户鼠标在该DOM元素上移动时”,不就是监听鼠标事件、然后取相关对象的目标属性值么,这有啥难点?
我也一直这么认为的,但经过那么多次面试,发现竟然很多人都不知道(╮(╯▽╰)╭),能通过筛选的怎么也是有几年前端工作经验的呢。
遇到过:“不知道”、 “onMouseover
”、“onTouch
”、“o(╯□╰)o”...
确定了事件监听方式,那么我们通过事件中的哪个对象啥属性获取X、Y呢?
曾经收到过的答案们(只拿X值关联属性示例):不知道、div.x、event.x、evnet.left、event.offsetX、event.clientX、event.pageX、... ???
上面这些肯定有错误的或者存在问题的,聪明的你,一定想到了正确的方案了。
你拿到的值是相对哪个坐标系的?如果得到的是 pageX值,是不是还得换算一下,又进一步依赖哪个属性怎么获取?
DOM属性读取
X、Y坐标值能取到了,那么boxWidth、boxHeight怎么取呢?
曾经收到的答案们(只拿宽度值关联属性示例):不知道、div.width、div.style.width、div.contentWidth、div.getAttribute('xxx')、div.offsetWidth、div.outerWidth、div.innerWidth、div.getBoundingClientRect().width....
上面这些还是存在错误的,聪明的你,又一定想到了正确的方案了。~O(∩_∩)O~
延展讨论
“既然聊到事件了,如果我页面里有好多元素,还存在懒加载动态插入的,都想达成这个题目的需求,事件绑定有没有一次绑定也都能生效的方案嘞?”、“是不是有个啥事件委托、事件代理?”
“事件可以自定义么?"
"如果我在JS代码里悄悄的自动触发一个元素的事件可以么,会不会有啥问题?”
“诶,上面你好像聊到了 div.style.width、div.offsetWidth,这俩货有啥区别啊?”、“浏览器里是不是有个盒模型的说法?”
“如果鼠标移动频度很高,会不会有性能问题?”、“可以怎么优化一下吗?”。
“如果要在DOM元素里绘制这个斜对角线,该怎么画?”
"你刚说用两个DOM元素分别实现上下三角区域,再绑定onClick判断?" “那这俩三角区域CSS咋写出来?”
收个尾
今天先想到啥写啥了,回头再想到啥再补充。
可能有同学会非常纳闷,“怎么会有这么个题目,前端工程师怎么可能用到?”。
首先这个问题,来自我11年前的一个真实项目经历中的产品需求:
如上图:“当某个WEB应用启用精简排版模式时,将第二行中俩功能按钮合并成第一行的那一个,按照点击位置判定并执行为独立按钮一样的目标行为。”
再后来,稍微了解了一点计算机图形学三角剖分法、纹理贴片,我勒个乖乖,全是三角形,太吓人了,果断放弃。
レ(゚∀゚;)ヘ=3=3=3
Comments
可以发邮件 huzunjie@pyzy.net 或移步到 https://github.com/huzunjie/blog.pyzy.net/issues 评论交流。