辑导语:在上下滚动页面时,除了出现吸顶,还会出现吸底、锚点等情况,那么这些都是在滚动页面时需要注意的控件。本文作者结合最近工作中的实际项目,对于滑动时的吸顶、锚点规则方式的总结心得,一起来学习下吧。
上下滚动页面时,除了出现吸顶,还会出现吸底、锚点等情况,这些都是在滚动页面时需要注意的控件。
结合最近工作中的实际项目,Cassie将滑动用到的场景进行了提炼,总结出这份控件设计规范,一起来学习吸底、锚点是如何在APP以及PC端应用的吧~
PC端及移动端的底部有一些操作栏,比如表单的填写操作或者支付按钮的放置,移动端底部还会有全局的导航栏,这些会占用一定的空间,可以根据使用场景灵活选择吸底方式。
需要注意吸底的是具有操作价值的内容,吸底元素包括操作按钮、 引导操作、移动端的导航栏…
PC端在表单内容较多、查看内容文章、需要引导用户操作比如支付等场景下,当用户需滑动查看更多内容,可将操作类按钮吸底,需要吸底的内容可以根据布局调整显示。
在左图PC端钉钉邮箱中,属于编辑表单类的,将发送操作按钮固定吸底,用户只需要修改部分字段,更利于快速完成编辑;在PC端简书中,属于内容展示类的,出于增强互动的目的,将评论、点赞等操作固定在底部增加其操作便捷性。
考试星PC端采用左中右布局,将提交考试放在右侧底部,可以不占用考试内容高度空间;百度学术PC端采用左右布局,右侧是一些介绍内容,所以操作按钮固定在和之有直接关系的左侧内容底部。
移动端底部常会有一些吸底的控件,比如底部导航栏、主操作按钮、需要引导或便捷用户操作的控件等。
一级页面导航固定在底部,当该页面有主按钮,比如结算等则将该栏放到导航栏上面,如果还有引导类或便捷操作类控件则再放到主操作栏上面。
移动端,特别是购物车场景存在多条吸底内容。
具有引导性的操作,为了配合主操作而出现,也是固定在底部,但位于底部操作上面,在特定场景下出现。
比如闲鱼提供了一些常用问题,可以跟卖家交流更便捷;考拉海购购物车的优惠引导也是固定在底部,类似的还有京东、淘宝等购物车。
当PC端展示内容分多段,且其中有需要引导用户操作的按钮,建议在滚动到该段时将该操作按钮吸底,滚动到另外一段内容后再取消吸底。
考拉海购PC端的购物车页面,如果购物车内容比较多,支付栏是吸底的,向上滚动到购物车商品内容结束后,支付栏不吸底,下面展示推荐商品。
京东官网的购物车也是这种方式,但移动端主流购物车的支付都是固定在底部的。
吸底内容可以根据具体情况显示或隐藏,这种非固定的方式常用于移动端阅读及查看话题评论时。
在微信读书的阅读状态时,为了给读者提供沉浸式体验,隐藏操作栏,上滑时再显示;在知乎热榜浏览主题内容时,主操作栏跟在内容下面,当页面滑动后主操作栏改变布局样式吸底展示。
锚点以回到顶部也属于页面滚动时需要的控件,配合滚动条用于跳转到页面指定位置。
PC端和移动端都可以在内容过多时使用回到顶部控件,PC端的锚点定位类似导航一样可以放到页面左侧或者右侧,但其实只是页面的内容定位。
移动端可以利用滚动条做时间轴类型的定位或者分页定位。
当PC端页面内容区域比较长时比如瀑布流的使用,用户需要频繁返回顶部查看相关内容时,可以滚动后出现回到顶部控件。
花瓣PC端页面滚动后,右下角有一些功能操作,滚动后出现回到顶部控件。
当页面内容区域比较长时;当用户需要频繁返回顶部查看相关内容时,可以使用回到顶端返回页面顶部。
如果当前页面是主页,可以滚动后主页按钮便成回到顶部按钮,这样可以避免遮挡内容,优化阅读体验。
京东购物车页面除了展示添加到购物车的商品外,底部还有推荐上面,滚动后出现回到顶部控件;每日优鲜APP页面滚动后,导航的主页按钮变成回到顶部按钮,优化体验,类似的还有淘宝、饿了么、考拉等主页有瀑布流的内容。
当PC端有多条组合内容时,可以左侧做一个锚点定位配合滚动条快速定位到页面需要查看的内容。
当PC端使用上下布局时,且内容区域居中固定时,锚点悬浮在左侧显示,当屏幕小于一定尺寸时,锚点缩小悬浮于页面左侧,鼠标移入时再显示。
在优设的网址导航中,由于导航分为多个类型,所以将具体类型名称放到左侧展示,能快速定位到需要的内容。
当PC端左侧有导航,锚点定位可以放到右侧,常用于阅读文章等场景。
在Ant design的组件页,由于左侧有二级导航,所以将页面的锚点定位放在右侧,类似的还有语雀文章阅读。
当有时间类型的内容比如浏览照片时,可以采取时间轴定位的方式快速滑动到需要查看的内容。
内容过多的情况下也可以采取分页的形式,滚动后将分页及回到顶部固定在底部右下角位置。
例如宝宝树APP采用时间轴的方式快速定位,默认状态定位控件缩小固定在右侧,滑动时控件变大显示具体时间,方便用户按时间快速查找照片,类似的还有百度网盘里的照片浏览。
豆瓣APP在电影的讨论模块,选择一个讨论查看详情滚动后底部显示回复的定位锚点,控件放在操作栏上面吸底展示。
作者: Cassie
原文链接:www.zcool.com.cn/article/ZMTM0ODkzMg==.html
本文由 @ Cassie 授权发布于人人都是产品经理,未经作者许可,禁止转载。
题图来自Unsplash,基于CC0协议。
窗的类型有非常多种,所以在使用时很容易被滥用,这样不仅会对用户带来困扰,也会让我们的设计中出现细枝末节的问题。本篇文章分析和总结了不同弹窗的使用场景及工作中的实际应用,知道这些后,以后再也不会“滥用”弹窗啦!
我们口中常说的弹窗其实是个广义的范围,包括了对话框,动作菜单,浮出层,toast,snackbar等,这么多类型的弹窗在使用中很容易混乱或者说滥用,反而得不偿失,给用户带来更多困扰。故本篇文章主要分析和总结不同弹窗的使用场景及工作中的实际应用。
官方的设计样式会提到,但是细节不展开,有需要的可以参阅MD官方文档和苹果HIG官方文档,文档里介绍的都很细致。
除了官方文档,本文还参阅了很多前辈的总结分析,参考链接已置于文末。(配图主要来自体验过程中的app截图,安卓部分截图主要来自MD规范)
在App使用中,弹窗出现的频率越来越高,运营活动,系统通知,信息反馈,任务引导等。滥用的弹窗会渐渐导致用户认知疲劳和视觉失调,甚至会出现“习惯性取消”等行为。
弹窗最主要的功能就是服务于当前主任务之外的支线任务,包括信息传递,操作反馈等。
对话框,警告框,toast……都属于弹窗,但是使用场景都不一样。
在合适的业务场景选择合适的弹窗组件,能够保证最基础的用户体验。因为像强干扰类弹窗的使用,对用户而言,更是一种强加的任务,很容易导致用户丧失耐心而流失。
弹窗可以按照是否强制打断用户操作来分成两种,模态弹窗和非模态弹窗(也可以叫做阻断式弹窗和非阻断式弹窗)。
模态弹窗:模态提供了一个专注聚焦的环境,用户只有完成或者关闭当前任务,才能进行其他任务。
特点:打断用户当前的操作流程,属于强势的干扰行为,故运用弹窗需要慎重考虑。
常用组件:dialog(对话框)/alert(警告框)、popover(浮出层)、action sheet(动作菜单)、activity views(活动视图)、modal bottom sheet(模态底部菜单)。
非模态弹窗:常用于轻量级的操作反馈和信息传递,不需要获取屏幕焦点,用户可以同时操作屏幕中的其他内容。
特点:属于轻量级的反馈,不会对用户流程产生干扰,但同时又给了用户反馈和信息。
常用组件:Toast(吐司),snackbar,Hud(透明指示层)。
dialog和alert分别是MD和ios的官方弹出框,是最常见的弹窗,两者功能一样,在使用上以及样式上略有区别(下文分析统一称为弹出框)。
弹出框通常用来传达和app及设备相关的重要信息,并且要求用户操作或反馈,且其出现在屏幕中央,对内容遮挡严重,会中断用户正常操作。用户只有完成或者关闭当前任务,才能进行其他任务。
其官方样式如下:
4.1.1 使用场景
通知用户app或设备相关的问题:
通过强干扰通知用户设备相关问题如备份,低电量等问题;这些潜在问题可能会对用户造成一定负面的影响。
再比如app的版本更新,消息通知,首饰引导等都关系到用户的利益,所以也会用强干扰的方式让用户明确知道并选择。
辅助用户完成任务,如系统权限:
用户在进行任务的过程中,受到阻拦,必须通过其他辅助操作帮助他完成任务。
如完成一些任务必须要开启相应的系统权限:上传照片要开启相册权限;拍小视频要麦克风权限;出行外卖等产品要开启定位权限;新建相册必须要为相册命名;下载app要登录itunes账号。
用户主动中断任务,破坏性操作等:
用户中断当前任务,对之前的操作有一定的影响,或者一些无法挽回的破坏性操作,故需强干扰的弹窗通知,避免用户因为失误有了不可挽回的损失。如退出账号;删除订单,活动消息等;放弃编辑。
操作反馈:
当操作后的反馈比较重要,会影响用户接下来的操作或会影响当下的任务,那就需要用强干扰让用户明确知道,要完成此操作需要什么,或者接下来会发生什么。
例如西瓜视频的结算通过强干扰通知到用户想要结算应该怎么做。
运营活动:
现在用弹出框来传递运营活动已经成为一个约定俗成的用法了,虽然ios规范中建议尽量少用弹出框,但公司还是要盈利的,所以基本上所有app都会以这种强干扰的形式来通知用户“这里有优惠活动”等运营活动。
这种场景下,弹出框会根据产品以及业务的运营需求及产品的调性做丰富的运营设计,来吸引用户参加运营活动,需要注意的一点,需要用户参加的buttom一定要加强,突出。
功能引导:
功能引导和运营活动一样,是产品出于业务角度考虑,用强干扰的方式吸引用户使用某功能,达到一定的业务目标,如用户活跃度。
例如完成订单后(外卖或商品)引导用户评价,并给予一定奖励。如将流量引流到新业务,从而达到新业务推广目的。
浮出层是ios的组件,是用户点击屏幕上的某个控件或区域出现在屏幕上方的临时视图,它最典型的是包含一个指向它出现位置的箭头,且浮出层一般在入口下方,整个浮出层应该位于整个屏幕的中上方。
浮出层最开始主要用于大屏幕的ipad,但由于手机屏幕越来越大,目前也被较多地运用到手机界面中。
4.2.1 使用场景
多个常用操作的快捷入口:
多个常用操作通过popover折叠起来,视觉上更清爽简洁,同时使用起来也方便,缺点是用户不能直观看到,需要一定的学习才能掌握,所以适合于有学习能力用户群的产品
呈现页面中一些折叠的信息:
属于浮出层的衍生应用,和上个场景一样,节约屏幕空间,显露出一部分,并将剩余信息折叠起来,不影响用户理解功能,又解决了屏幕空间,若用户有需求,即可展开探索更多的信息,同样也会用箭头等指向出处
对于新用户的功能引导或者新功能的引导:
此类场景也属于浮出层的衍生应用,主要通过带指向箭头的浮层引导用户学习某个功能,一般需要学习的功能是高亮的,且箭头指向它。
actionsheet是ios系统中特定的警告框,用来响应动作或控件,或者呈现和当前内容相关的两个及更多的选项。一般在屏幕底部。官方不建议在动作菜单中应用滚动条,所以动作菜单中的选项不能过多。
4.3.1 使用场景
当前对象的多个操作或者完成任务的多个选择:
对当前对象的的多个操作,如qq中对图片长按,出现多个对该图片可进行的操作,帮助完成任务。除了文字列表外,还可以用图标+宫格式的展示方式,例如分享功能的多个选项。
执行潜在的破坏性操作前的二次确认:
当执行潜在的破坏性操作前需再做提醒,避免产生不可挽回的失误。需注意的是破坏性操作的按钮需重点突出,一般用红色,起到警示,危险的提醒作用
和alert的区别:
alert主要适用于两个选项,而actionsheet可以有多个功能选项,且展示形式更多样。前文讲过,alert也有破坏性操作提醒的场景使用。
两者相比,alert出现在屏幕中央,actionsheet出现在屏幕底部。视觉角度上alert相较于actionsheet更有阻断感,对用户而言干扰性更大。
另一方面底部的actionsheet从手势操作的角度上来看,操作更方便,更容易对此作出选择或关闭。所以alert更加适用于严重后果的破坏性操作提醒。
活动视图是ios组件,是针对当前页面提供的一系列任务和服务,例如复制,收藏,查找等。系统提供了许多内置活动,包括打印,信息和AirPlay。
这些任务始终首先出现在活动视图中,无法重新排序。无需创建执行这些内置任务的自定义活动。活动视图还显示来自其他应用的共享和操作扩展。
Bottom sheet是MD的组件,MD中底部菜单有两种,一种是Standard bottom sheet(标准底部菜单),另一种是Modal bottom sheet(模态底部菜单)。
MD的模态底部菜单和iOS的action sheet类似,它阻止用户与屏幕其他地方交互,通过聚焦的底部菜单提供了更多的选项和功能。它可以是内联菜单和简单对话框的替代方案,为内容,图标和动作提供了额外的空间。
规范建议,模态底部淡淡的初始垂直位置的上限为屏幕高度的50%。内容超过屏幕高度50%的模态菜单可以在整个屏幕上拉动,在内部滚动以访问其余项目。同样他的展现方式有列表式,也可有宫格式
snackbar是android专有控件,是出现在屏幕底部的提供有关app相关的简短信息提醒,它属于轻量级的信息提醒,一般出现几秒后就会自动消失,不会中断用户操作。
snackbar往往由一条文案+一个引导性按钮(可选,按钮可以引导用户进一步操作)组成,带有一定的交互性。因为它自动会消失,所以它一定没有取消或者不要等否定性按钮。
4.6.1 使用场景
传达轻量级的信息和操作反馈,可以引导用户操作:
传达轻量级的信息或反馈,并且可以引导用户进行下一步行为,但并不强制用户操作。比如chrome添加书签时,可以进一步对新加的书签进行编辑;删除书签时防止用户后悔,提供一个撤销按钮。
Toast是android专有的控件,原先的MD规范中,toast是和snackbar放在一起讲的,翻阅了最新的MD规范,snackbar里找不到关于toast的相关介绍(有小伙伴找到的望提醒一下)。
Toast应该包含在snackbar里了,当snackbar没有按钮其实就是toast了,不过这边还是把Toast单独拿出来分析
4.7.1 使用场景
传达轻量级的信息和操作反馈,且不需要用户操作:
适用于通知用户不重要的信息和操作反馈,且不会对用户当前的任务有影响,因为不能交互,且几秒后消失,所以用户很可能忽略,所以该类信息相对而言没那么重要。
虽然toast是android专有样式,但现在很多ios版本的系统中都使用了改良版的“toast”,因为轻反馈,不打断用户操作,同时又能通知信息和操作反馈,对用户而言及其友好,但是不易传达过多的文字,因为用户很有可能会忽略。
ios文档中的feedback中有建议:反馈可以帮助人们了解应用正在做什么,发现他们下一步可以做什么,并了解行动的结果。所以实际应用中,既要不打扰用户,又要能引起用户注意,还要和产品设计相协调。
比如结合了文字和icon的样式,再比如用较为突出的背景色,位置的话在中央,顶部,底部,都会出现,会根据具体的业务来选择合适的位置。一般出现的位置会和操作内容在一起,这样用户才能清晰有效地得到即时反馈。
下方例举的toast案例因为选用了比内容更为突出的背景色,相比较上方案例的toast更易被用户发现和察觉,达到通知用户的目的。
Hud透明指示层,ios专用控件,典型的就是音量调节的弹窗样式。部分改良的toast,在样式上有借鉴学习Hud。
Dialog/Alert:
当信息或操作非常重要,并且必须要由用户做决定或者操作才能继续,一般用alert,更适用于用户判断选择。
Modal bottom sheet/Action sheet:
稍弱于dialog/alert,更着重于提供更多的功能和选项时使用。
Activity view:
是针对当前页面提供的一系列额外的任务和服务。
Popover:
使用更侧重于指向性,更适用于信息或功能折叠。
Toast:
不太重要的信息提醒和操作反馈,更适用于不需用户响应或反馈的场景。
snackbar:
不太重要的信息提醒和操作反馈,可以交互,但并不强制,更适用于可以引导用户进行下一步或者一些撤销上一步的场景。
Hud:
音量调节。
了解了每个弹窗组件的用法,下次就可以根据实际业务设计合适的弹窗了,不过官方规范或者文章的建议也都只是参考,实际工作中还是要灵活变通,设计的目标是帮助用户更好更快的解决问题。
以上就是我对弹窗相关知识的总结,总结的过程中也对官方规范弹窗部分的内容再次熟悉了好几遍,因为看的英文,所以理解上可能稍微有些不足,有不对的地方,还希望大家批评指正。(推荐大家多看看官方设计规范,就像一本非常实用的设计工具书,对于实际工作还是非常有帮助的)
再次感谢前辈的经验分享!
这个控件叫什么系列之toast的曾经,现在,与未来 https://www.uisdc.com/ui-element-toast
如何设计App中的提示控件(toast) https://zhuanlan.zhihu.com/p/22405748
iOS和Android规范解析——底部浮层(上)https://www.jianshu.com/p/8bdfbc0a9339
iOS和Android规范解析——提示框(Toast)对比 https://www.jianshu.com/p/e1beeacbea32
不要滥用对话框!细说 iOS Alert View 与 Action Sheet https://zhuanlan.zhihu.com/p/20189186
App设计中,6组常见组件的区别和用法 http://www.woshipm.com/pd/873075.html
APP提示框架详解:Toast提示、Snackers和Alert http://www.woshipm.com/pmd/296674.html
本文由 @麦子_Maizi 原创发布于人人都是产品经理。未经许可,禁止转载
题图来自Unsplash,基于CC0协议
最近收到很多同行的抱怨,前端开发高级还行,对初中级最难过的不是面试过不去,而是“已读不回”,来自某聘的梗,确实是,初中级因为坑位较少,很多HR在专心招聘的时候都未必能让所有投简历都去面试,更别说还有刷业绩现象,还是那几个点:
1.学历要注意,在外的个人名片,企业对比哈工和清华这即使不看面试也对清华有好感了吧!
2.项目经历,强调很多遍了,简介的形容你在项目中的作用,负责,以及运行,突出重点,
3.简历的简洁,要学会用最短的语句体现最大的价值,没用的写上写上也用处不大,
4.工作经历,跳的多自己掂量,跳的少,空窗期少,包装,这些要注意
5.面试经过,八股面试题,刷就完了,尽量做到说话不急也不慢,吐字清晰,磕磕绊绊毫无条理,再来个不确定,你是在被面试,不是提问面试官的
6.衣着,不要紧张,如果紧张可以多约几个,把重要的排在最后,
大多情况下,简历方面的问题居多,对标大厂的话项目经历,工作经验、还有学历要求居多,对简历和面试题可以【点击此处】,解决还是很简单的!
第 1 题:写 React / Vue 项目时为什么要在列表组件中写 key, 其作用是什么?
key 是给每一个 vnode 的唯一 id,可以依靠 key,更准确,更快的拿到 oldVnode 中对 应的 vnode 节点
第 2 题:['1', '2', '3'].map(parseInt) what & why ?
第一眼看到这个题目的时候,脑海跳出的答案是 [1, 2, 3],但是真正的答案是[1, NaN, NaN]。
首先让我们回顾一下,map 函数的第一个参数 callback。这个 callback 一共可以接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该元素的索引。
arr.map(callback: (value: T, index: number, array: T[])=> U, thisArg?: any);
而 parseInt 则是用来解析字符串的,使字符串成为指定基数的整数。接收两个参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数。
parseInt(string, radix)
了解这两个函数后,我们可以模拟一下运行情况
parseInt('1', 0) //radix 为 0 时,且 string 参数不以“0x”和“0”开头时, 按照 10 为基数处理。这个时候返回 1parseInt('2', 1) //基数为 1(1 进制)表示的数中,最大值小于 2,所以无法解析,返回 NaNparseInt('3', 2) //基数为 2(2 进制)表示的数中,最大值小于 3,所以无法解析,返回 NaN
第 3 题:什么是防抖和节流?有什么区别?如何实现?
防抖——触发高频事件后 n 秒后函数只会执行一次,如果 n 秒内高频事件再 次被触发,则重新计算时间;
function debounce(fn) {
let timeout=null
// 创建一个标记用来存放定时器的返回值
return function() {
clearTimeout(timeout)
// 每当用户输入的时候把前一个 setTimeout clear 掉
timeout=setTimeout(()=> {
// 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
fn.apply(this, arguments)
}, 500)
}}function sayHi() {
console.log('防抖成功')}var inp=
document.getElementById('inp')inp.addEventListener('input',
debounce(sayHi)) // 防抖
节流——高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。
function throttle(fn) {
let canRun=true // 通过闭包保存一个标记
return function() {
if (!canRun) return
// 在函数开头判断标记是否为 true,不为 true 则 return
canRun=false // 立即设置为 false
setTimeout(()=> {
// 将外部传入的函数的执行放在 setTimeout 中
fn.apply(this, arguments)
// 最后在 setTimeout 执行完毕后再把标记设置为 true(关键) 表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false,在开头被 return 掉
canRun=true
}, 500)
}}function sayHi(e) {
console.log(e.target.innerWidth,
e.target.innerHeight)}window.addEventListener('resize',
throttle(sayHi))
第 4 题:介绍下 Set、Map、WeakSet 和 WeakMap 的区别?
Set——对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用 WeakSet——成员都是对象;成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏;
Map——本质上是键值对的集合,类似集合;可以遍历,方法很多,可以跟各种数据格式转换。
WeakMap——只接受对象最为键名(null 除外),不接受其他类型的值作为键名;键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的;不能遍历,方法有 get、set、has、delete。
第 7 题:ES5/ES6 的继承除了写法以外还有什么区别?
let
-1)}let isTypeOf
map[type]
}
=1.
ES5 的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到 this 上(Parent.apply(this)).
2. ES6 的继承机制完全不同,实质上是先创建父类的实例对象 this(所以必须先调用父类的 super()方法),然后再用子类的构造函数修改 this。
3. ES5 的继承时通过原型或构造函数机制来实现。
4. ES6 通过 class 关键字定义类,里面有构造方法,类之间通过 extends 关键字实现继承。
5. 子类必须在 constructor 方法中调用 super 方法,否则新建实例报错。因为子类没有自己的 this 对象,而是继承了父类的 this 对象,然后对其进行加工。
如果不调用 super 方法,子类得不到 this 对象。
6. 注意 super 关键字指代父类的实例,即父类的 this 对象。
7. 注意:在子类构造函数中,调用 super 后,才可使用 this 关键字,否则报错。
第 11 题:算法手写题
已知如下数组,编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
var arr=[ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
答:使用 Set 方法去重,flat(Infinity)扁平化
Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
第 12 题:JS 异步解决方案的发展历程以及优缺点。
1、回调函数(callback)
优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。)
缺点:回调地狱,不能用 try catch 捕获错误,不能 return
2、Promise
优点:解决了回调地狱的问题
缺点:无法取消 Promise ,错误需要通过回调函数来捕获
3、Generator
特点:可以控制函数的执行,可以配合 co 函数库使用
4、Async/await
优点:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题
缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。
第 13 题:Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?
const promise=new Promise((resolve, reject)=> {
console.log(1)
resolve()
console.log(2)})promise.then(()=> {
console.log(3)})console.log(4)
执行结果是:1243,promise 构造函数是同步执行的,then 方法是异步执行的
第 15 题:简单讲解一下 http2 的多路复用
HTTP2 采用二进制格式传输,取代了 HTTP1.x 的文本格式,二进制格式解析更高效。
多路复用代替了 HTTP1.x 的序列和阻塞机制,所有的相同域名请求都通过同一个 TCP 连接并发完成。
在 HTTP1.x 中,并发多个请求需要多个 TCP 连接,浏览器为了控制资源会有 6-8个 TCP 连接都限制。HTTP2 中
同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。
单个连接上可以并行交错的请求和响应,之间互不干扰
第 17 题:A、B 机器正常连接后,B 机器突然重启,问 A 此时处于 TCP 什么状态
如果 A 与 B 建立了正常连接后,从未相互发过数据,这个时候 B 突然机器重启,问 A 此时处于 TCP 什么状态?如何消除服务器程序中的这个状态?(超纲题,了解即可)
因为 B 会在重启之后进入 tcp 状态机的 listen 状态,只要当 a 重新发送一个数据包(无论是 syn 包或者是应用数据),b 端应该会主动发送一个带 rst 位的重置包来进行连接重置,所以 a 应该在 syn_sent 状态
第 18 题:React 中 setState 什么时候是同步的,什么时候是异步的?
1、由 React 控制的事件处理程序,以及生命周期函数调用 setState 不会同步更新 state 。
2、React 控制之外的事件中调用 setState 是同步更新的。比如原生 js 绑定的事件,setTimeout/setInterval 等。
第 48 题:call 和 apply 的区别是什么,哪个性能更好一些
1. Function.prototype.apply 和 Function.prototype.call 的作用是一样的,区 别在于传入参数的不同;
2. 第一个参数都是,指定函数体内 this 的指向;
3. 第二个参数开始不同,apply 是传入带下标的集合,数组或者类数组, apply 把它传给函数作为参数,call 从第二个开始传入的参数是不固定的,都会传给函数作为参数。
4. call 比 apply 的性能要好,平常可以多用 call, call 传入参数的格式正是内部所需要的格式
第 49 题:为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?
1. 没有跨域问题,一般这种上报数据,代码要写通用的;(排除 ajax)
2. 不会阻塞页面加载,影响用户的体验,只要 new Image 对象就好了;(排 除 JS/CSS 文件资源方式上报)
3. 在所有图片中,体积最小;(比较 PNG/JPG)
第 51 题:Vue 的响应式原理中 Object.defineProperty 有什么缺陷?
为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
? Object.defineProperty 无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
? Object.defineProperty 只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy 可以劫持整个对象,并返回一个新的对象。
? Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
第 53 题:输出以下代码的执行结果并解释为什么
var a={n: 1};
var b=a;a.x=a={n: 2};
console.log(a.x)
console.log(b.x)
结果:undefined{n:2}
首先,a 和 b 同时引用了{n:2}对象,接着执行到 a.x=a={n:2}语句,尽管赋值 是从右到左的没错,但是.的优先级比=要高,所以这里首先执行 a.x,相当于为 a(或者 b)所指向的{n:1}对象新增了一个属性 x,即此时对象将变为 {n:1;x:undefined}。之后按正常情况,从右到左进行赋值,此时执行 a={n:2}的时 候,a 的引用改变,指向了新对象{n:2},而 b 依然指向的是旧对象。之后执行 a.x={n:2}的时候,并不会重新解析一遍 a,而是沿用最初解析 a.x 时候的 a, 也即旧对象,故此时旧对象的 x 的值为{n:2},旧对象为 {n:1;x:{n:2}},它被 b引用着。后面输出 a.x 的时候,又要解析 a 了,此时的 a 是指向新对象的 a,而这个新对象是没有 x 属性的,故访问时输出 undefined;而访问 b.x 的时候,将输出旧对象的 x 的值,即{n:2}。
第 73 题: 介绍下 BFC、IFC、GFC 和 FFC
BFC(Block formatting contexts):
块级格式上下文页面上的一个隔离的渲染区域,那么他是如何产生的呢?可以 触发 BFC 的元素有 float、position、overflow、display:table-cell/ inline-block/table-caption ;BFC 有什么作用呢?比如说实现多栏布局’
IFC(Inline formatting contexts):
内联格式上下文 IFC 的 line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的 padding/margin 影响)IFC 中的 line box 一般左右都贴紧整个 IFC,但是会因为 float 元素而扰乱。
float 元素会位于 IFC 与与 line box之间,使得 line box 宽度缩短。 同个 ifc 下的多个 line box 高度会不同 IFC 中时不可能有块级元素的,当插入块级元素时(如 p 中插入 div)会产生两个匿名块 与 div 分隔开,即产生两个 IFC,每个 IFC 对外表现为块级元素,与 div 垂直排列。那么 IFC 一般有什么用呢?水平居中:当一个块要在环境中水平居中时, 设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。
垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
GFC(GrideLayout formatting contexts):
网格布局格式化上下文当为一个元素设置 display 值为 grid 的时候,此元素将会 获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义 网格定义行(grid definition rows)和网格定义列(grid definition columns)属性 各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)
为每一个网格项目(grid item)定义位置和空间。那么 GFC 有什么用呢,和 table 又有什么区别呢?首先同样是一个二维的表格,但 GridLayout 会有更加丰富的 属性来控制行列,控制对齐以及更为精细的渲染语义和控制。
FFC(Flex formatting contexts):
自适应格式上下文 display 值为 flex 或者 inline-flex 的元素将会生成自适应容器 (flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端 也足够了,至少 safari 和 chrome 还是 OK 的,毕竟这俩在移动端才是王道。Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素, 而设置为 inline-flex 的容器则渲染为一个行内元素。伸缩容器中的每一个子元 素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如 何布局。
第 83 题:var、let 和 const 区别的实现原理是什么
三者的区别:
? var 和 let 用以声明变量,const 用于声明只读的常量;
? var 和 let 用以声明变量,const 用于声明只读的常量;
? var 声明的变量,不存在块级作用域,在全局范围内都有效,let 和 const 声明的,只在它所在的代码块内有效;
? let 和 const 不存在像 var 那样的 “变量提升” 现象,所以 var 定义变量可以先使用,后声明,而 let 和 const 只可先声明,后使用;
? let 声明的变量存在暂时性死区,即只要块级作用域中存在 let,那么它所声明的变量就绑定了这个区域,不再受外部的影响。
? let 不允许在相同作用域内,重复声明同一个变量;
? const 在声明时必须初始化赋值,一旦声明,其声明的值就不允许改变, 更不允许重复声明;如 const 声明了一个复合类型的常量,其存储的是一个引用地址,不允许改变的是这个地址,而对象本身是可变的。
变量与内存之间的关系,主要由三个部分组成:
? 变量名
? 内存地址
? 内存空间JS 引擎在读取变量时,先找到变量绑定的内存地址,然后找到地址所指向的内 存空间,最后读取其中的内容。当变量改变时,JS 引擎不会用新值覆盖之前旧 值的内存空间(虽然从写代码的角度来看,确实像是被覆盖掉了),而是重新分配一个新的内存空间来存储新值,并将新的内存地址与变量进行绑定,JS 引擎会在合适的时机进行 GC,回收旧的内存空间。
const 定义变量(常量)后,变量名与内存地址之间建立了一种不可变的绑定关系,阻隔变量地址被改变,当 const 定义的变量进行重新赋值时,根据前面的论述,JS 引擎会尝试重新分配新的内存空间,所以会被拒绝,便会抛出异常。
第 96 题:介绍下前端加密的常见场景和方法
首先,加密的目的,简而言之就是将明文转换为密文、甚至转换为其他的东西, 用来隐藏明文内容本身,防止其他人直接获取到敏感明文信息、或者提高其他人获取到明文信息的难度。通常我们提到加密会想到密码加密、HTTPS 等关键词,这里从场景和方法分别提一些我的个人见解。
场景-密码传输
前端密码传输过程中如果不加密,在日志中就可以拿到用户的明文密码,对用户安全不太负责。这种加密其实相对比较简单,可以使用 PlanA-前端加密、后端解密后计算密码字符串的 MD5/MD6 存入数据库;也可以 PlanB-直接前端使用一种稳定算法加密成唯一值、后端直接将加密结果进行 MD5/MD6,全程密码明文不出现在程序中。
PlanA 使用 Base64 / Unicode+1 等方式加密成非明文,后端解开之后再存它的MD5/MD6 。
PlanB 直接使用 MD5/MD6 之类的方式取 Hash ,让后端存 Hash 的 Hash 。
场景-数据包加密
应该大家有遇到过:打开一个正经网站,网站底下蹦出个不正经广告——比如X 通的流量浮层,X 信的插入式广告……(我没有针对谁)但是这几年,我们会发现这种广告逐渐变少了,其原因就是大家都开始采用 HTTPS 了。被人插入这种广告的方法其实很好理解:你的网页数据包被抓取->在数据包到达你手机之前被篡改->你得到了带网页广告的数据包->渲染到你手机屏幕。而 HTTPS 进行了包加密,就解决了这个问题。严格来说我认为从手段上来看,它不算是一种前端加密场景;但是从解决问题的角度来看,这确实是前端需要知道的事情。
Plan 全面采用 HTTPS
场景-展示成果加密
经常有人开发网页爬虫爬取大家辛辛苦苦一点一点发布的数据成果,有些会影响你的竞争力,有些会降低你的知名度,甚至有些出于恶意爬取你的公开数据后进行全量公开……比如有些食谱网站被爬掉所有食谱,站点被克隆;有些求职网站被爬掉所有职位,被拿去卖信息;甚至有些小说漫画网站赖以生存的内容也很容易被爬取。
Plan 将文本内容进行展示层加密,利用字体的引用特点,把拿给爬虫的数据变成“乱码”。举个栗子:正常来讲,当我们拥有一串数字“12345”并将其放在网站页面上的时候,其实网站页面上显示的并不是简单的数字,而是数字对应的字体的“12345”。这时我们打乱一下字体中图形和字码的对应关系,比如我们搞成这样:
图形:1 2 3 4 5 字码:2 3 1 5 4
这时,如果你想让用户看到“12345”,你在页面中渲染的数字就应该是“23154”。
这种手段也可以算作一种加密。
前端面试合集~
八股文and大厂面经~
技术知识点源码笔记解析~
总是投简历找不到工作,或者已读不回居多要考虑简历的问题,也可以【点击此处】,优化及修改
很多时候来说前端开发确实对新人不友好,想要更进一步,薪资涨幅比较难,大多时候都没有机会,简历的修改与更新,项目的参与和制作,大环境就是这样,想要进步只能被迫向前,内卷每个行业都有,不是说只有前端卷的严重,所以安稳求富贵,多给自己的技术升升级才能在行业不断更迭下维持现状,寻找突破~
*请认真填写需求信息,我们会在24小时内与您取得联系。