导语
近年三维表现已经越来越多的融入到各种商业设计当中,在电商、品牌、UI、影视等各个领域都有广泛的运用。其中一个关键因素是C4D这款软件的出现,大大降低了3D设计的学习门槛。
C4D相对于专业性更强、功能较为复杂的3DMax、Maya、ZBrush等软件,界面更加简洁友好,对于没有接触过3D的的小白,学习成本更低。配合Octane、Redshift等渲染器,可以很快做出强视觉表现力的效果。凭借这种操作友好、易出效果的特性,C4D很快成为了近年最流行的3D设计软件之一。
本文结合作者自身的经验整理了一波自学的思路和技巧,希望能在大家学习C4D的过程中有所帮助。
前言
相信很多没有三维设计基础的小白,刚接触到C4D时会有无从下手的感觉,面对各种形形色色的命令菜单和工具面板,内心是这样的:
其实大可不必担心,不同方向的设计师可以有不同的侧重点,只要掌握自身职业需要的模块,并不需要学会所有的功能。追求大而全反而难度大效率低,容易产生挫败感从而被劝退。
所以这里建议的C4D学习思路是:结合自身的职业方向,先明确要学习的侧重点,集中精力突破,然后再根据新的需要逐步学习更多即可。
学习过程则大体上分为入门、上手、实战三个阶段。
Part 1. 入门
1.1 明确学习方向
C4D大体可以分为建模、渲染、角色、动画、运动图形、动力学这几个模块,每个模块都可以看成是独立的知识体系,往下又有更具体的细分。真要全面仔细钻研的话,需要投入很多的时间精力,这也是让很多初学者无从下手甚至望而却步的原因。
所以除了建模和渲染是绕不开的基本模块,我们可以将另外几个看成是比较具有针对性的模块,具体需要着重学习哪一部分,则需要先明确最适合自己的学习方向:
比如你是电商设计师,平时的工作内容主要是制作各种产品高大上的渲染图以及推广视频,那除了基本的建模与渲染,还可以着重学习运动图形,做出各种酷炫的商业广告视频;
如果你是IP设计师,则需着重学习角色模块,在完成静态角色的建模渲染后,绑骨骼刷权重也是必须掌握的知识点,才能做出丰富的动作和表情,让角色生动起来;
总之,不同职业方向,甚至项目的不同时期,都有不同的学习侧重点,这里需要每个人自己去判断。
建模和渲染则是最常用的两个模块,无需有职业方向的针对性,都应该在前期优先学习,并且做到基本掌握甚至熟练运用。
常规的步骤是先学习建模,再学习渲染;不过建模比较枯燥,渲染则是最出效果也是最提升学习信心的环节,我认为根据个人喜好,先学渲染再学建模,反而是更推荐的学习顺序。
1.2 选择学习资源
选择学习资源方面,目前网络的免费教程十分丰富,依靠教程的学习足以让你初期快速的上手,新手在选择教程方面尽量以体系较为完整,演示时软件版本较好的原则,如英文水平较好建议去外网看看各路大神的教程,原汁原味的学习;另外考虑到外网资源的机翻和获取难度的原因,这里主要推荐一些国内网络能获取自学资源:
建模
建模方面在学习阶段主要注重C4D的工具使用和基础技巧,这里推荐几个免费教程。
1、https://www.bilibili.com/video/BV1Cb411T7Dc?p=1&vd_source=018f00780190d4b9c79b5abbdb3be276
2、https://www.bilibili.com/video/BV1PZ4y1s7vm?p=1&vd_source=018f00780190d4b9c79b5abbdb3be276
渲染
渲染以OC渲染器为例,这是现网能找到比较完整的免费教程,学习后可以直接上手出图。
1、https://www.bilibili.com/video/BV1ur4y1T72V?p=39&vd_source=018f00780190d4b9c79b5abbdb3be276
2、https://www.bilibili.com/video/BV1f4411V7qh?p=1&vd_source=018f00780190d4b9c79b5abbdb3be276
动力学
动力学可以由浅入深,从基础的常用动态手法及运动原理开始入手,以小实例练习的方式慢慢转向大场景的动态设计学习。
1、https://www.bilibili.com/video/BV17f4y127uv/?spm_id_from=333.788.recommend_more_video.1&vd_source=018f00780190d4b9c79b5abbdb3be276
2、https://www.bilibili.com/video/BV1ZA411w7qC/?spm_id_from=333.337.search-card.all.click&vd_source=018f00780190d4b9c79b5abbdb3be276
更多综合性实战教程
各大网站都能找到不少实战案例的教程,根据需要可以找到更多。
1.https://www.bilibili.com/video/BV177411P7d1?p=1&vd_source=018f00780190d4b9c79b5abbdb3be276
2.https://www.bilibili.com/video/BV1AY4y1G7Nc?p=1&vd_source=018f00780190d4b9c79b5abbdb3be276
1.3 软硬件配置相关
打团下副本之前,还得先准备一下装备;这里简单对于萌新学习前的软硬件要求做一些说明和推荐。
渲染器选择
C4D目前可选主流的渲染器有octane、阿诺德、Redshift、vray、自带渲染器(不推荐)。主流渲染器各有优缺点,综合下来笔者推荐萌新选择OC渲染器,原因是学习资源多,学习难度低,渲染效果优、渲染速度快等优点。
以下是各渲染器的对比,萌新们可权衡自身的情况进行选择:
电脑配置
在PC电脑方面,以笔者正版OC4.0渲染器为例,显卡选择N卡,型号以20系列以上最好,显存4G以上(有经费的可以入手今年的40系列显卡);其他配置看自己的经济情况而定,如CPU方面单核性能越强对于渲染效率和c4d默认渲染器的加速越快,内存推荐64G以上,另外在电源上如果已经配备了20系列以上的显卡建议选择900W以上的,除了显卡和CPU这两个核心硬件其他的配置主要看个人情况而定,对电脑不懂的优先看电商平台的整机方案,主要以显卡和cpu为参考依据,其他的配置可浮动选择。
在苹果电脑方面,笔者并不推荐以3d工作为主的设计师选择苹果电脑,主要原因是主流渲染器的选择较少,另外C4D插件各方面的支持也远不如PC方便和丰富(如有特殊原因,可以优先选择M1芯片的电脑或者配备N卡独显的苹果电脑)。
软件版本
C4D软件版本推荐使用最新版本或者R23以上版本,随着厂商的更新换代,有些以前只有插件能完成的功能慢慢完善在新版本上,新版本带来的便捷功能可提高萌新的出图效率并免去旧版本没有兼顾的功能导致的学习成本浪费问题。
另外在OC渲染器上的版本问题尽量以当前版本能兼容的最新OC为主,当然,需要你的显卡需要和OC版本是匹配的情况下。
1.4 好记性不如烂笔头
收藏和观看的教程多了,容易看了后面的忘记前面的,或者没有实际上手印象不深。这里我尝试过最好用的方法可以总结为一句话,就是俗话说的“好记性不如烂笔头”。
对于一些关键的知识点,或者很有用的上手练习案例,可以在自己学习或者练习后,将关键步骤以在线笔记的形式自己整理一遍。
这样做有两个好处,一是能大大加深你对知识点的印象,不易遗忘;二是即使真的隔了很长时间有所遗忘,只要调出对应的文字笔记,就能很快重新想起对应知识点,比起重新翻出视频教程,边拖进度条检索再看一遍,效率高得多。
比如我之前在学习渲染体积光效果(丁达尔效应)时,总是掌握的不扎实,学过就忘,下回再用到时,基本相当于又要翻出视频教程再看一遍,效率很低。但是将关键知识点整理成笔记后,不单对这个知识点记得很牢,甚至能在不重新翻看笔记和教程的条件下,熟练的以教程中提到的三种不同方式做出体积光。
笔记链接:https://note.youdao.com/s/Lwt42DsG
以下是我整理的部分笔记库,感觉在笔记库里的知识点才算是比较掌握了的。
1.5 多搜集优秀案例
除了掌握工具,多看优秀案例以提升自己的设计思维和审美也很重要,只有看的优秀案例够多够好,将自己的设计眼光、审美水平、思考方式向大神们的靠拢,才能做出好的作品。
这里推荐几个我觉得的很赞的3D类网站:
Artstation:http://www.artstation.com;
Sketchfab:https://sketchfab.com/feed;
Behance 3D:https://www.behance.net/galleries/3d-art;
Dribbble 3D:https://dribbble.com/search/3d;
Part 2. 上手
2.1 熟能生巧多练习
上手阶段,充分的动手练习是必不可少的。
这里的练习也分为两种,一种是跟随教程案例做出一样的效果,一种则是结合自己感兴趣的题材设定一个主题或场景,将学习的知识点融会贯通,在自己的命题作品里实际应用起来。两种练习的方式也是相辅相成,在积累足够多的教程案例练习后,更推荐按照自己的想法来创作。
比如我会将自己感兴趣的漫画题材,在C4D里作为一个场景练习,融合进平时学的一些知识点。
《头文字D》场景
《海贼王》场景
因为用的是自己感兴趣的内容练习,所以做起来也上手很快,知识点也记得很牢,推荐大家可以试试。
2.2 善用插件提效率
1.Forester-植物生成插件
轻松生成各种类型的植物和部分岩石,各项小参数的调整方便个性化的调整,另外有便捷的动力系统可以轻松制作风吹植物的效果,结合OC渲染器的克隆功能搭建大场景非常轻松,适合在做动态设计的时候快速生成搭建场景。
2.QuadRemesher-四边面重拓补
有时候我们工作中会遇到三角面模型,对于新手来说转换成四角面模型可以选择这款插件轻松转换成你想要的四角面而且还有便捷的参数可以调整。
3.PolyCircle-挖洞插件及Nitro4D NitroCap-封洞插件
在日常建模的工作中经常需要给模型开洞及封洞的操作,虽然靠布线调整也可以实现,但是插件的效率更便捷,所以推荐这两款插件分别对应的模型开洞及模型封洞的功能,另外注意在C4D软件R26之前都是必备的插件,但如果你软件版本是R26以上版本,那么自带整合了这样的工具,不需要额外安装插件了。
4.CodeVonc Proc3durale-镂空腐蚀溶洞效果插件
这是一款风格化的效果插件,可以配合噪波制造出独一无二的风化、镂空、分解动画、甚至是流体动画的效果,在产品设计及品牌动态视频中运用广泛。
(图来源于网络侵删)
5.TerraformFX-地形插件
这块地形插件,可以让你轻易搭建自然环境,制作次时代的虚幻场景,操作简单,可以在Cinema 4D 中生成、动画和逼真的地形。在几秒钟内创建非常详细的山脉、峡谷和沙漠。直观的非破坏性工作流程可以轻松创建和自定义地形。
(图来源于网络侵删)
Part 3. 实战
在入门的学习和上手的练习之后,相信很多人都会对C4D有了初步的掌握。这时更重要的当然是将这些学到的知识点运用到实际项目当中,这样的实战操作才能让你的知识体系更有针对性,并且实际项目命题固定、要求更高,完成后的提升才会更大。
这里分享几个在完成基础的学习与练习后,我们用C4D做的实际项目。
3.1 QQ小游戏-春节会场
小游戏会场是从QQ春节活动的主会场进入,通过限时抽奖以及游戏任务等形式,引导用户参与活动,从而提升业务增长和助力品牌传播。
在前期设计推导阶段,我提炼了三个设计关键词,并对应发散出一些相关元素:
一是游戏:这是凸显平台特色和趣味性的元素;
二是福利:这是强化用户参与活动的动机;
三是春节:春节活动不可少的是体现节日氛围的元素;
根据这些元素画了三个方向的概念草图,分别以游戏机、扭蛋机、街机作为主要载体。
最终我们选择了通过破窗的形式将Q猛虎结合进场景中的方向一,展示游戏和夺宝元素,让用户感知福利的同时,也体现小游戏平台的特色和趣味性。
创意上是参照超级玛丽这种经典的横版过关形式,也将中国传统建筑中的红墙金瓦、松树、福袋这些元素融入在了画面中。
游戏机场景及其他主要元素建模
场景白模及空间构成设定
角色及福袋动态的制作,这里主要用到了角色及动力学模块相关的一些知识点。
渲染完成后的主视觉,Q猛虎在游戏机上往前奔跑,不断获得福袋并蹦出金币、红包实际UI中的应用效果
实际UI中的应用效果
另外将主视觉中的“松树”,延展成了松、竹、梅、兰这四种具有传统中国风的植物,作为辅助元素运用到页面中,保持整体调性的统一。
部分主要页面总览
3.2 QQ红包-节日封皮
节日红包封皮是传递用户关怀的重要手段,作为QQ红包的一部分,我们希望让用户有更新颖的感知和更深刻的共鸣。
相对于常规的插画手绘风格,我们希望尝试用3D的方式做一些新的探索。
在构思中秋节的红包封皮时,首先围绕“中秋”进行关键词发散
再选取其中桂树、玉兔、明月等这几个适合构建场景的元素,构建成一个立体化的场景
将一些元素抽象化,结合3D手法,加入更有意境的表达
最终完成的效果,整体也是塑造一个比较有中国风和意境的场景
新年封皮也是用同样的方式完成,像刚才中秋的桂花树一样,这里也将锦鲤也做了一些抽象化的表达,比如鱼的眼睛是宝石质感,鱼的身体是黄金质感,传递一种新年好运、财运连连的感觉。
最终完成的效果,QQ和banyQ坐在锦鲤背上,手上拿着铜钱串在吊锦鲤,寓意新年大吉大利、锦鲤附体。
新版封皮的使用量对比旧版有了较大提升,可以看出用户对新版封皮的喜爱程度还是很高的,目前的节日封皮也是按照新风格持续延展中。
Part 4. 结语
以上就是本文的全部内容,希望能帮助大家在学习C4D的过程中有所帮助,总结下来就是多看多练多运用。对文中提到的插件感兴趣的朋友,也可以通过附上的链接去官网了解更多详细介绍。若是大家有更好的学习建议,也欢迎在评论区留言一起讨论。
作者:腾讯ISUX
链接:https://www.zcool.com.cn/article/ZMTUxNDU4MA==.html
来源:站酷
界面设计的好坏,会直接影响到用户的使用体验,很多时候我们往往会直接拿到竞品的页面搬运到自己产品上,而没有针对自身产品的特点和业务加以思考。
这种做法理论上不会让自己的页面出错。但是很多人往往忽略了一点,就是别人这么设计的出发点是什么,是否匹配自身产品的业务流程,如果不了解这些贸然的去搬运设计,那么时间久了就会养成一个不好的习惯,导致思维不能得到足够的刺激和知识的沉淀。当需要我们专门进行设计构思时,就会遇到诸多困难。
如果是刚入手的领域,前期可以去进行适当的搬运参考,但是一定要了解别人设计思考点,明白其背后的原因,将其沉淀成自己的知识储备在脑海中。
过去60年,人类社会的数据发生了爆炸式增长。2008年人类大约创造了近10亿张DVD能存储的数据,这等同于过去5000年的人类创造数据的总和。12年,调研机构预测信息每隔18月会翻一倍20年,调研机构预测信息每隔73天会翻一倍
在信息爆炸的年代,人类进化的速度却是缓慢的,我们现在的大脑跟250万年前的原始人并没有太大区别。
我们的大脑每秒钟要接收约4000万次的感官信息输入,但意识一次能注意到其中约40个,其中短期工作记忆能处理的只有4±1个。
正是由于现代信息数据的大爆炸,多数产品日益臃肿的结构,以及人类有限的处理能力,所以呈现什么信息,以何种形式呈现的信息层级设计就非常重要。
作为设计师,我们有必要根据自身产品的业务方向,以及用户的行为和特征,结合信息环境,选择合适的信息,并以适合的方式进行组织和呈现,以便让用户获取并理解信息更容易,完成信息的组织和传达作用。
相关联信息需要进行归类,无论是什么类型的产品模块,我们在设计中应当做好信息分层,当两段内容元素具有关联性时,他们应当作为一个整体给用户展现。
(1)层级数量应靠近“3”
信息层级作为影响页面信息传达效率的重要因素之一,那么怎样做好页面的信息层级便尤为重要。网上资料大多都在围绕对比、对齐、亲密、重复四个基本原则讲解。
不可否认的是这四个方法对于我们排布信息层级确实起到了很大的作用,并且也是我们非常熟悉的。但其阐述得太过宽泛,在我们实际工作中面对复杂层级排版时,仍会面感到困惑,很难直接有效地利用。
于是我把优秀的案例进行收集并整理分析。
经过线上页面与概念的整体研究发现,他们在遵循排版原则的基础上,都存在着一个简单的规律:主内容的层级控制在三层左右。
如下图所示:
可以发现,三层左右的层级是最容易被用户识别的,且视觉上不易混乱。三层往后,随着层级越多其复杂性会成比增加。
比如我们看下面这两个例子,左边层级方面平铺直叙没有重构区分,使得层级复杂,造成用户识别效率变低。但其实我们只需要对信息加以归类并控制层级数量,瞬间就变得更简单且易懂。
因此,我们需要在着手设计前,首先思考一个逻辑:尽量将我们的内容层级控制在三层左右,且这三层内有比较明显的对比关系。
有朋友看到这肯定要问了,这个道理大家都懂啊,可是在实际工作中大多数拿到的信息都非常多,根本做不到保持在三层以内。别着急,本文的重点当然不是告诉你这么简单的道理,而是在面对复杂层级的时候,我们应该怎样去控制它的层级表现,从而让它在最终呈现上保持在三层左右,让用户获取信息的效率更高。
(2)源头筛选处理
源头筛选的关键在于接手复杂信息时,我们首先需要从源头上进行第一层的判断,了解这些信息是否真实地被需要。这也是我们大多数人容易忽视的一点,当然这也不能完全怪我们,因为通常需求给到我们的时候都是大致的概括,好一点的话还有个交接文档,甚至有时候需求拿到我们手上时,已经转好几手了交接人可能也不知所云,导致很难知晓其底层出因,
源头筛选的本质就是判断我们当前所要呈现的信息是不是必要的。
比如某些时候产品给到了我们很多信息,但我们并不一定会全盘接受,而是通过当前页面的业务场景去进行判断。确定每个信息的合理性,从而可以决定有些元素是否可以删减,提高整体信息设计的一致性。
过程需要我们对以下2点进行思考:
上述两个问题的确认,会影响我们对后面的信息排布。因此我们需要在源头,比如去和产品或者业务沟通,弄清楚该信息呈现的缘由以及必要性,这样能够帮助我们最后理清楚信息层级。
(3)在排布上降低复杂度
信息排布的本质是通过我们对信息进行主观的排列上的组织重构,来将复杂的层级控制在三层左右的区间里。从而保证我们页面的简洁性、规律性、识别性。
通过目前的实践总结,合理地安排信息层级的方法大致可以分为:分组、组件、组织、融入、弱化。
① 信息分组
信息分组是大家在设计时都能够想到的形式,分组能够将复杂的信息归组从整,从而降低整体复杂度,清晰线索。
我们常用的分组方式主要有三种:间距、分割线、卡片。
那么这三种方式有没有区分呢?
VIVO设计团队曾经就这个问题展开过用户调研,但结果表示,如果纯粹从用户的角度来讲,对其变化感知不大。但这三种分割方式会影响我们在呈现信息时的整体视觉观感,因此我们可以根据当前信息的复杂度作出以下规则:
② 利用组件拆分
组件其实是目前大部分设计师在进行信息排布时必备的部分,因此对于这部分设计师的熟练度也是最高的。而本篇想要强调的是,目前这几种组件对于我们信息层级的划分起到了比较重要的作用:树形结构、表格结构、步骤条、选项卡。
③ 灵活组织
通过对组织方式的调整,我们可以将多层结构的样式通过拆分布局来将其控制在三层内。
举个简单的例子:
从图中你可以看出左侧的层级较多,尤其是两层tab的叠加,视觉上就会显得稍微有点凌乱。我们可以通过将第二层tab换个布局,从上下结构变为左右结构,达到从视觉上简化层级的作用:
当然以上只是举了一个简单的例子。这里底层逻辑就是当遇到相对比较复杂逻辑时,我们可以通过改变结构使其交互逻辑更清晰,从而减少其复杂度。
④ 巧妙融入
我们可以利用信息融入的形式来减弱其对层级的影响。信息融入从本质上讲就是将某两种层级信息通过不同的组合方式,让其融入到同一个层级中。比如我们看下面这一个例子,产品设计中将button与查询项利用分割排列在一起,从而变为同一层级,通过这种方式有效降低了页面的复杂度。
当我们在进行B端布局时,信息融入这个方法用得比较多。比如我们最常见的标题、搜索和按钮等都放在同一行上。这样既能够节省视觉空间,还能够降低信息层级的复杂度。
但在进行信息融入的过程中,我们需要注意的是:如果放在同一层级会造成理解上的误解时,这个时候不要采用该方案。比如搜索框的位置,放在哪个层级决定了对应的搜索范围。
⑤ 信息弱化
信息弱化的原则是:将某些超出层级的部分进行弱化。
比如图中有5个层级,但其巧妙地将功能筛选融入到了当前的结构中,使得即使超过3层我们也不会觉得其特别复杂。
在很多时候,我们觉得信息混乱的原因,就是页面要素太多太花哨。
比如工作中的一个小卡片,也就是利用信息弱化去减少画面的复杂度:
因此我们需要学会对信息分级,不重要的信息就进行弱化,这样整体的呈现上会好很多。
但不可否认仍会有更复杂的页面,即使缩减也仍有过多层级,那么这个时候就一定要记得最开始的从源头去追溯这些所有信息是否必要。
(4)突出热区
当模块具有按钮、文字链、图片入口等需要下一步操作的关键元素,需要进行高亮显示,以此帮助用户快速定位目标。
图中 “Learn more” 使用文字高亮进行处理,通过颜色让用户快速定位入口,且不影响用户正常阅读,若使用色块按钮进行突出,模块会冗余,过于喧宾夺主。
当产品需要用户进行多步骤完成任务时,应当展示系统进度,让用户了解他们的行为操作在界面中所处于的位置。
比如下图中房屋装修信息填写流程,用户面对这种多流程任务时,耐心往往很低,我们可以在设计时添加系统状态进度条,时刻提示用户当前的节点,此方法应用场景还有注册登录、信息完善等更多场景,目的都是为了让用户达到交互可预测的状态,提升用户体验。
我们在设计内容复杂的网页时,建议根据产品诉求和用户目标,合理的放置元素,以此来达到目标,另一方面符合眼动规律的浏览顺序,可以让用户不会产生视觉疲惫,每个视觉点停顿时看到元素都是不同,提升用户体验。
在设计大面积文字排版时,应当注意字体粗细,它决定着我们的设计是否易读性高。
无论标题还是内容,字体过重或者过轻都会降低文本的基本识别度,而且遇到文字信息过多的情况,长时间专注文本的识别很容易出现视觉疲劳的情况。
在设计UI界面中,无论是长文字体还是模块元素字体,我们都要注意字体的重量,保证基本识别度的同时,优化视觉重心,确保用户在阅读时不容易陷入疲劳。
当界面中存在多个入口时,我们可以对这些入口进行优先级处理,以突出核心功能为目的,用户浏览界面的动作是大面积扫读的形式,这就意味着我们需要弱化无关信息,既保证了界面的基本美观性,又能够具备良好的体验。
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加蓝小助,微信号:ben_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系01063334945。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
web自动化测试作为软件自动化测试领域中绕不过去的一个“香饽饽”,通常都会作为广大测试从业者的首选学习对象,相较于C/S架构的自动化来说,B/S有着其无法忽视的诸多优势,从行业发展趋、研发模式特点、测试工具支持,其整体的完整生态已经远远超过了C/S架构方面的测试价值。接上一篇文章,我们将继续深入探讨Selenium的相关使用方法与技巧。
此篇中所用的技术栈为Selenium+Python,因其本身编程难度不高,总体思想都是基于面向对象的编程理念,故只要大家的编码语言基础不弱,就完全可以做到平替。
在正式启动浏览器之前,这里还需要说说上一篇没有提及的一个问题,后台有同学私信说在对应驱动网站上完全找不到自己浏览器对应版本的驱动,关于浏览器驱动的版本,大家都知道驱动的版本应该是要与浏览器的版本完全对应上的。但往往日常工作中因为环境或者其他客观因素会导致浏览器的版本五花八门,也会出现驱动网站上完全没有你目前工作环境中对应的浏览器版本,这里我们大可使用中版本号一致的驱动来进行尝试,没有必要将版本进行完全的匹配。比如你的Chrome浏览器的版本号为107.0.5304.107
,如果这时对应网站只有107.0.5304.62
与108.0.5359.22
的前后两个版本的驱动比较相近,这里就有两个选择,第一就是卸掉原有的浏览器,安装对应的版本;第二则是选择107.0.5304.62
来进行尝试;相信大家在成本耗时的判断下,一般都会选择第二个选项来进行尝试对吧?那么我可以很负责任的告诉你,第二个判断是完全行的通的。不必太过纠结驱动的小版本号是否完全匹配。
我们将一切准备就绪后就可以开始我们的selenium之旅了,首先我们需要将使用selenium进行浏览器的启动(访问百度)。
from selenium import webdriver
browser = webdriver.Chrome() browser.get('https://www.baidu.com')
如果对应的浏览器驱动没有进行环境变量的设置,可以在代码中直接进行程序的路径指定来进行后续的浏览器操作。
from selenium import webdriver
path = r'C:\Program Files\Google\Chrome\Application\chromedriver.exe' browser = webdriver.Chrome(path) browser.get('https://www.baidu.com')
使用Selenium打开后的浏览器都会标识出正在受到自动化测试软件控制的相关提示。
Selenium本身提供给了我们非常多的各类浏览器与页面的操作函数,方便我们根据所需测试业务来进行自由搭配使用甚至是二开。
对于浏览器窗口的尺寸进行控制与获取,如最大化、最小化、指定窗口大小等。
窗口全屏
browser.fullscreen_window()
窗口最大化
browser.maximize_window()
窗口最小化
browser.minimize_window()
自定义窗口大小(宽X高)
browser.set_window_size(1080, 720)
自定义窗口坐标位置与大小(x坐标,y坐标,宽X高)
browser.set_window_rect(100, 200, 1080, 720)
获取窗口的大小(宽X高)
browser.get_window_size()
获取窗口的坐标位置,返回一个字典对象
browser.get_window_position()
获取窗口的坐标与大小(x坐标,y坐标,宽X高)
browser.get_window_rect()
获取当前窗口的句柄
browser.current_window_handle
获取当前所有窗口的句柄
browser.window_handles
对于浏览器当前页面的一些操作,如前进、后退、刷新等。
前进(下一页面)
browser.forward()
后退(上一页面)
browser.back()
刷新(当前页面)
browser.refresh()
截图并保存为test.png(当前页面)
browser.save_screenshot('test.png')
截图并保存为png文件(当前页面)
browser.get_screenshot_as_file('test_02.png')
截图并将信息转为base64编码的字符串
browser.get_screenshot_as_base64()
对于浏览器当前一些信息的获取与操作。
获取页面URL(当前页面)
browser.current_url
获取日志类型,会返回一个列表对象
browser.log_types
获取浏览器操作日志,注意函数内的参数为固定值类型’browser’
browser.get_log('browser')
获取设备操作日志,参数原理同上
browser.get_log('driver')
获取当前页面标题
browser.title
获取当前浏览器的名字
browser.name
Selenium中最基础也是最重要的一环,基本上对于页面的业务操作大多数都集中与此。另外需要注意的是元素定位所使用的find_element_by的方法在很早之前就已经被废弃,这里同样也会使用最新的find_element方法进行讲解。
如何查看页面中的元素与其相关属性,这里以Chrome为例,我们只需按F12或者右键页面选择“检查”,再点击调试窗口的左上角的箭头标志或者使用快捷键Ctrl+Shift+C
来进行元素的选取,此时Elements标签页中会将焦点对应跳转至该元素的html代码行中,接下来我们就可以针对不同的元素和不同的属性来进行定位操作。
通过一个元素的name属性来进行定位。
比如定位百度中的搜索栏,我们通过name属性来进行定位。该元素的html构造如下:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
我们只需将name属性后面的值拿出,赋予给find_element方法即可。新的By方法我们只需要导入selenium.webdriver.common.by下的By方法即可。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.NAME, 'wd')
通过一个元素的class属性来进行定位。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CLASS_NAME, 's_ipt')
通过一个元素的id属性来进行定位。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.ID, 'kw')
css selector也被成为选择器定位,它通过页面内的元素的id、name、tag三个属性来进行定位,根据元素属性的重复程度,可以单独属性定位也可组合属性来进行定位。而且相较于xpath定位方式来说,博主更推荐使用此方法来进行定位,无论是易用度还是维护性来说比xpath定位好的多。
单属性定位–tag属性
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CSS_SELECTOR, 'input')
单属性定位–id属性
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CSS_SELECTOR, '#kw')
单属性定位–class属性
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CSS_SELECTOR, '.s_ipt')
多属性定位–tag+id属性
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CSS_SELECTOR, 'input#kw')
多属性定位–tag+class属性
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.CSS_SELECTOR, 'input.s_ipt')
同样的,其他的组合方式大家可以举一反三,不断尝试,比如模糊匹配input[class ~= "局部关键字"]
、层级定位#form > span > input
等等等等。
这种定位方式适用于页面中带有超链接的元素,直接通过超链接标签内的文字进行元素定位。
我们以百度首页为例,可以看到该页面中有很多的超链接标签,如果我们想模拟点击跳转至新闻对应页面的操作,就可以用link text的元素定位方法来进行实现。
使用超链接标签对中的“新闻”一词来进行定位。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.LINK_TEXT, '新闻').click()
这个定位方式与link text定位十分相像,实际上也就是link text的模糊查找定位方式,对象也是超链接内的文字,只不过他匹配的不是全部文字而是局部。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.PARTIAL_LINK_TEXT, '新').click()
tag定位的效率总体来说不高,也不太推荐单独使用,html页面中一般也是由很多相同或不同的标签对组成。就tag而言标签重复的越多,定位的效率其实也就越低。
比如我们想在百度的搜索栏中输入“selenium”关键字,那么光使用tag其实就很难达到我们的目的,甚至无法准确定位到我们想要的元素。如果运气好,搜索栏的input标签在html页面中排在第一位那还好,只要不是第一位,我们就需要编写其他的代码逻辑来辅助我们继续定位这个元素。
所以下面的代码实在是不能称之为高效的执行代码
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.TAG_NAME, 'input').send_keys('selenium')
一般来说无法通过以上的这些元素定位方法定位的情况下,我们会使用xpath定位方法。但这里需要特别注意,xpath方法分为绝对路径和相对路径两种定位方式,博主只推荐如果真要使用xpath就使用相对路径+正则表达式的方式来进行元素定位。不推荐绝对路径的原因就不用博主多说了吧,只要你敢用,后期的脚本维护与复用绝对会让你抓狂的。
还是老样子,我们使用xpath的相对路径写法来定位百度首页的搜索栏。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.XPATH, '//*[@id="kw"]').send_keys('selenium')
另外与find_element方法相对应的find_elements方法这里就不多做介绍了,该种方法是将当前页面中所有能匹配上对应元素定位方法的元素全部获取。大家可以根据自己的需求来进行选取和使用。
我们加载页面时通常会因为网络环境等各方面的客观因素而导致元素加载的速度各不相同,如果此时我们没有对业务操作进行一定的延时执行,那么大概率业务操作会出现各类的no such element
报错。
那么我们就需要在页面元素加载完成之后再对相应的元素进行业务操作来规避上面说的这个问题。Selenium内可以使用三种延时的函数来进行对应的延时业务操作。
隐式等待的作用是在页面加载是隐性的进行特定时长的等待,如果在规定的等待时长内页面加载完毕,则会继续进入下一个业务操作,如果没有加载完毕,则会抛出一个超时的异常。这里其实有两个问题,第一,隐式等待是全局性质的,也就是说一旦你设置了个5秒,那整个程序都会使用这个等待时间类进行配置,灵活性较低;第二,如果碰到了有些页面中的元素是局部加载的话,那整个页面的加载是否完成也就没有了其意义,隐式加载无法针对这样的情况作出调整,智能度较低。所以一般来说只要是对于页面的整体加载要求不高或者元素的加载比较稳定的程序,都可以使用隐式等待来进行延时操作。
from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.baidu.com') browser.implicitly_wait(5) browser.find_element(By.XPATH, '//*[@id="kw"]').send_keys('selenium')
显式等待的作用则是使用特定的等待时长来进行某些业务逻辑判断,如果判断(比如元素是或否加被定位)在时间完成那继续执行下一个业务操作,如果判断失败也会抛出no such element的异常,而显式等待的默认检查元素周期为0.5秒。乍一看好像与隐式等待差不多,其实不然,首先显式等待是针对页面中某个或某组特定元素而执行的,隐式则是全局,对所有的元素都生效;其二,显式等待可以通过自定义条件来进行元素的定位和选取,隐式则不行。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome() browser.get('https://www.baidu.com') ele = WebDriverWait(browser, 10, 0.5).until(EC.presence_of_element_located((By.XPATH, '//*[@id="kw"]'))) ele.send_keys('selenium')
这个应该是平时大家代码中用的最多的等待方式了吧,sleep是针对线程进行挂起的一种等待方式,等待时长根据指定的参数来进行决定。最大的好处就是简单粗暴,无任何逻辑在里面,所以也被称为强制等待。
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') sleep(2) browser.find_element(By.XPATH, '//*[@id="kw"]').send_keys('selenium')
那么以上的三种等待方式其实各有各的特点与缺点,三者之间没有绝对的好用和不好用,而在我们的日常工作场景中也希望大家可以根据实际的情况有选择性的使用。
元素加载超时我们可以使用以上三种延时方式来进行处理,那么页面超时了又该如何操作呢?selenium也为我们准备了两个函数来对应这样的局面。
页面加载超时
browser.set_page_load_timeout(30)
这里推荐将超时的时间有效的拉长,不宜过短。过短的超时时间容易导致整体页面出现未加载html代码情况下直接令驱动无法工作的情况。
页面异步js或ajax操作超时
browser.set_script_timeout(30)
这个函数是用于execute_async_script()
相关的异步js操作超时报错,由于是异步操作,等待时间同理也不易过短。
浏览器中键盘与鼠标的操作也是不可或缺的重要一环,在被测对象的业务要求中往往占有不少的戏份。
文字输入
browser.find_element(By.ID, 'kw').send_keys('selenium')
点击
browser.find_element(By.ID, 'kw').click()
点击并按住不放(左键长按),这些模拟鼠标操作需要导入ActionChains包
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw') act.click_and_hold(ele).perform()
右键点击
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw') act.context_click(ele).perform()
双击
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw') act.double_click(ele).perform()
拖拽元素至另一个元素处,ele_a 为source,ele_b 为target
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele_a = browser.find_element(By.ID, 'btn_a') ele_b = browser.find_element(By.ID, 'btn_b') act.drag_and_drop(ele_a, ele_b).perform()
拖拽元素至指定位置后松开,元素后为x,y坐标值
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'btn_a') act.drag_and_drop_by_offset(ele, 200, 100).perform()
鼠标移动至指定元素
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'btn_a') act.move_to_element(ele).perform()
按下指定的键位(示例代码中是回车键)
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.key_down(Keys.ENTER).perform()
松开指定的键位,这里也可以用链式写法
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.key_down(Keys.ENTER) act.key_up(Keys.ENTER) # 链式写法 act.key_down(Keys.ENTER).act.key_up(Keys.ENTER).perform()
移动鼠标到指定坐标位置
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.move_by_offset(100, 200).perform()
移动到距离指定元素多少距离的位置(从左上角0, 0开始计算)
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.move_to_element_with_offset(ele, 100, 200).perform()
在指定元素位置松开鼠标
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.click_and_hold(ele).release(ele).perform()
发送指定的键或者内容至指定元素
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.send_keys_to_element(ele, 'selenium').perform()
暂停所有操作,默认单位为秒
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw').send_keys('selenium') act.context_click(ele).pause(5).double_click(ele).perform()
页面中也存在着很多不同种类的组件,比如单选框、多选框、下拉列表、选项卡等。这些操作也可以通过selenium提供的函数进行实现。
清除指定元素中的内容(输入框等)
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw') ele.send_keys('selenium') sleep(2) ele.clear()
提交确认(类似于Keys.ENTER的效果)
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from time import sleep
browser = webdriver.Chrome() browser.get('https://www.baidu.com') act = ActionChains(browser) ele = browser.find_element(By.ID, 'kw') ele.send_keys('selenium') sleep(2) ele.submit()
下拉列表,我们就可以使用Select方法来实现选取操作
使用Select方法需要从selenium.webdriver.support.select导入该方法
例如下图中某网站的下拉列表对象
html构造如下
select_by_index()方法
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') ele = browser.find_element(By.ID, 'input_factor_gj_count') # 需要注意下标要从0开始,选择1%那一项 Select(ele).select_by_index('0')
select_by_value()方法
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') ele = browser.find_element(By.ID, 'input_factor_gj_count') # 指定元素的value属性值,选择1%那一项 Select(ele).select_by_value('0.01')
select_by_value()方法
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') ele = browser.find_element(By.ID, 'input_factor_gj_count') # 指定元素的文本值,选择1%那一项 Select(ele).select_by_visible_text('1%')
框架切换(Frame)
如果在页面中定位某一个元素失败并检查其属性并没有问题时,就该考虑是否在祖先节点中是否存在frame或者iframe标签。这样的页面就表名存在多层框架嵌套,这时我们就需要进行框架切换的操作,来准确定位到指定元素。
例如某页面存在两层frame嵌套,内部框架的xpath为://*[@id="mainDiv"]/iframe
,此时如果定位某个输入框失败之后,我们就应该转而跳入该frame内进行元素定位。
from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') # 定位到指定的frame path = browser.find_element(By.XPATH, '//*[@id="mainDiv"]/iframe') # 切换至该frame内 browser.switch_to_frame(path) ele = browser.find_element(By.CLASS_NAME, 'input') ele.send_keys('selenium')
标签页切换
我们浏览器在使用中一般会打开多个浏览窗口,也就是多个标签页。此时我们就可以通过每个标签页的句柄来进行定位和互相切换。
switch_to_window()
我们利用浏览器窗口的句柄来进行标签页的切换
from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.baidu.com') # 第一个窗口的句柄下标为0,打开第二个就是1 browser.switch_to_window(browser.window_handles[1]) # 此时就会使用第二个标签页去访问淘宝 browser.get('https://www.taobao.com')
弹窗处理
页面中时常也存在着各类的弹窗,比如警告、确认、提示等等,那么对于这些弹窗我们也有着相应的业务处理方法。
首先我们需要明确的是每种类型的弹窗中元素也是各不相同,所以我们针对不同的弹窗使用不同的属性来定位和操作。
警告弹窗
一般来说就是告知到使用者执行某些操作与页面之后将要注意的事项,这种窗口只需确认。
from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') browser.find_element(By.ID, 'btn_tg_title').click() sleep(1) # 在警告弹窗中点击确认按钮 browser.switch_to_alert().accept()
确认弹窗
多用于在用户执行提交操作后的动作确认,有确认和取消两个选项。
from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') browser.find_element(By.ID, 'btn_submit').click() sleep(1) #确认二选一 browser.switch_to_alert().accept() #取消二选一 browser.switch_to_alert().dismiss()
提示弹窗
这个通常用来处理用户信息交互的场景,用户可以通过弹窗输入一些文字信息,来传递与进行后续的业务处理。
from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By
browser = webdriver.Chrome() browser.get('https://www.xxxx.com') browser.find_element(By.ID, 'btn_info_inquiry').click() sleep(1) # 这里传递信息到提示弹窗,警告与确认两类弹窗不可使用,会报错 browser.switch_to_alert().send_keys('20100909')
既然是web自动化测试,那我们又怎么能少了Cookie的相关操作呢?用户的状态和业务请求都的需要用他来进行鉴权。在selenium中对Cookie进行操作其实也很简单,首先我们需要手动的登录被测网站一次,待网站Cookie存入本地后即可使用Selenium自带的函数对齐进行业务操作。
首先我们获取对应网站的Cookie值
import json from selenium import webdriver
browser = webdriver.Chrome() browser.get('https://www.baidu.com') # 写入保存为文件还是直接打印至控制台,各取所需 with open('cookies.txt', 'w') as f: f.write(json.dumps(browser.get_cookies())) cookies = browser.get_cookies() print(cookies)
接下来我们简单的对获得的Cookie进行处理
# 删除所有的cookies browser.delete_all_cookies() # 循环打印cookie中的name和value for c in cookies: # 查看打印出的cookie对应的键值对 print("%s : %s" % (c['name'], c['value'])) # 根据自己的业务需求进行cookie的增删改 cookie = {"name": "xxxx", "value": "xxxx"} # 最后添加即可 driver.add_cookie(cookie)
Selenium也为我们提供了可执行js脚本相关的函数,他们的作用是在某些页面中模拟一些业务动作(画面滑动,选择日期等)。在一些仅靠webdriver无法实现的业务场景中,我们就可以依靠此函数来辅助测试目的的达成。
js的查找元素方法(ID)
document.getElementById("id")
js的查找元素方法(name)
document.getElementsByName('name')
js的查找元素方法(class)
document.getElementsByClassName("class_name")
js的查找元素方法(tag)
document.getElementsByTagName('tag_name')
js的查找元素方法(css)
document.querySelector("css selector")
js的查找元素方法(css_list)
document.querySelectorAll("css selector")
execute_script()
从上可以看出其实js的定位元素方法和selenium中的差不多,接下来我们就可以将需要执行的js语句放入到执行函数中使用。
from selenium import webdriver
browser = webdriver.Chrome() browser.get('https://www.baidu.com') # 定位后修改指定元素的value属性 js_script_exec = 'document.getElementById("form_motion").value="list_modify";' browser.execute_script(js_script_exec)
对于某些动态div标签(窗口),一般的方法不太奏效的情况下,可以尝试下switch_to_default_content()方法,跳转到最外层;
使用模拟键鼠操作的时候,无论是单独使用还是链式写法,记得在结尾加上perform()方法进行执行;
如果元素定位时报错element click intercepted,记得检查界面上是否有其他元素进行覆盖,元素有可能也是具有隐藏属性的;
元素过期报错element is not attached to the page document,可以尝试重新刷新页面,这里不推荐直接使用refresh方法,还是养成好习惯先怼上try…except…捕捉到异常后在进行刷新或重置操作;
对于属性值为动态的元素,墙裂推荐使用CSS selector或者xpath方法来进行元素定位,正则表达式也推荐大家最好能掌握;
如果前期对xpath的相对路径写法比较头疼,推荐使用F12调试工具自带的元素复制功能,在你想要复制的元素所在的标签对这行右键,选择copy —— Copy XPath选项即可;
输入框默认存在内容想要删除再输入信息的话,不推荐模拟键盘操作Ctrl+A,然后模拟退格键,试试clear()方法吧;
抓不到元素可以使用延时方法,输入文字也是一样的道理,业务场景中需要大量输入文字的,无论是从文件中还是提取又或者是遍历,出现少字漏字的话,同样也可以使用延时的方法,适当的放慢处理的速度;
在页面中总会有些不可见的元素,这种情况使用is_displayed()方法即可快速定位找到;
有些被测页面需要验证码,无论是手机的还是图片验证,和开发同学沟通一下,留个万能的就行了,其本身的功能手工回归一下即可,不必太过纠结;
三方登录功能也是如此,不推荐直接使用web自动化去搞,三方的一般是不开源的,有这折腾的时间还不如跑跑接口和黑盒,自动化的话绕过去即可;
自动化测试用例这块的话博主还是推荐不要有依赖,和功能测试用例同理,每次的执行顺序或者数量都会根据需求与业务场景发生变化,一旦依赖了会大大增加测试同学的维护成本,后面有空我会单独出一期自动化测试用例的文章来为大家介绍。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
目录
搞明白前端开发人员在企业中的占比,你才可以在学校或者即将毕业的时候选择出自己将要深入学习的开发语言。很多学校既要教C语言,又教单片机,既教java,也教前端开发知识,但老师的课是有限的,给留了作业,也许都不检查,下一课老师就要继续往下讲,因为这是他的工作,老师们也有生活,不可能围着某些人转,学不会就不往下开课了。
而搞懂前端开发在企业中的占比呢,能够更好的让你觉得如果自己比较平凡,得到什么等级可以卷得过别人,可以在这么多职位中占有一席之地。
很可喜的是,目前传统行业已经信息化改造完成,不管他们是内部系统,或者外部联合系统,都需要前端开发;我们每天看见大街上跑的汽车企业,某些电子企业,手机厂商,都需要前端开发的职位;更别提电商,直播这些我们生活所不可缺少的行业。但你还需要知道的是,如果你想学的一门服务端语言,java phython .net 或者其他,很可能这家公司就不会用,无形中给自己减少了很多工作机会。
以上的图,是从过去几年一直到今年(2022)年的各大公司的占比,毕竟是大厂嘛,对用户体验,前端接触到浏览器,最接近用户的要求肯定会高一些。
但是通过对多家中小公司的逐步了解发现,出去UI , 项目,产品,DBA, 运维等职位外,服务端开发与前端开发的比例几乎是1:1 ,甚至有的外包性质的公司,他们一旦产品成型后,新的客户换皮肤,更换界面的需求会更多,所以前端开发会需求更多一些。
此前有人戏称,是开发语言受欢迎,并非你受欢迎。但不得不说,某个开发语言受欢迎程度如果更加靠前,说明市场需求更大,更受欢迎,而将来准备从事某一种开发语言,也是非常关键的信息来源。
通过以上往年到今年的开发语言受欢迎程度发现,javascript这门前端必备的开发语言名列前茅,甚至在众多服务端开发语言中也不甘示弱,当然这之中并没有表明HTML CSS是一门开发语言,如果是的话,HTML CSS 也必将榜上有名,因为各行各业都不要网页对外公式自己的产品,但服务端开发语言五花八门,而前端必备javascript。
从web1.0时代,页面简单的只读时代,到web2.0时代,不断的交互,前端开发这个职位也在不断的进步。那么在未来的web3.0时代,很多人疑惑,可能PC的网页用处会越来越少,甚至不客气的说H5的页面也会少很多,据推测APP也会减少,未来将会有更多的数据整合产品出现。那么未来前端还会大有可为吗?
答案是肯定的,伟大的《红宝书》开头便说:javascript能做所有的事情,如果他能。而且nodejs的流行,也使前端可以更多的渗透到服务端开发,flutter的最新发布,WPA的使用,也使APP得到了更大的挑战,CSS3的不断进步,前端游戏引擎的盛行,也使前端有了更大的发展前景与选择,那么即便未来的元宇宙世界,相信前端javascript也一定能够勇往直前
如果这只是当下技术领域的一个缩影,可见比较活跃的的开发语言有java phython c mysql 然后才是javascript。从开发开发技术职位区分还是服务端和前端,但前端活跃度却比较靠后,不管是提问,回答,数量等维度上
说明什么问题呢?从事前端开发人数少吗?前端开发在学习,工作中没有问题吗?前端开发比较懒惰,不愿意上社区来参与活动吗?
我们知道nodejs可以做服务端开发,但是有多少企业敢于让从开始就搭上node serve的架子,不断让前端同学去尝试,不断在node领域发光发热,为整个行业添砖加瓦呢,很少吧。而几乎大部分公司,还是比较守旧的,从最开始的jSP时代,甚至不需要前端,服务端写完服务端代码,然后开始写JSP。JSP里再套java代码,顺带着添加一些javascript事件,样式怎么办,那个时候extjs jquery还非常盛行,easyui jqueryui 等,可以让服务端开发人员快速生产页面。
但随着提升用户体验的欲望越来越强烈,《国富论》开篇也讲分工带来的好处,前端才逐渐有了一席之地,甚至在一些大公司,前端的话语权可以超越服务端,他们通过技术驱动业务向前。
按照比例学可知,一旦某些事物达到一个数量后,某些细节世界也可以大体展现整体的宏观判断。那么我的理解是,在众多开发语言中,尽管javascript那么受欢迎,目前企业中前端占比还算不错,但总的来说,跟其他服务端开发语言总和来比,前端人员还是少。如果服务端语言像前端一样仅有javascript的话,我相信csdn问答模块这个业界缩影将不会是这种状态,甚至会大有不同。
其实很多老师,很多培训机构的老师教前端,大家各有各自的工作,各有各自的生活, 他知道来了一批学生,这是自己分内的工作,其实很多学生也只是停留在前端开发做网页的意识上,未来我想找到一份共走,可以养活自己。这无可厚非
其实日产工作还真就是做网页,做了C端做B端,做了PC做H5,嵌套到webview里,嵌套的APP的壳子里,这些都是工作。
小程序,各种各样的小程序;各种手机屏幕尺寸的适配;各种APP内部的嵌套;
做完了前端,开发点node层的工作吧,卷一卷,棒服务端同学减轻点工作压力;
再来点代码优化吧,如果将自己的代码调的代码量更少,如何不写注释也可以清晰明了,如何不得不写注释,可以写的更清楚;
来一点性能优化吧,现在出去面试,没做过性能优化都不好意思说自己做过工作。没办法,整体的需求缠身,但你却很少从中吸取知识,日复一日,到找工作那天发现,自己做的工作,其实都是劳动力。如何驱动自己,再寻求解决方案,再将性能指标不断提升。
卷一卷,读书破万卷。将自己的点子,自己的做法不断形成方法论,对内输出,乃至对外输出,提升影响力。
还要啥理想,向公共组件团队渗透,向技术栈所在团队渗透?
小插曲:这里加一个小插曲,promise解决了什么问题?这道题是不是必考题,千篇一律的答案是什么?解决了回调地狱?异步的工作我们当同步的来执行?
这算不算进步?这算不算创新?那么我就问问你,有回调地狱你的项目跑步起来了?用同步的写法来搞异步的事情降本增效了?
那么我就问问你,是你把之前的写法用上现在的promise节省的时间多,还是你每天摸鱼的时间多。说白了异步是一个需要花费时间的事情,因为有了异步,有了时间差,才使我们的工作出现了更多的可能性,不确定性。你更应该解决的是不是这个问题。
个人观点啊,没说promise不好,挺好的。
不管是在校或者迷茫的即将离校,一旦决定要学,不管是学哪种开发语言,都要坚定信心,切记不可三天打鱼,两天晒网;
这要看个人家庭的生活水平,一个家庭攻读出一个大学生实属不易,毕业后念培训班需要一定的资本支持。但对于很多人来说,没有学习方向,念培训班也是个选择,至少可以入个门;但大部分的培训课程对于目前的就业形势掌握不足,就像杨过刚去钟南山一样,练不够基本功,词汇一大堆,实战没多少,最后说啥名词都是666,一干活就挠头;
其实我根据自己的经验,也在筹备规划一套更卷,更适合入门到守门再到卸门的课程,我的目标就是更实用,更卷,更有助于大多数想学习的同学们,你需要的只是一句:我想学习,我要学习,我能学习,而不是马内。
现在网络上文章多的是,虽然很多不够系统,但正好够大家巩固当日知识点所用。学一定要用,用后一定要巩固,巩固后一定要举一反三形成自己的知识点,方法论,记录个博客啦,笔记啦,分享到身边的人,这样足可巩固无忧
知识点掌握的好不叫好,可以把知识点贯穿起来,做出一个市面上的东西,这算超越自我,切记不可自满,学完知识点就说自己精通,那只会在面试或者在工作的时候让自己更加烦恼,掉头发,熬夜。
做为初级开发,最重要的就是对于解决问题,有自己的一套手段,这样至少可以保证快速的完成需求。但如果想继续往上走,必须得有一些别人所没有的东西。这里说到举一反三,记得当时学习的时候,学完js基础需要写一个99乘法表,当时本来上课就少,硬生生把js的嵌套循环99乘法表写出来。晚上睡觉的时候想,如果纯用HTML CSS 是不是也能写出来,就这样,HTML的倒是好写,但CSS的又憋了很久,总算是写出来了。你就说,这样下去,谁能有我卷。现在我总结出了怎么利用纯HTML CSS JS 写出3版99乘法表,并且总结出了自己的文章,希望可以让初学者能够更快的入门。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
Web 开发是指在互联网上创建网站或 Web 应用程序。它涉及一系列任务,从开发网站的整体结构和设计到编写使网站栩栩如生的代码。Web 开发可能是一个复杂的过程,它通常涉及使用各种不同的技术,包括 HTML、CSS 和 JavaScript,以及服务器端语言,如 PHP、Ruby、Nodejs 和 Python。Web 开发人员可能在前端工作网站的一部分,这是用户与之交互的部分,或者在后端,这是处理网站幕后功能的部分。Web 开发是一个快速发展的领域,Web 开发人员需要跟上最新的技术和最佳实践,才能创建有效且引人入胜的网站和 Web 应用程序。
可以肯定地说,Web 开发将继续是一个重要且充满活力的领域。随着 Internet 的不断发展和演变,对 Web 开发人员的需求也可能会增加。Web 开发中使用的技术和工具也将继续发展和改进,这将使 Web 开发人员能够创建更先进、更复杂的网站和应用程序。此外,人工智能、虚拟现实和增强现实以及物联网等新技术的兴起可能会为网络开发人员带来新的机遇和挑战。Web 开发的未来看起来一片光明,对于那些对技术充满热情的人来说,它将继续是一个令人兴奋和有益的领域。
Web 开发是一个快速发展和动态的领域,由于 Web 应用程序开发的复杂性和多样性不断增加,因此对 Web 开发人员的需求量很大。
Web 开发人员有什么好的工作机会吗?答案是肯定的。互联网改变了我们的生活方式。如果您想加入一个令人兴奋的新行业来开发新技术,我们建议您这样做并成为一名网络开发人员。该技术不仅“防 covid”,而且相对抗衰退。
人们每天都越来越多地参与网络,并使用他们的智能手机和平板电脑访问互联网,因此对于网络开发人员来说,创建针对这些智能设备优化的网站和网络应用程序非常重要。
对于网站和应用程序而言,提供用户会喜欢的令人难忘的用户体验将变得更加重要。具有提供引人入胜的用户体验天赋的开发人员应该研究这些趋势带来的机会。
总之,每项 Web 技术的背后都有一支经验丰富、才华横溢的开发人员团队,他们负责更新、开发和维护它。技术每天都在发展,因此有才华的 Web 开发人员始终可用并存在非常重要。
网页开发和网页设计是两个经常混淆的独立领域。虽然它们是相关的,但它们是具有不同重点和目标的不同学科。
网页设计侧重于网站的美学和功能方面,涉及用户界面和用户体验的规划和创建。网页设计师负责网站的布局、配色方案和整体外观,以及网站的导航和用户流程。
另一方面,Web 开发侧重于构建网站的技术方面。这包括编写代码来创建网站的各种组件,例如前端和后端,并将它们集成以创建功能强大且可用的网站。Web 开发人员负责网站的实施和维护,并且可能会使用各种编程技能和框架来实现。
Web 开发人员是专门开发可通过 Web 浏览器访问 Internet 的应用程序和服务的程序员。Web 开发人员使用各种技术和语言(例如 HTML、CSS 和 JavaScript)来创建网站或 Web 应用程序的结构、布局和设计。
Web 开发人员负责构建和维护 Web 应用程序的各种组件,包括用户界面、服务器端逻辑和数据库。他们还可能负责将 Web 应用程序与其他系统和 API 集成,并负责实现增强用户体验的特性和功能。
总之,网页设计关注网站的视觉和面向用户的方面,而网页开发则关注网站的技术实现和功能。
前端开发人员是专门从事 Web 开发客户端的 Web 开发人员。他们负责构建和维护 Web 应用程序的用户界面和用户体验,包括布局、设计和交互性。
前端开发人员通常精通前端技术和语言,例如 HTML、CSS 和 JavaScript。他们负责实施 Web 应用程序的视觉设计,包括布局、排版和配色方案。他们还可能负责实现交互元素,例如按钮、表单和菜单,以及将 Web 应用程序与后端系统和 API 集成。
除了技术技能,前端开发人员还需要对用户体验和设计原则有深刻的理解。他们应该能够创建直观、用户友好且美观的 Web 应用程序。
前端开发是 Web 开发的重要组成部分,前端开发人员在创建 Web 应用程序的外观方面发挥着关键作用。
后端开发人员是专门从事 Web 开发服务器端的 Web 开发人员。他们负责构建和维护 Web 应用程序的底层逻辑和基础设施,包括服务器端逻辑、数据库和 API。
后端开发人员通常具有服务器端语言和技术方面的专业知识,例如 PHP、Python、Ruby 和 Node.js。他们负责实现 Web 应用程序的服务器端逻辑,包括业务规则、数据验证和用户身份验证。他们还可能负责设计和实施数据库模式,以及将 Web 应用程序与其他系统和 API 集成。
除了技术技能,后端开发人员还需要具备强大的问题解决、沟通和协作能力。他们应该能够批判性和逻辑性地思考,并能够设计和实施可扩展、可维护且高效的解决方案。
后端开发是 Web 开发的重要组成部分,后端开发人员在构建和维护 Web 应用程序的功能和性能方面发挥着关键作用。
全栈开发人员是在前端和后端开发方面都具有专业知识的 Web 开发人员。他们负责构建和维护整个 Web 应用程序,从用户界面和用户体验到底层服务器端逻辑和数据库。
全栈开发人员通常对用于构建 Web 应用程序的技术和语言有深入的了解,包括 HTML、CSS、JavaScript 和服务器端语言(如 PHP、Python 和 Ruby)。他们能够处理 Web 应用程序的所有层,从用户界面和用户体验到数据库和服务器端逻辑。
除了技术技能,全栈开发人员还需要具备强大的问题解决、沟通和协作能力。他们应该能够创造性和批判性地思考,并能够适应不断变化的技术和要求。
全栈开发是一个充满挑战和回报的领域,由于 Web 应用程序的复杂性和多样性不断增加,对全栈开发人员的需求量很大。
网站管理员负责构建、维护和更新网站。他们还可能负责将网站与其他系统或云服务集成,例如数据库和内容管理系统 (CMS),以及实施增强用户体验的特性和功能。
网站管理员通常与开发团队的其他成员(包括图形设计师、内容创建者和项目经理)密切合作,以创建和维护满足企业或组织需求的网站。他们还可以与客户合作以了解他们的要求并提供满足他们需求的解决方案。
如果你是 Web 开发的新手并且想知道从哪里开始以及第一步是什么,这里有一些建议:
学习 HTML 和 CSS 等 Web 开发基础知识——这些是 Web 的核心技术,良好的这些语言基础对于任何 Web 开发人员来说都是必不可少的。您可以从学习 HTML 和 CSS 的基础知识开始,例如网页的结构、如何添加内容和样式以及如何创建简单的静态网页。
选择开发环境——开发环境是一组用于构建和测试 Web 应用程序的工具和资源。这通常包括用于编写代码的文本编辑器或集成开发环境 (IDE)、用于测试网页的 Web 浏览器以及用于运行 Web 应用程序的本地 Web 服务器。带有大量插件的 vscode 编辑器肯定需要引起您的注意。
构建一个简单的网页——学习了 HTML 和 CSS 的基础知识后,尝试构建一个包含一些文本、图像和基本样式的简单网页。这将使您有机会练习所学的技能,并了解不同技术如何协同工作。然后更进一步,开始复制一些最流行的网络应用程序,然后 memic 尝试重新创建它,我指的只是这里的设计。
探索 Web 开发框架和库– 有许多可用的 Web 开发框架和库可以更轻松地构建 Web 应用程序。一些流行的选项包括 React、Angular、Vue.js 和 Django。一旦你确定了一个框架,立即开始学习它并坚持下去直到你掌握它。
HTML或超文本标记语言是一种用于创建和构建网页内容的编程语言。HTML使用一系列元素或标签来定义网页的结构和布局,包括标题、段落、列表和链接。HTML 还允许开发人员向网页添加图像、视频和其他多媒体内容,使其成为构建 Web 应用程序的强大且通用的语言。
定义带有标题、段落和图像的简单网页的 HTML 代码:
<!DOCTYPE html> <html> <head> <title>我的 Web 页面</title> </head> <body> <h1>Hello, World!</h1> <p>这是我的第一个 Web 页面</p> <img src="https://www.example.com/image.jpg" alt="A beautiful landscape"> </body> </html>
在此示例中,<html>
和<body>
标签定义了网页的结构,而<h1>
、<p>
和<img>
标签定义了页面的内容。<img>
标签的src属性指定要显示的图像的 URL,而alt
属性为无法看到图像的用户提供图像的文本描述。所以你需要了解 HTML 标签和它们的属性。
CSS或层叠样式表是一种样式表语言,用于描述以标记语言编写的文档的外观和格式。在 Web 开发环境中,CSS 用于控制以 HTML 或其他标记语言编写的网页的外观和布局。CSS 允许开发人员为网页上的内容定义颜色、字体、大小和其他样式,使其成为构建现代响应式 Web 应用程序的重要组成部分。
可用于设置上述网页内容样式的 CSS 代码:
body { font-family: Arial, sans-serif; background-color: #f1f1f1; } h1 { color: #333; text-align: center; margin: 30px 0; } p { color: #777; font-size: 18px; line-height: 1.5; padding: 0 20px; } img { width: 100%; height: auto; }
![]()
在此示例中,body选择器将样式应用于网页的<body>
元素, h1选择器将样式应用于所有<h1>
元素,p和img选择器将样式应用于所有<p>
和<img>
元素, 分别。此 CSS 代码中定义的样式指定页面及其元素的字体系列、背景颜色、文本对齐方式和其他属性。显示此示例演示了选择 HTML 元素的重要性以及需要使用哪些属性来设置它的样式。因此,了解所有类型的选择器以及它们需要的属性。
你可以使用 CSS 框架让您的生活更轻松。最受欢迎的是Bootstrap和Tailwind CSS,它们都是用于构建响应式、移动优先的 Web 应用程序的前端框架。这两个框架都提供了一组预定义的 CSS 类和组件,可以轻松地将它们合并到网页中,以创建一致的、具有专业外观的设计。Bootstrap 和 Tailwind CSS 是构建现代响应式 Web 应用程序的强大工具。这两个框架之间的选择将取决于您的个人喜好和项目的具体需求。
有许多不同的框架可用于 Web 开发,每个框架的流行程度取决于项目的具体需求以及开发人员、团队或公司的偏好。一些最流行的 Web 开发框架包括:
React: React 是用于构建用户界面的最多的javascript 框架之一。 许多公司都在使用它,并且拥有庞大的开发人员社区。
Angular: Angular 是一个基于 TypeScript 的开源 Web 应用程序框架,由 Google 的 Angular 团队以及个人和公司社区领导。
Vue.js: Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它旨在逐步采用并可以集成到现有项目中。
Ember.js: Ember.js 是一个用于构建大型 Web 应用程序的开源 JavaScript Web 框架。它以其约定优于配置方法和强调开发人员生产力而闻名。
以下编程语言列表可帮助您了解在成为 Web 开发人员的过程中您想要学习和追求的语言。大多数时候,选择将取决于您选择的框架或其他方式:
JavaScript——让我们从显而易见的最流行的 Web 开发编程语言开始,它是 JavaScript,它是一种用于构建前端 Web 应用程序的通用语言。它是一种客户端语言,这意味着它在用户的网络浏览器中运行,并允许开发人员创建交互式和动态网页。JavaScript 还通过 Node.js 等技术用于服务器端开发,它允许开发人员构建可扩展的高性能 Web 应用程序。
Python – Python 是一种高级解释型编程语言,广泛用于 Web 开发。它具有简单易学的语法,是初学者的绝佳选择。Python 还以其强大的库和框架而闻名,例如 Flask 和 Django,这使得快速构建复杂的 Web 应用程序变得容易。
Java – Java 是一种流行的面向对象的编程语言,广泛用于构建可扩展的高性能 Web 应用程序。它是一种通用语言,可用于为各种平台(包括桌面、移动和 Web)构建 Web 应用程序。
Ruby – Ruby 是一种高级解释型编程语言,通常用于 Web 开发。它以简单和优雅着称,使其成为想要快速轻松地构建 Web 应用程序的开发人员的热门选择。
PHP – PHP 是一种流行的脚本语言,广泛用于构建动态网站和 Web 应用程序。它是一种服务器端语言,这意味着它在网络服务器上运行并生成发送到用户网络浏览器的 HTML 页面。
C# – C# 是一种流行的面向对象的编程语言,通常用于构建 Web 应用程序。它是一种通用语言,可用于为各种平台(包括桌面、移动和 Web)构建 Web 应用程序。
Swift – Swift 是一种现代的编译型编程语言,通常用于构建 Web 应用程序。它是一种功能强大的语言,以其安全性和性能着称,使其成为构建需要处理大量数据或执行复杂计算的 Web 应用程序的绝佳选择。
Go – Go 是一种现代的编译型编程语言,通常用于构建 Web 应用程序。它是一种快速、高效的语言,以并发性和可扩展性着称,使其成为构建需要处理大量流量或数据的 Web 应用程序的绝佳选择。
TypeScript – TypeScript 是一种流行的类型化编程语言,通常用于构建大型、复杂的 Web 应用程序。它是 JavaScript 的超集,这意味着它包含 JavaScript 的所有功能,以及可以更轻松地构建大型、可维护的 Web 应用程序的附加功能。
Kotlin – Kotlin 是一种现代的编译型编程语言,通常用于构建 Web 应用程序。它是一种简洁、强大的语言,以其安全性和与 Java 的互操作性而著称,使其成为构建需要与现有 Java 代码集成的 Web 应用程序的绝佳选择。
追求网络开发职业道路可能是一个不错的选择,原因有很多。Web 开发职业的一些好处包括:
对 Web 开发人员的高需求:对 Web 开发人员的需求一直很高,并且预计在未来几年将继续增长。这意味着那些拥有技能和经验的人将有很多机会在这个领域取得成功。
高薪: Web 开发人员的薪水很高,薪水因经验、地点和其他因素而异。总的来说,Web 开发人员可以期望获得丰厚的薪水,并且成长和进步的潜力很大。
灵活性: Web 开发可以在工作地点和日程安排方面提供很大的灵活性。许多 Web 开发人员远程工作,并且能够设置自己的时间并按照灵活的时间表工作。
学习和成长的机会: Web 开发是一个不断变化的领域,新技术和工具不断涌现。这意味着作为 Web 开发人员,始终有学习和成长的机会,并保持在行业的前沿。
创造有形事物的满足感:作为一名 Web 开发人员,您将有机会创造有形且有用的事物。这可以令人难以置信地满足,并且可以为您的工作提供成就感和自豪感。
Web 开发的未来看起来一片光明,许多激动人心的发展和趋势即将出现。一些可能影响 Web 开发未来的最新 Web 开发趋势包括:
人工智能和机器学习的兴起:人工智能和机器学习在网络开发中变得越来越重要,出现了许多新的工具和框架来帮助开发人员构建人工智能驱动的应用程序。
物联网的发展:物联网 (IoT) 是一个由可以收集和共享数据的连接设备组成的网络,预计在未来几年将显着增长。这将为网络开发人员创造新的机会来构建可以连接这些设备并与之交互的应用程序。
移动设备的重要性日益增加:随着越来越多的人使用智能手机和其他移动设备访问网络,网络开发人员创建适合移动设备的应用程序和网站将变得越来越重要。
渐进式 Web 应用程序的兴起:渐进式 Web 应用程序 (PWA) 是外观和感觉都像本机移动应用程序的 Web 应用程序,并且有望在未来变得更加流行。这将为 Web 开发人员创造新的机会来构建可跨不同设备和平台提供无缝用户体验的 PWA。
云计算的发展:云计算在网络开发中变得越来越重要,许多公司将他们的应用程序和数据转移到云中。这将为 Web 开发人员创造新的机会来构建云原生应用程序并将它们与现有的云服务集成。
Web 开发仍然值得学习,因为它是构建和维护作为现代 Internet 支柱的网站和 Web 应用程序的基本技能。随着世界变得越来越紧密,对 Web 开发人员的需求不断增长,对于那些拥有构建和维护未来 Web 应用程序的技能和专业知识的人来说,有许多激动人心的机会。
Web 开发也是一个回报丰厚且具有挑战性的领域,它允许开发人员利用他们的创造力和解决问题的技能来构建供全球数百万人使用的应用程序。有了合适的工具和资源,任何人都可以学习 Web 开发并开始构建自己的 Web 应用程序,从而打开一个充满可能性和机遇的世界。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
Vuex 和 Pinia 是用于管理 Vue.js 应用程序状态的标准 Vue.js 库。让我们比较一下他们的代码、语言、功能和社区支持。
如果没有合适的库,开发人员管理应用程序的状态可能会很困难。Vuex 和 Pinia 是标准的 Vue.js 库,用于处理应用程序中的条件。这两个库都非常适合状态管理,但是由于它们出色的特性和功能,选择哪个库用于你的项目需要时间并且令人沮丧。好吧,我们将在本文中看看为什么一个是最好的。
在本文中,我们将通过实际代码示例查看代码比较、它们的变体、功能,以及推荐使用哪一个来管理你的状态应用程序,以便更好地理解。我们还将考虑每个产品的语言、功能和社区支持。
我将简要总结 Vuex 和 Pinia。如果你想要更详尽的解释,我建议阅读Vuex 文档和Pinia 文档。
Pinia是一个新的状态管理库,可帮助你在 Vue.js 应用程序中跨组件管理和存储响应数据和状态。Pinia 由 Vue 核心团队成员之一 Eduardo San Martin Morote 创建。
Pinia 使用新的反应系统来构建一个直观且完全类型化的状态管理系统。
库中引入的新特性是促成 Pinia 推荐的因素之一。总体而言,Pinia 显得轻巧、简单且易于掌握。它拥有可以使 Vue 3 和 Vue 2 中的编程变得通用的一切。因此,这是试用 Pinia 的理想机会。
Vuex是一种状态管理模式和库,构建为集中式存储,可帮助你维护 Vue 应用程序中存在的所有组件的状态。Vuex 遵循确保你的状态突变为预测标准的规则。
使 Vuex 更强大的一个因素是组件从 Vuex store 中获取它们的状态,并且可以快速有效地响应 store 状态的变化。
Vuex虽然是维护你store的状态管理库,但建议你熟悉或搭建过大型SPA。如果你没有经验,Vuex 可能会冗长且令人生畏。
如果你的应用程序很广泛,你需要管理复杂的数据流,并且你有嵌套的组件,你可以使用 Vuex。查看官方文档以获取有关何时使用 Vuex 的更多信息。
Pinia 和 Vuex 之间的区别之一是 Pinia 是“模块化设计”,换句话说,它被构建为拥有多个商店,而 Vuex 只有一个商店。在这些商店中,您可以拥有子模块。除此之外,Pinia 允许将这些模块中的每一个从他们的商店直接导入到需要的组件中。
如果您是一名 Vue 开发人员并且曾使用 Vuex 管理应用程序的状态,您会注意到 Vuex 只有一个商店。在该商店中,您可以在其中包含多个模块。使用 Pinia,您可以将这些模块中的每一个都存储在一个地方,并在需要时将它们直接导入到组件中。
此方法允许捆绑器自动对它们进行代码拆分,并提供更好的 TypeScript 推理。
Pinia 提供开发工具支持,以帮助您使用该库构建和轻松调试。当我们安装 Pinia 时,它会自动挂接到我们的 Vue.js 开发工具,并让我们跟踪对我们的商店所做的更改,这让我们在 Vue.js 版本(Vue 2 和 Vue3)中获得流畅的开发人员体验。
Pinia 提供了一个简单的 API,使您的商店的编写变得简单且井井有条,就像创建组件一样。这意味着与 Vuex 解决方案相比,需要掌握的样板文件和概念更少。
Pinia 还提供了一个完整的插件系统,具有交易和本地存储同步等功能,适用于 Pinia 默认行为不足的情况。
Pinia 提供比 Vuex 更好的 TypeScript 支持,具有 Javascript 自动完成功能,这使得开发过程变得简单。
Pinia 的重量只有 1 KB,因此很容易融入您的项目。这可能会提高您的应用程序性能。
当您的应用程序扩展时,遍历变得很困难。但是,使用 Vuex 模块,您可以根据领域功能将您的商店拆分为多个文件,并从该特定命名空间中的模块访问状态循环。
Vue devtools 中的 Vuex 选项卡允许我们查看状态并跟踪我们的变化。这使我们能够快速评估我们的程序如何执行和调试错误。
Vuex支持热重载功能,它使用 webpack 的热模块替换 API,可以在您开发时快速重载您的 mutations、modules、action 和 getters。
如果你想编写一个 TypeScript 存储定义,Vuex 可以提供它的类型并且更容易实现。它有一个默认的 TypeScript 配置,不需要额外的设置。
Pinia 是一个轻量级库,可帮助您管理整个应用程序的反应状态。与 Vuex 相比,Pinia API 易于学习,使您的代码更易于阅读。
让我们看一下使用 Pinia 和 Vuex 管理我们的状态的代码比较:
Vuex
在此示例中,我们将查看一个简单的 Vuex 存储,它跟踪待办事项列表项的状态:
import { createStore } from 'vuex' const TodoListstore = createStore({ state() { return { todoListItems: [] } }, actions: { addNewList({ commit }, item) { { commit('createNewItem', item) } }, mutations: { createNewItem(state, item) { state.todoListItems.push(item) } } })
![]()
如果你看上面的代码,你可以看到 Vuex 存储中的三个动作:状态、 动作和突变。状态返回当前的todoListItems,动作提交一个突变来创建一个新项目,最后,突变创建新项目并将其添加到列表中。当你构建一个更大的应用程序时,你可能会意识到动作和突变相对相似,导致冗余代码,因为每个状态变化都需要一个样板。
Pinia
使用 Pinia 简单 API,您可以消除突变和冗余代码。让我们查看一个代码示例,了解当您使用 Pinia 实现之前的代码时的样子:
import { defineStore } from 'pinia' Export const useListStore = defineStore('list', { state() => ({ return { todoListItems: [] } }), actions: { addNewList() { this.todoListItems.push(item) } }})
上面的示例是 Pinia API 在管理应用程序状态时如何工作的简单代码。使用 Pinia,我们删除了突变并将其直接更新到我们的动作中。
注意:在上面的代码示例中,当我们将项目直接提交给我们的操作时,我们不需要跟踪我们的项目。
Pinia 和 Vuex 是控制应用程序状态的优秀工具,但其中一个必须具有另一个所没有的某些功能。让我们来看看它们是什么。
好吧,这就是它变得更具挑战性的地方,因为仍然有一些项目需要使用 Vuex 来处理状态应用程序,即使 Pinia 是新推荐的状态管理库。它有几个 Vuex 没有的有价值的功能。
Vuex 仍然是构建大型 SPA 的理想解决方案,因为对于构建中小型应用程序的人来说,它相当冗长。
Pinia 也一样。尽管如此,如果你需要所有列出的功能,例如 devtool 支持、TypeScript 支持和状态应用程序的轻松管理,那么 Pinia 是最好的解决方案——它为你提供流畅的开发体验。
如果你正在构建一个不太复杂的应用程序,无论是中等到广泛的应用程序,你都可以使用 Pinia,因为它的重量约为 1 KB。
由于功能多样,在管理应用程序状态时,在 Vuex 和 Pinia 之间进行选择可能会造成混淆。不过,这两个框架都非常适合管理状态应用程序。本文简要比较了它们的特性、功能和对代码的影响。读完这篇文章后,也许你将能够找到适合你的库。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
可视化图表是提升信息传递效率的一种有效方法,特别是在B端平台中经常遇到对统计的数据分析总结的呈现。我们设计师在设计图表的过程中,如果没有系统的可视化知识,会出现设计的图表虽然美观但图表不能很好的反应数据的情况。那么,在复杂的数据关系中如何设计和选用图表,如何在好看的同时提升信息传达效率,看完这篇文章希望对你的设计过程有所帮助。
// 为什么要数据可视化
数据可视化就是用图表来表示数据信息,它所传达的信息包括你所拿到的数据源和你分析后的结果,再通过图形强化用户的理解和记忆。能让用户简洁明了的获取更多的信息,是我们可视化的最终目的。
举个例子,同样一组数据,用表格的形式呈现是很难有所洞察的;如果将各个地区维度的数据聚合以柱图形式呈现,很容易就能看出各个地区间数据的差异,并从中洞察规律
关于如何设计好数据可视化图表,这边总结了三个步骤:选择适合的图表,强化视觉层次,图表响应式适配。
一、选择适合的图表
数据可视化的图表种类繁多,当我们真的开始作图,往往会遇到一个困境:有这么多类型,要如何选择正确的图表呢?首要依据是考虑所要传达的信息意图,即所要制作的图表它的任务是什么,再通过分析数据关系来选择表达方式;第二层意图是图表传达内容,这时候我们就需要根据数据的特征去突出和强化。
1. 分析数据关系
根据数据分析的方式来看,每一种图表都对应了一种数据关系。从数据的维度出发弄清呈现结构,再结合数据关系作出选择。了解图表的可能知道,一般图表的数据关系有构成、比较、分布,以商业数据为例,常见的还有流转关系。
构成关系
构成关系的图表表达的是部分和整体的关系,用于分析总体和各部分的占比比例,构成关系一般局部元素加起来为总数。如果只是想对比个别组成部分的大小,也可以使用比较关系的图表。
常用图表:饼/环图、堆叠图、面积图等,如涉及到层级结构,还会用矩形树图或旭日图等特殊结构图表。
关键词:“占比、比例、百分比”
比较关系
比较关系是基础分析中常用的一种图表类型。在一定的取值范围内,通过对两个或两个以上的指标分析,可以直观的看到变化和差距。对比分析包括趋势对比和分类对比两种形式,趋势对比用于表示一段时间内数据的变化,分类对比用于比较数据规模。
常用图表:趋势对比常用图表有折线图、散点图等;分类对比常用条形图、柱状图、气泡图等。
关键词:“增减、升降、涨跌、波动”
分布关系
利用空间分区来展示数据之间的分布关系,常用于体现两个或以上数据的相关性。
常用图表:散点图、热力图、雷达图等
关键词:“随着……而变化、A/B之间的相关性、交/并集”等
关联与流转
流转关系是B端数据常用的一种关系,它可以动态的体现相关路径下对象之间的关系、状态、数据量的流转变化等,以面积或颜色深浅展示了多个状态或对象之间的流动量或流动强度。
常用图表:关系图、桑基图、漏斗图、进度图等
关键词:“流程步骤、留存、转化、关系”
2. 分析数据特征
按数据关系和分析目的选择好图表类型后,第二步是根据数据特征选择更加适合的展示方式。从数据分析的角度常见数据特征有:变量特征、维度特征、层级特征、流程特征。
变量特征
分辨一个指标通常有两类特征,按变量值是否连续可分为连续数据与离散数据两种。连续数据通常会统计一组数据的变化趋势,离散数据通常统计各分类下数量的变化。
维度特征
多维度分析需要将多个变量在同一平面上直观的表示,可以选择使用极坐标系去展示多个维度变量。如果希望对比多组数据,可使用不同颜色进行分类
层级特征
多层级数据由多个部分构成一个整体,又称树形结构数据。除了用结构树图表表现以外,还可以考虑以下两种图表类型:
例如:上图显示了市场销售额的来源结构。长方形的大小取决于各国家的平均销售额,通过色调来区分不同类型,颜色的深浅代表分类下的子集,面积体现销售占比。对比一般结构树图表,它的优势在于可以有效利用空间。
流程特征
流转关系是表达数据转化流程的重要类型,不仅包含统计意义上的数据总和,同时还表达了信息流转的路径;其中桑基图和漏斗图都可以表达路径中流量的变化,不同的是桑基图重点强调流量的强度和走向,漏斗图更加注重突出转化率和效果,根据不同的表达目的选用。
二、强化视觉层次
选择合适的图表后,在信息传达上也需要正确的表达,展示形式美观的同时能够清晰的体现数据特点。
1. 强化数据特性
使用图表正确的表达信息,需要设计师在强化数据特性的同时避免偏差
2. 色彩视觉传达
除了在设计构图上优化以外,颜色的选择也是图表重要的的信息表达元素。颜色会影响我们对数据的感知,错误的取色会让信息读取产生误解。我们可以通过不同的分析目的设置意图色板,精确传达信息同时后续的项目在选用时也可以达到用色的统一。
我们在之前的文章里有介绍过图表的取色模型,通过调整颜色HSL值的区间,可以得到以下三种意图色板:
那么我们要怎么样去使用这些色板呢?下面几个案例将带你了解其中的差异。
定性型:使用色调来进行分类
数据内在没有顺序差别时,建议使用色调值(H)进行区分;如定义国家、行业等类型。如果希望图表看起来更加专业,以下有几项分类色板的小建议:
定量型:使用深浅色板强调内在顺序
如果在同一个分类下包含子类别,或者数据本身具有排名属性,那么建议使用连续色板来突出他们内在的顺序,使图表更加易读。
三、图表中的响应式设计
B端图表可视化的数据一般是在网页或移动端上动态显示。不同于平面展示或汇报,在基础设计完成后还需要考虑到图表展示的环境,根据不同端去适配显示效果,以适应各种复杂情况。而动态显示带来的交互特性也让数据展示有了更多的可能性。
1. 布局框架适配
在网页端显示时,有时候同一个图表需要考虑不同容器下的适配方式。根据数据相关性变化元素的适应形态,将非必要的的元素转化或隐藏,保留重要的图形元素去适应当前空间;元素隐藏后使用悬浮交互来保证信息的展示,保持图表的可读性同时也避免产生元素的重叠。
如案例中的图表,在不同尺寸下通过改变和隐藏图表元素,以达到适配当前空间的效果。
2. 图表元素适配
要适配移动端,网页端横向延展的显示方式需要适应移动端纵向空间的显示。除了呈现角度的改变外,还需要考虑手机屏幕的尺寸和图表元素的适配性,去兼容相关的交互操作。
3. 极值适配
因B端平台的特性,我们无法预知客户传入的数据量,可能会遇到因数据量过多,造成图表显示不佳,数据读取困难等问题。这种情况下,提前考虑数据极限场景,通过交互的形式变化的方式让用户获取完整信息,提升理解同时信息展示更灵活。
还有悬浮放大、点击下钻、联动图表等交互行为可以组成更加丰富的图表。因篇幅原因,在这篇文章就不做深入讲解了,以后可独立介绍。
// 结语
数据可视化在B端设计场景中发挥着重要作用。设计师在表达数据之美的同时更加准确,才能更直观地向用户传达数据的价值。使业务人员能够从复杂的业务数据中快速、直接地找到重要数据,确保用户能够更好的接收信息,才是可视化的关键。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
随着B端体验设计的发展,表单类页面已经形成了一定的设计模式,例如登录页面,场景比较明确、业务流程和设计模式都比较成熟了。
业务型表单设计与业务强相关。既需要考虑交互带来的用户体验,又要从业务角度出发满足用户的行为需求,相对比较复杂。不过也形成了一些固定的设计方法。今天我们先来看看「精简」策略。
本文主要内容:
✦ 删除,实现表单轻量化
✦ 组织,让表单更加有层次
✦ 隐藏,让表单更加灵活
✦ 转移,扩展表单的异步空间
表单是系统与用户进行沟通的语言,它应当符合双方的认知逻辑。因此表单设计时,需要解决「产品」和「用户」2个方面的问题:
✦ 表单需要用户提供哪些信息,保证信息的正常流转和业务的完整
✦ 用户如何理解这些信息,如何更好地帮助用户完成表单填写
尤其是面对复杂表单,需要从这两方面寻找到突破口。
✦ 在业务层面,设计师需要探究用户的实际需求,反思表单项是否必要,从而减少不必要的选项,提高用户效率。
✦ 同时在设计层面,还需要基于用户认知习惯,通过合理的信息组织、交互形式帮助用户完成表单任务。
复杂表单通常包含多种业务场景,并且与其他业务存在关联和嵌套,导致表单内容信息量较大。我们需要通过「删除」、「组织」、「隐藏」、「转移」4个交互设计原则,让表单页面更加简单、有效。
前几年,我们在银行或者移动营业厅开通一些新业务时,都会填写表单,通常是密密麻麻一堆信息。但是实际需要填写的内容可能只有2~3项,业务人员会特意勾选出来给客户,其余的都是非必填项,或者是业务人员填写的。
线上表单设计时,没有专门的业务人员指导,用户更容易迷失。所以设计师或者产品经理的首要任务就是尽可能地减少表单信息量,降低用户的认知负荷。
最近在做一个表单的优化,业务方要求增加“入参”、“出参”两个表格项,说是用户会看。与用户沟通后,反馈也说“会看一下”。但是在深度挖掘用户场景后,发现用户确实会查看这个信息,只不过不是在当前环节查看,而是在结果项中查看。
所以我们最终去掉了这两个信息量较大的表格内容,从而让整个表单的信息量得到了明显的下降。因此面对复杂长表单,我们需要从需求入手,判断是否有必要让用户提供如此多的复杂信息。
当我们不得不面对复杂表单时,如果采用简单内容平铺,用户看到的是满屏的散点信息,造成信息识别困难,用户一时间难以找到填写思路,反而增加用户的心理负担。因此信息的层次性,对于复杂表单至关重要。
首先要从内容和视觉层面让复杂信息变得清晰、规整,更加符合用户的认知习惯。例如,可以利用分组标题、分割线、卡片,按照不同信息的类别、属性和相关性进行区块划分。
根据不同的布局和交互,主要有以下4种表单设计模式。
表单分组后,可以按照业务逻辑顺序铺开展示。用户只要按顺序填写就可以了。但是对于超长表单,这种布局方式下,用户无法全览页面信息。页面上下滚动、定位查找带来的交互成本比较高。
1)平铺表单
2)卡片表单
因此顺序表单更多地用在业务信息比较简单的场景中。
为了解决长表单的定位效率问题,可以在顺序表单的基础上增加锚点。另外锚点还可以帮助用户快速了解表单所包含的内容模块。
根据锚点的布局,可以分为横向锚点和纵向锚点两类。锚点需要吸顶方便用户操作。本质上来说,锚点表单是顺序表单的优化版本。
如果长表单内容没有依赖关系,还可以将表单拆分为几个相互独立的标签内容,这就是标签表单。
不过标签表单更强调内容的并列关系,常用于配置表单中,例如 MAC 或者 Windows 系统的配置弹窗。标签表单在全新表单中应用较少。
因为标签表单容易造成内容遗漏,并且无法告知用户哪些标签已经填写,哪些标签未填写,或者无法清晰地展示校验信息。来回切换标签查看信息,也会影响效率,因此主要用于用户有目的的配置行为中。
步骤表单是一种常见的表单拆分方式。通过节点将子表单串联起来,形成一个完整的业务闭环。例如阿里云的云服务器订单流程,或者一些开户流程等。
步骤表单有几个特点:
理论上来说,步骤表单有明显的操作顺序,用户需要按照节点完成内容填写,因此不会产生信息遗漏。当然也可以根据实际的业务场景,设置选填节点。但是总得来说,步骤表单更强调的是顺序操作。
对于复杂业务,步骤表单可以将分散在不同页面中的独立业务串联起来,在一定程度上具备新人教学功能,帮助用户了解业务逻辑。减少用户自定义操作时在不同页面的跳转,从而提供新人用户的操作效率。例如系统配置向导类的步骤表单。
由于步骤表单存在正向和逆向操作,因此设计时还需要考虑清楚逆向操作的设计逻辑。例如:
✦ 当用户想要修改前面步骤信息时,除了逐步返回,是否可以步骤条直接跨节点修改?
✦ 用户中途退出表单后,重启时是从第一步开始,还是直接从未填写的步骤开始呢?
✦ 用户如果完成了步骤条表单填写,想要二次修改时,是用普通表单,还是仍然使用步骤表单形式呢?
步骤表单可以分拆信息,化整为零。但是信息节点也不能过多,否则同样会影响用户的操作效率。所以要减少不必要的流程节点。
最近在做设计时,发现步骤表单最后一步是内容预览。通过用户调研发现,部分用户会谨慎地预览前面4步填写的内容。而另一部分用户则认为,刚填写了内容不需要预览,强制预览的设计并不友好。该如何平衡设计呢?
最终我们选择了将预览节点取消,将预览功能调整到第4步,采用「预览」按钮的形式。既满足了部分用户预览的需要,另一部分用户也可以不做预览,直接提交申请。
所以步骤表单过程中的节点具有一定的强制性,需要谨慎对待,保证节点的合理有效。
表单实际上是任务信息的集合,为了具有更高的适配性,内容通常是多种场景的集合。而场景有高频、低频区分,对于高频信息需要优先展示,便于提高用户的填写效率;对于低频场景,可以隐藏弱化展示,从而降低整个表单的复杂度。
例如我们常见的「高级配置」,通常在表单的底部默认收起展示。
复杂表单中信息会出现多级信息共存的场景。这种场景下,复杂表单默认展示当前选项对应的子内容,隐藏其他选项的内容,从而提高信息的指向性。
3、合理的组件形式
比较典型的就是单选和下拉选择器如何选择。有人为了强调效率,一味地追求单选按钮平铺展示,认为单选更加直观,用户不需要点击下拉滚动查看备选项。但是用户同样需要逐个浏览选择,反而增加了整个页面的信息量。
所以单选框更多用在备选项较少的场景,如果备选项较多,建议优先采用下拉选择器,隐藏备选项。
在表单设计时,可以将部分二级信息转移到弹窗、抽屉中,利用浮层空间拓展业务内容,根据用户操作逐级加载出来。从而减少表单的信息量。
例如下图中,没有将「所有配送区域及运费」直接展示出来供用户选择,而是放在了弹窗中,表单中只呈现最后的选择结果。既简化了表单的内容,又让选择结果更加突出,方便用户的查看和校验。
现在很多浏览器都增加了密码存储功能,减少用户记忆成本。而在电商购物网站可以设定默认的收货地址。系统自动读取调用,从而减少用户的输入操作。
现在越来越多的网站支持「手机短信验证码」免密注册登录方式,或者第三方登录方式,或者手机端扫码登录。将原有的表单填写转变为系统行为,从而降低用户的行为成本。
好了,以上就是我总结的表单设计的内容~
重复一遍:
✦ 删除,实现表单轻量化
✦ 组织,让表单更加有层次
✦ 隐藏,让表单更加灵活
✦ 转移,扩展表单的异步空间
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系。
作者:腾讯ISUX团队 来源:子牧先生
分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
本文转载至 : Mac解压压缩 rar文件
RAR 5.60 for Mac OS Xwww.rarlab.com
cd ~/Downloads/rar
sudo install -c -o $USER rar /usr/local/bin/
sudo install -c -o $USER unrar /usr/local/bin
1,解压命令
//解压到当前目录
unrar x a.rar //解压到指定目录
unrar x a.rar ~/Downloads //解压文件到当前目录
unrar e test.rar //查看rar中的文件
unrar l test.rar //更详细Ï
unrar v test.rar //测试是否可以成功解压
unrar t test.rar
2,压缩命令
// 将file文件压缩到text.rar
rar a text.rar file
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
我们会看到很多页面带有水印,但是怎么实现呢?当然可以有多种实现方式,本文主要讲解在vue项目中基于DOM或者Cavans实现水印效果,当然还有其他的实现方式,比如在原图片的基础上加上水印生成新的图片,但是这需要后端处理。因为要在vue项目中使用,所以我使用自定义指令可以直接对挂载的dom实现水印效果。
本文实现水印的项目环境为:vue + vite + ts
前面专门有一篇讲解vue2.x与vue3.x中自定义指令详解
将水印的指令放到标签上,设置标签的宽高。水印可以放大div
标签上,也可以是img
标签上。注意:img
才有onload
方法,div
标签么有。
<script setup lang="ts"> import { ref } from "vue"; </script> <template> <div class="index-content" > <div class="watermaker" v-watermark ></div> <!-- <img v-watermark style="width:400px;height:400px" src="../assets/vue.svg" alt=""> --> </div> </template> <style scoped> .watermaker { width: 400px; height: 400px; } .index-content{ width: 100%; height: 100%; } </style>
![]()
directives
文件
在directives
文件下创建waterMark.ts
文件,具体内容实现如下:
import waterImg from "@/assets/vue.svg" const directives: any = { mounted(el: HTMLElement) { //如果el元素是img,则可以用el.onload将下面包裹 const { clientWidth, clientHeight, parentElement } = el; console.log(parentElement, 'parentElement') const waterMark: HTMLElement = document.createElement('div'); const waterBg: HTMLElement = document.createElement('div'); //设置waterMark的class和style waterMark.className = `water-mark`; waterMark.setAttribute('style', ` display: inline-block; overflow: hidden; position: relative; width: ${clientWidth}px; height: ${clientHeight}px;`); // 创建waterBg的class和style waterBg.className = `water-mark-bg`;// 方便自定义展示结果 waterBg.setAttribute('style', ` position: absolute; pointer-events: none;`在这里插入代码片` transform: rotate(45deg); width: 100%; height: 100%; opacity: 0.2; background-image: url(${waterImg}); background-repeat: repeat; `); // 水印元素waterBg放到waterMark元素中 waterMark.appendChild(waterBg); //waterMark插入到el之前,即插入到绑定元素之前 parentElement?.insertBefore(waterMark, el); // 绑定元素移入到包裹水印的盒子 waterMark.appendChild(el); } } export default { name: 'watermark', directives }
![]()
directives
文件下创建 index.ts
文件
import type { App } from 'vue' import watermark from './waterMark' export default function installDirective(app: App) { app.directive(watermark.name, watermark.directives); }
main.ts
中全局引入
import { createApp } from 'vue' import App from './App.vue' import directives from './directives' const app = createApp(App); app.use(directives); app.mount('#app');
MutationObserver
对水印元素进行监听,删除时,我们再立即生成一个水印元素就可以了,具体方面在下面讲解。
position:relative
position:absolute
,实现这个水印元素覆盖到原始元素的上层,以实现水印的效果。
通过将图片绘制在cavans
中,然后通过cavans
的toDataURL
方法,将图片转为base64编码。
// 全局保存 canvas 和 div ,避免重复创建(单例模式) const globalCanvas = null; const globalWaterMark = null; // 获取 toDataURL 的结果 const getDataUrl = ( // font = "16px normal", // fillStyle = "rgba(180, 180, 180, 0.3)", // textAlign, // textBaseline, // text = "请勿外传", ) => { const rotate = -10; const canvas = globalCanvas || document.createElement("canvas"); const ctx = canvas.getContext("2d"); // 获取画布上下文 ctx.rotate((rotate * Math.PI) / 180); ctx.font = "16px normal"; ctx.fillStyle = "rgba(180, 180, 180, 0.3)"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; ctx.fillText('请勿外传', canvas.width / 3, canvas.height / 2); return canvas.toDataURL("image/png"); };
![]()
使用MutationObserver
监听dom变化,MutationObserver
详细用法之前已经讲过了,详细可见作为前端你还不懂MutationObserver?那Out了
具体监听逻辑如下:
// watermark 样式 let style = ` display: block; overflow: hidden; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-repeat: repeat; pointer-events: none;`; //设置水印 const setWaterMark = (el: HTMLElement, binding: any) => { const { parentElement } = el; // 获取对应的 canvas 画布相关的 base64 url const url = getDataUrl(binding); // 创建 waterMark 父元素 const waterMark = globalWaterMark || document.createElement("div"); waterMark.className = `water-mark`; // 方便自定义展示结果 style = `${style}background-image: url(${url});`; waterMark.setAttribute("style", style); // 将对应图片的父容器作为定位元素 parentElement.setAttribute("style", "position: relative;"); // 将图片元素移动到 waterMark 中 parentElement.appendChild(waterMark); }; // 监听 DOM 变化 const createObserver = (el: HTMLElement, binding: any) => { console.log(el, 'el') console.log(style, 'style') // console.log(el.parentElement.querySelector('.water-mark'),'el.parentElement') const waterMarkEl = el.parentElement.querySelector(".water-mark"); const observer = new MutationObserver((mutationsList) => { console.log(mutationsList, 'mutationsList') if (mutationsList.length) { const { removedNodes, type, target } = mutationsList[0]; const currStyle = waterMarkEl.getAttribute("style"); // console.log(currStyle, 'currStyle') // 证明被删除了 // (1)直接删除dom // 1.先获取设置水印的dom // 2.监听到被删除元素的dom // 如果他两相等的话就停止观察,初始化(设置水印+启动监控) // (2) 删除style中的属性 // 1 判断删除的是否是标签的属性 (type === "attributes") // 2.判断删除的标签属性是否是在设置水印的标签上 // 3.判断修改过的style和之前的style对比,不等的话,重新赋值 if (removedNodes[0] === waterMarkEl) { console.log(removedNodes[0]) // 停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器。 observer.disconnect(); //初始化(设置水印,启动监控) init(el, binding); } else if ( type === "attributes" && target === waterMarkEl && currStyle !== style ) { console.log(currStyle, 'currStyle') console.log(style, 'style') waterMarkEl.setAttribute("style", style); } } }); observer.observe(el.parentElement, { childList: true, attributes: true, subtree: true, }); }; // 初始化 const init = (el: HTMLElement, binding: any = {}) => { // 设置水印 setWaterMark(el, binding.value); // 启动监控 createObserver(el, binding.value); }; const directives: any = { mounted(el: HTMLElement, binding: any) { //注意img有onload的方法,如果自定义指令注册在html标签的话,只需要init(el, binding.value) el.onload = init.bind(null, el, binding.value); }, };
![]()
删除水印标签依然还在,除非删除水印注册的标签才能删除水印,但是这样做毫无意义,因为这样做内容也会全部删除掉。
toDataURL(type, encoderOptions)
,接收两个参数:
image/png、image/jpeg、image/webp
等等,默认为image/png
格式
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
蓝蓝设计的小编 http://www.lanlanwork.com