2019-7-29 牛客网 前端工程师 在线面试
1.如果要画一条0.5px的线,你会怎么去实现呢?讲讲你的方法。
像素<-------屏幕显示最小的单位
像素数量1920 * 1080(宽W有1920个像素,高H为1080个)<---------一个1080p的屏幕
像素实际上是一个面积的概念,因此像素本身有大小.
同样大小的屏幕,像素越小,需要的像素点就越多,像素就越密集.
1寸=1.31233596英寸
1英寸=25.4毫米
图像的采样率ppi--------在图像中,每英寸所包含的像素数目
打印分辨率dpi-----------每英寸所能打印的点数,即打印精度
图像的宽W(高H)像素数=打印宽W(高H)分辨率×打印的宽W(高H)尺寸
435pix = 435dpi/ppi * 1inch
15寸的分辨率为2880 x 1800,15寸是指屏幕的对角线为15寸(具体为15.4)实际按照宽高勾股比例计算,宽W为13寸,所以2880/13=220ppi,可见,同一大小屏幕,像素数越多,像素越密集,分辨率也高,屏幕越细腻越高清.
在Mac/Windows上可以设置屏幕显示的分辨率,Mac默认为设备分辨率的一半,它的dpr= 2,即宽和高用2个像素表示1个像素,所以2880个物理像素点实际上只表示1440个逻辑像素。
如果我们直接设置0.5px,在不同的浏览器会有不同的表现
<!DOCType html> <html> <head> <meta charset="utf-8"> <style> .hr { width: 300px; background-color: #000; } .hr.half-px { height: 0.5px; } .hr.one-px { height: 1px; } </style> </head> <body> <p>0.5px</p> <div class="hr half-px"></div> <p>1px</p> <div class="hr one-px"></div> </body> </html>
自己验证的如上图---------
几乎没什么不一样
Chrome把0.5px四舍五入变成了1px,把小于0.5px的当成0
firefox/safari能够画出0.5px的边,把不小于0.55px当成1px,Safari是把不小于0.75px当成1px
手机上观察IOS苹果的Chrome会画出0.5px的边,而安卓(5.0)原生浏览器是不行的
所以直接设置0.5px不同浏览器的差异比较大,并且我们看到不同系统的不同浏览器对小数点的px有不同的处理。所以如果我们把单位设置成小数的px包括宽高等,其实不太可靠,因为不同浏览器表现不一样.
<!DOCType html> <html> <head> <meta charset="utf-8"> <style> .hr { width: 300px; background-color: #000; } .hr.scale-half { height: 1px; transform: scaleY(0.5); } </style> </head> <body> <p>1px + scaleY(0.5)</p> <div class="hr scale-half"></div> </body> </html>
自己验证的如上图--------
IE浏览器中使用transform属性后,线不可见了
火狐几乎没什么变化
360浏览器线变虚了
Chrome/Safari都变虚了
Firefox比较完美看起来是实的而且还很细,效果和直接设置0.5px一样
所以通过transform: scale会导致Chrome变虚了,而粗细几乎没有变化
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
} .hr.scale-half { height: 1px; transform: scaleY(0.5); transform-origin: 50% 100%; } </style>
</head>
<body>
<p>1px + scaleY(0.5)</p> <div class="hr scale-half"></div>
</body>
</html>
自己验证如上图------
IE因添加了transform属性,线不可见,3当不添加transform属性,线可见,再添加transform-origin属性,线可见几乎无变化.
360浏览器,线变实了,
火狐因添加了transform-origin属性,线不可见了,但是transform-origin和transform二选一则线变可见.
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
} .hr.gradient { height: 1px; background: linear-gradient(0deg, #fff, #000); } </style>
</head>
<body>
<p>linear-gradient(0deg, #fff, #000)</p> <div class="hr gradient"></div>
</body>
</html>
自己验证如上图------
除了虚实效果,大概看不出什么不同
inear-gradient(0deg, #fff, #000):渐变的角度从下往上,从白色#fff渐变到黑色#000,而且是线性的,在高清屏上,1px的逻辑像素代表的物理(设备)像素有2px,由于是线性渐变,所以第1个px只能是#fff,而剩下的那个像素只能是#000,这样就达到了画一半的目的
<!DOCType html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-sacle=0.5"> <style> .hr { width: 300px; background-color: #000; } .hr.boxshadow { height: 1px; background: none; box-shadow: 0 0.5px 0 #000; } </style> </head> <body> <p>box-shadow: 0 0.5px 0 #000</p> <div class="hr boxshadow"></div> </body> </html>
自己验证如上图-------
几乎一样
width=device-width表示将viewport视窗的宽度调整为设备的宽度,这个宽度通常是指物理上宽度。默认的缩放比例为1时,如iphone 6竖屏的宽度为750px,它的dpr=2,用2px表示1px,这样设置之后viewport的宽度就变成375px。但是我们可以改成0.5,viewport的宽度就是原本的750px,所以1个px还是1px,正常画就行,但这样也意味着UI需要按2倍图的出,整体面面的单位都会放大一倍
2.请讲一下对于前端中的事件流,你是怎么理解的
事件流--------描述的是从页面中接受事件,事件发生的顺序,自下而上(由具体节点到不具体节点)---事件捕获流/自上而下(由不具体节点到具有节点)----事件冒泡流
IE提出的是“事件冒泡流”
Netscape提出的是“事件捕获流”
事件冒泡流:从下而上的过程,由具体节点到不具体节点,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档)
事件捕获流:与冒泡流截然相反,从上而下的过程,由不具体节点到具体节点,它的定义是最不具体的节点应该更早接收到事件,而最具体的节点最后接收到事件
Netscape提出的是“事件捕获流”
事件冒泡流:从下而上的过程,由具体节点到不具体节点,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档)
事件捕获流:与冒泡流截然相反,从上而下的过程,由不具体节点到具体节点,它的定义是最不具体的节点应该更早接收到事件,而最具体的节点最后接收到事件
<html> <head> <tltle>事件流</title> <meta charset="UTF-8" > </head> <body> <div> <input type="button" value="按钮" id="btn"> </div> </body>
用户点击按钮,浏览器就会认为你点击按钮的同时也点击了div,认为你点击了div就会认为你也点击了body,一直往上,会认为你点击了document.也就是说你点击了按钮,浏览器会一级一级往上冒,认为你点击了整个document
如button和button的父元素都添加了click事件,当点击button的时候,button和其父元素的点击事件都会执行,自下而上的顺序执行。这个事件需要阻止冒泡事件。
解决方法:
$('button').click(function(e){ //可以是任何需要阻止冒泡的元素。
e.stopPropagation();
//ie
e.cancelBubble = true;
})
解决方法:
$('button').click(function(e){ //可以是任何需要阻止冒泡的元素。
e.stopPropagation();
//ie
e.cancelBubble = true;
})
一些不支持冒泡的事件:
blur:元素失去焦点时触发,不支持冒泡。
focus: 元素获得焦点时触发,不支持冒泡。
mouseenter:鼠标移入元素触发,不支持冒泡。
mouseleave:鼠标移出元素时触发,不支持冒泡。
3.给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
此问题包含两个步骤:
(1)判断链表中是否有环
(2)找出环
(1)判断链表中是否有环
(2)找出环
如何判断链表是否有环?
设置两个指针,开始都指向链表头,然后其中一个指针每次向前走一步,另一个指针每次向前走两步,如果快的遇到NULL了,证明该链表中没有环,如果有环,快的指针每次都要比慢的多走一步,最终两个指针会相遇,(注意:这里快指针不会跳过慢指针而不相遇,因为它每次都只比慢指针多走一个单位)
/*function ListNode(x){ this.val = x; this.next = null; }*/ function EntryNodeOfLoop(pHead) { // write code here // 使用两个指针,一个快的,一个慢的,快的时慢的两倍,如果有环,那么他么一定会相遇。 if (pHead == null || pHead.next == null) { return null; } var p1 = pHead; var p2 = pHead; while (p2 != null && p2.next != null) { p1 = p1.next; p2 = p2.next.next; if (p1 == p2) { p2 = pHead; while (p1 != p2) { p1 = p1.next; p2 = p2.next; } if (p1 == p2) { return p1; } } } return null; } module.exports = { EntryNodeOfLoop : EntryNodeOfLoop };