快速变化的技术每年都在影响着设计趋势。作为设计师,我们需要时刻保持关注,对设计趋势拥有较高的敏感度,不断学习,扩充自己的设计技能,目的是为了跟上的市场环境。基于我的调研,经验和观察,我甄选了在2020年你将会看到的最为关键的8个UI/UX设计趋势。让我们一起来看看吧。
插图被应用到APP中已经有很长一段时间了,它们在最近几年的演变令人印象深刻。插图作为一种非常流行的设计元素,为我们产品的整体产品增加了情感化体验。插图非常能抓人眼球,尤其是在融入动效后会显得更加的自然,将产品带入生活的气息,使得产品功能更加突出,同时也增添了更多的细节和个性。
△ Welcome to Swiggy by Saptarshi Prakash
△ Onboarding animations — Virgil Pana
另一个好处是使用动效后,能抓住用户的注意力使其能够更加沉浸在你的产品中。动效同样是讲好品牌故事,产品或者服务最有影响力的途径之一。
微交互存在与每一个网页或者app界面中。每当打开你最喜欢的那些应用时,都有机会看到它们,比如像Facebook中就有大量不同的微交互,我认为「Like」功能就是一个完美的例子。有时,我们几乎意识不到它的存在,因为它们非常的不显眼,非常自然地融到界面中去了。但是,如果当你把这些微交互移除掉的话,你又会非常快的注意并能感受到一些非常重要的东西丢失了。
△ Menu toggle close animation — Aaron Iker
△ Tab bar active animation — Aaron Iker
一般来说,在UI/UX中即使非常小和细节处的设计都可能会带来巨大的冲击力。微交互就是完美的证明,细节和对它的关注能极大的改善产品的整体体验,并让产品体验上升一个台阶。每年,新设备的发布伴随着新的机会,能给产品塑造新品牌和创造富有创意的微交互。
3D图形设计几乎无处不在,比如在电影,游戏或者运营广告里等等。3D图形设计早在10年前就出现了然后一直在不断提升和进化。手机和web技术进展迅猛,新的web浏览器能力打开了3D设计新世界的大门,这给了设计师们在web和手机界面中创造炫酷3D设计的机会。
△ 3D flip menu by Minh Pham
△ Car health report UI by Gleb Kuznetsov
创造并整合这些3D创意设计到web和手机界面中需要特殊的技能和花费大量的工作,但这些付出会得到回报。
△ Apple AirPods Pro landing page
3D设计对于产品和服务来说,具有非常大的吸引力,例如在交互上能够支持用户360度查看产品,从而大大提升整个的产品体验。
在2020年会有更多的品牌利用3D渲染模型的产品和服务去模仿线下购物体验。
VR技术在2019年有一个巨大的飞跃。最近的一年我们激动地看到了头戴式设备有了非常大的发展,尤其是在游戏领域。我们需要记住的是,游戏行业经常在引领着新技术的发展并落地到实际的产品设计中。研究表明,VR也不例外,在Oculus Quest于2019年推出后,许多机会为其他行业打开了大门。Facebook CEO 扎克伯格已经测试了激动人心的手部交互功能,并正式宣布将在2020年初为Quest进行更新。
△ Oculus Quest — hand interaction feature
△ PlayStation Virtual Reality Website Design by Kazi Mohammed Erfan
索尼和微软计划在2020年夏季发布他们的新设备,这就给VR技术带来巨大的机会和发展空间。
学习VR 可以阅读优设这个专题:https://www.uisdc.com/zt/vr-design
在最近几年,我们能看到在AR(增强现实)这块有了很大的进步和惊喜。世界引领着科技公司在AR开发方面进行了巨大的投入,所以我们应该期待这项技术在2020年有更大的成长和发展。苹果公司也发布了他们自己的AR套件叫AR KIT3来帮助设计师和开发者在他们的产品中打造AR体验。
△ Apple ARKit 3 by Apple
△ Public transit app by Yi Li
△ House of Plants AR Concept by Nathan Riley
在AR空间里会有无限的机会和创意去打造一个新的品牌和激动人心的体验。为AR做UI设计会在2020年成为一大趋势,这就要求设计师们在面对创造AR产品体验前,应该去准备和抓紧学习新的工具,原型之类的知识。
学习AR 可以阅读优设这个专题:https://www.uisdc.com/zt/ar-design
一般来说,拟物化设计是指以现实风格/方式创造出来与现实中的物体相匹配的设计元素。不断发展的VR/AR技术以及在各大最流行设计平台(Dribbble,Behance等)上展示的设计作品趋势来看,预示着拟物化的回归,但这次换了个更现代,更酷略微高大上的名字叫「新拟物风」(也叫Neumorphism)。
△ Skeuomorph Mobile Banking | Dark Mode by Alexander Plyuto
△ Simple Music Player by Filip Legierski
△ Sleep Cycle App — Neumorphism Redesign by Devanta Ebison
你可能注意到了:Neumorphism代表了丰富细节和明确的一种设计风格。高光,投影,发光,这些细节非常令人印象深刻。Neumorphism风格已经鼓舞了全世界一大批的设计师创作作品,它也会成为2020年最大的设计趋势。
学习新拟物风可以阅读优设这个专题:https://www.uisdc.com/zt/neumorphism
最近一年我们也注意到一种不对称风格正在快速发展。传统基于「模板」的布局肯定会消失。这种设计趋势给2020年的设计带来了更多的差异化。合适的不对称风格将会在我们的作品中增多一大批不同的性格,火力以及个性,所以设计不再单纯的基于模板。
△ Limnia Fine Jewelry Grid — Zhenya Rynzhuk
△ Carine fashion store — selection screen concept — Dawid Tomczyk
当设计这种不对称风格时,设计师拥有非常多的选项以及巨大的发挥空间。但是,想设计好这种不对称风格需要大量的练习,它绝不是将元素随机的摆放在网格中,而应该小心使用和实现它们,时刻需要把用户的诉求考虑到设计中。我们并不想让用户迷失在我们的产品中,对吗?
故事在整个用户体验中扮演着非常重要的角色。你可能经常会在着落页看到它作为品牌介绍,产品或者一个新的服务。讲故事就是利用创意的形式把信息传递给用户。这可以通过强大的视觉元素来呈现(字体,插画,高清图片,颜色,动画,交互元素)。
△ A+WQ / Young Lab Page Story of The Week Animation by Zhenya Rynzhuk
△ Free Sketch Template :: Mimini by Tran Mau Tri Tam
讲故事可以帮助产品创造出品牌和用户之间积极的情感连接。讲故事可以为你的产品创造出非常多的记忆点,让用户感受到自己就是产品或服务的一部分,他们便会更加愿意使用你的产品。话虽如此,讲故事也是一种非常有效的营销手段,它可以极大地提高你的产品/服务的销量。讲故事作为一种非常成功的手段,将在2020年继续发扬光大。
1. 动态插图
通过把动画和插图进行结合,我们可以使得设计变得更加突出,并把它带入用户的日常生活,为产品赋予了的细节和个性化。
2. 微交互
微交互被证明是可以在当用户注意到他们是能够带来非常大的惊喜体验,它能够有效的提升整个产品的用户体验并把产品的品质提升一个等级。
3. 3D图形的应用
新的浏览器技术打开了3D图形应用的大门,能够给设计师带来非常大的创意机会去打造让人惊叹的3D图形设计应用到网页和手机APP中。
4. 虚拟现实
游戏行业将迎来新的变革,新的技术能够应用到产品设计中。
5. 增强现实
在AR空间中拥有无限的机会去创造新的品牌和令人激动的新体验。为AR技术服务的UI设计将在2020年成为主要趋势,设计师需要位为之准备并去学习新的工具,原型,当真的需要你去做一款AR应用时就需要用到。
6. 新拟物风
AR/VR技术不断发展,以及在各大流行设计平台上大量涌现的写实设计作品预示着拟物风的回归,但只是这次换了个新的更加现代化的名字。
7. 不对称布局
运用不对称布局能让设计创意变得拥有更多选项和机会。虽然,设计一个成功的不对称布局需要投入大量的练习和时间。
8. 讲故事
讲故事就是利用创意形式把信息传递给用户。讲故事是一个非常好的营销工具,可能会大大增长产品的销售额或服务。
文章来源:优设 作者:彩云译设计
最近关于新拟物化 Neumorphism 的风太大,简直是传遍大江南北无人不知。对于它的看法大家也都众说纷纭,大部分的观点都集中于:第一看过去非常的高大上,再仔细琢磨一下就感觉只能是飞机稿中的战斗稿。对此我表示非常的理解,毕竟在国内体制下的用户界面设计基本都延续商业设计的命脉──低效能、不实用、不能带来良好转化的东西统统给我丢掉,哪怕是用户体验也是建立在商业目标驱动下的存在。
尽管观点如此,我还是想为新拟物化这位诞生在不平凡 2020 年的新生儿稍稍正个身,它并非空穴来风,也并非完全无法落地使用,相反如果合理加以优化应该能达到意想不到的双赢效果。
一切的开始都源于一个叫 Alexander Plyuto 的设计师在各平台发布了一个他的新作品──「Skeuomorph Mobile Banking(拟物化手机银行)」。
在去年末的时候这名设计师还一直沿用 Skeuomorph(拟物化)这个名词来命名自己的一系列设计作品,直到 HYPE4 的 CEO-Michal Malewicz 写了一篇关于此风格的文章,并赋予了它一个新名词 Neumorphism(New+Skeuomorphism),自此之后大家就都照着这个新名词进行传播了。
在详解新风格之前,先让我们回忆一下这些年移动端用户界面设计风格的演变历程。自 2013 年苹果推出了 iOS7 之后开始刮起的扁平风潮,所有走在设计前沿的大厂都开始不约而同地对自己家的 app 进行了大刀阔斧的改版。
这扁平风一刮就是 7 年,仔细分析一下就能明白为何 ta 如此长寿:内容优先的认知简约,不仅拓展性强且具有能的特性,解放了一大堆「手活」不是那么好的设计师,让他们有更多时间专注在设计解决问题的命题上。
但就算一个风格再适应市场的需求,用户和时代还是会对它逐渐疲惫,审美疲劳和新的市场需求都会催生新的变革。
1. 新拟物化≠轻拟物
第一次看到这个风格介绍的时候险些以为就是曾经的轻拟物重返江湖了,但仔细看看原设计师输出的设计原则,发现确实是完全不同的 2 种定义。
轻拟物从本质上来说是 Y 轴面原质化层级分离的,而新拟物是在 Y 轴面不分离的情况下物理化拟态。
来看一个轻拟物与新拟物卡片的比对:
从上图可以感受到新拟物在保留轻质感的同时,更贴近事物的物理还原,但真实感与舒适度带来的代价就是它的辨识度和对比度明显较其他风格低了很多,这也是它被大家吐槽飞机稿中的战斗稿的重要原因之一。
2. 新拟物化控件示例
原设计师对新拟物化的「浅色版」控件规范如下,基本涵盖了核心的界面设计控件,整体对于控件的定义就在于良好使用投影和渐变来打造物理化界面肌理。
另外还有可以良好适配当前流行黑色模式的「黑色版」。
在了解新拟物化的设计语言特点之后,大家应该都发现这种风格的设计是有一定局限性的,它并不适用于一部分商业产品,大部分时候也不适合全局控件应用。那么如果我们想要把新拟物化应用到我们的落地项目设计中,需要注意哪些地方,并进行什么样的改良呢?
1. 深浅模式叠加解决弱可视难题
新拟物的按钮肌理很多是建立在素色白板上的浅色按钮,如果继续沿用浅色按钮,且不说色弱用户的可视问题,普通用户的操作行为也会大打折扣,所以这里我们建议将新拟物的深浅模式叠加来使用,如下图:
2. 局部高光使用解决层级难辨问题
如果将新拟物化全控制使用,确实容易造成界面层级混乱的问题,因为毕竟它的设计语言就是 Y 轴面不分离的设计定义,但如果我们合理选择它来作为局部高光,应该大部分情况下还是不错的。如下图,我们仅在银行卡部分使用新拟物化(深浅双模式均可用),其他的控件部分保持扁平,使用 2 个风格相融合的方式可以良好保障层级的划分:
3. 拿什么解决开发崩溃的问题?
之前看到很多文章在转发一个生成新拟物化 css 代码的网站:Neumorphism.io,说是用这个就可以轻松解决开发的问题。
然而事实的真相总是令人落泪的,这个网站提供的 css 代码只是网页代码,移动端是完全用不了的。而且就算有对应的 css 代码,对于开发来说也是远不够的,他们还是要写框架来支持这套 css 代码,不然是跑不起来的。所以我们要如何解决开发小哥哥手写新拟物化设计稿崩溃的问题呢?
很简单,就是给他们切图。按钮的软点击切两张状态图,卡片背景只需要切一张,ppduck 压缩走一波,对 app 性能的影响基本可以忽略不计(因为上文我也说过了这种风格不大可能大面积或者全界面应用)。
至于新拟物风不适用的场景大家应该都心知肚明了,信息承载大,层级关系复杂,我就不一一举例了,基本就涵盖了大部分现在市面上主流的产品的大部分场景。但即便如此我们还是需要对新的设计保有一丝激情与希望,不要轻易的去否定,毕竟新生事物总是有它的魅力与独到之处。
文章来源:优设 作者:Nana的设计锦囊
在一个asp.net 的项目中,前端通过ajax将富文本中的文字内容post到服务端的一个ashx中,在ashx中尝试读取参数值时,
结果报错:“从客户端中检测到有潜在危险的 Request.Form 值”
#事故分析
由于在asp.net中,Request提交时出现有html代码字符串时,程序系统会认为其具有潜在危险的值。会报出“从客户端 中检测到有潜在危险的Request.Form值”这样的Error。
而富文本中的内容是包含html代码的,所以...
#解决方案:
1、前端对富文本字符串进行encodeURI编码,服务端进行HttpUtility.UrlDecode解码操作;
前端代码:
var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
$(function() {
$.ajax({
type: "post",
url: "TestHandle.ashx",
data: { Title: 'jack', Content: encodeURI(str) },
success: function (data) {
$("#div").html(data);
}
});
});
后端代码:
public void ProcessRequest(HttpContext context)
{
string str = context.Request["content"];
string content = HttpUtility.UrlDecode(str);
context.Response.ContentType = "text/plain";
context.Response.Write(content);
}
效果图:
2、前端不以form的方式提交,直接以json方式提交,服务端从request的body中读取数据,然后反序列化,得到信息;
前端代码:
var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
var temp = { Title: 'jack', Content: str };
$.ajax({
type: "post",
url: "TestHandle.ashx",
contentType:"application/json;charset=utf-8",
data: JSON.stringify(temp),
success: function (data) {
$("#div").html(data);
}
});
后端代码:
string bodyText;
using (var bodyReader = new System.IO.StreamReader(context.Request.InputStream))
{
bodyText = bodyReader.ReadToEnd();
}
dynamic bodyObj = JsonConvert.DeserializeObject(bodyText);
context.Response.ContentType = "text/plain";
context.Response.Write(bodyObj.Content);
效果图:
#其他场景的解决方案:
1、aspx页面,当前页面进行form提交
打开当前.aspx页面,页头加上代码:validateRequest=”false”,如:
<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="false" CodeFile="default.aspx.cs" Inherits="default" %>
该方法不推荐,还有一种修改web.config配置文件的方法,强烈不推荐,就不写在这里了;
2、在ASP.NET MVC中的解决方案
1)、针对某个实体类的单个字段设置 [AllowHtml] ,这样提交的时候,系统就会放过该字段。
2)、前端代码:
var str = '<p><span style="color: #00B0F0;"><em><strong>我想留在你的身边,</strong></em></span><br/></p><p><span style="color: #7030A0;"><strong><span style="text-decoration: underline;">深情款款多么可怜;</span></strong></span></p>';
$(function () {
$.ajax({
type: "post",
url: "Home/Test",
data: { Title: 'jack', Content: str },
success: function (data) {
$("#div").html(data.ok);
}
});
});
3)、后端代码:
public class NewInfo
{
public string Title { get; set; }
[AllowHtml]
public string Content { get; set; }
}
#写在最后
该文只是浅显的总结一下,其中涉及的xss方面,没有详细考虑,欢迎指正!
前言
开发中,经常会用到js的Array数组的各种迭代函数map(),filter(),some(),every(),forEach(),find() findIndex(),也是在ES6中新增一些遍历函数。同样是不是也是一道面试题,说说ES6新增的一些新特性????
✍开始正文some()函数
✍一、对some()函数的定义:
some():用于检测数组中的元素是否满足指定条件(函数提供);
some()方法会依次执行数组中的每一个元素:
如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
注意:
some()不会对空数组进行检测。
some() 不会改变原始数组。
✍二、浏览器支持
表格中的数字表示支持该方法的第一个浏览器的版本号。
✍三、语法
array.some(function(currentValue,index,arr),thisValue)
1
参数说明:
✍三、示例
<script>
var ages = [4, 12, 16, 20];
function checkAdult(age) {
return age >= document.getElementById("ageToCheck").value;
}
function myFunction() {
document.getElementById("demo").innerHTML = ages.some(checkAdult);
}
</script>
以蚂蚁森林和蚂蚁庄园为典型代表,而淘宝里的“野生小伙伴”、天猫里的“童话镇”也是此类题材。这类游戏更多是通过公益捐献的形式赋予用户更多的使命感,吸引用户参与,但是带来的用户商业价值不高。目前“野生小伙伴”已经下架,“童话镇”在天猫平台的露出并不明显,用户的感知较弱。
四、总结
爱玩是人类的天性。因此游戏以及游戏化的产品,天然具有高用户粘度和用户活跃度的特质。但是市场上有无数的游戏化产品,为什么有的异常火爆,有的无人问津呢?
在产品设计时需要注意以下几点:
1、游戏化产品之所以受到用户的喜爱,利益点仅仅是表层驱动,游戏的玩法才是产品真正的核心。因此需要通过建立完善的游戏化体系,提升产品的竞争力;
2、游戏化产品竞争激烈,需要不断的进行玩法创新,才能带给用户差异化体验。例如拼多多系列产品,通过实物领取和兑换,带给了用户全新的体验感受,对用户的吸引力也更强;
3、游戏化产品需要赋能商业目标,在实现了用户活跃的基础上,还需要提升用户转化;
作者:子牧先生
转自 :子牧设计笔谈
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>隔行变色</title>
</head>
<body>
<table id="mytable" align="center" width="80%" border="1">
<tr bgcolor="#cccccc">
<td>aaa</td>
<td>aaa</td>
<td>aaa</td>
</tr>
<tr>
<td>bbb</td>
<td>bbb</td>
<td>bbb</td>
</tr>
<tr>
<td>ccc</td>
<td>ccc</td>
<td>ccc</td>
</tr>
</table>
<script type="text/javascript">
window.onload=function(){
//获取mytable中标签名为tr的字节点
mytable=document.getElementById("mytable");
trs=mytable.getElementsByTagName("tr");
len=trs.length;
flag=true;
for(i=0;i<len;i++){
if(flag){
//每隔一行设置背景色
var tr=document.getElementsByTagName("tr")[i].setAttribute("bgcolor","#cccccc");
flag=false;
}else{
flag=true;
}
}
}
</script>
</body>
</html>
/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
<script type="text/javascript">
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
//以下进行测试
if (Sys.ie) document.write('IE: ' + Sys.ie);
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
if (Sys.opera) document.write('Opera: ' + Sys.opera);
if (Sys.safari) document.write('Safari: ' + Sys.safari);
</script>
PC端只有Chrome有Safari字段吗?为什么不需要判断其他浏览器?
其实360,QQ等浏览器的userAgent字段也会带有Safari字段,但是由于他们基于Chrome二次开发的,所有也会携带有Chrome字段。
所以「匹配规则:拥有Safari字段,并且没有Chrome字段」就可以了。
接下来是修改元素样式
<html>
<head>
<style>
#a{
width:700px;
height:300px;
font-size:50px;
color:red;
background-color:grey;
z-index:2;
position:absolute;
top:1300px;
left:200px;
display:none;
}
</style>
</head>
<body>
<div id="a"></div>
</body>
<script type="text/javascript">
//假设想修改display为block
function modify(){
//1.原生Js法
var a= document.getElementById("a");
a.style.display="block";
//2.用JQuery的css方法
var a =$("#a");
a.css("display","block");
//3.用JQuery的attr方法
var a =$("#a");
a.attr("style","display:block");
}
</script>
</html>
这样就可以根据不同浏览器写出不同的样式适配啦
JS中数据类型转换
目前为止,我了解到的JavaScript中共有6种类型。通过typeof关键字可以查看类型名称。
数据的类型:
字符串:若值为字符串,则显示为String。字符串使用单引号或双引号括起来。在控制台显示为黑色。
数字:若值为数字,则显示为Number。在控制台显示为蓝色。
布尔值:若值为布尔值,则显示为Boolean。它的值只有”true”和”false”。
对象:若值为对象,则显示为Object。
未定义:若值未定义,也就是仅仅声明,但未进行赋值,则显示为Undefined。
空值:若值为指向不引用对象的指针,则显示为Null,它与Undefined不同,以后慢慢深入了解。
以下表格详细写出了各种情况下相互转换的结果,可作为辅助记忆。
值 转换为字符串 转换为数字 转换为布尔值 转换为对象
undefined “undefined” NaN false throw TypeError
null “null” 0 false throw TypeError
true “true” 1 new Boolean(“true”)
false “false” 0 new Boolean(“false”)
“” 0 false new String("")
“1.2” 1.2 true new String(“1.2”)
“1.2a” NaN true new String(“1.2a”)
“aaa” NaN true new String(“aaa”)
0 “0” false new Number(0)
1 “1” true new Number(1)
NaN “NaN” false new Number(NaN)
Infinity “Infinity” true new Number(Infinity)
[] “” 0 true
[9] “9” 9 true
[“a”“b”] “a,b” NaN true
在Js中,数据类型可以相互转换,转换的方式有两种,隐式转换和强制转换,首先来说一些隐式转换。在进行代码书写时,要经常提醒自己所使用的元素是什么数据类型,在进行某些操作后是否会导致数据类型的变化,原因就是Js会对数据进行类型的隐式转换。
隐式转换举例:
(+)加法运算的隐式转换:加号两边只要出先了字符串,就自动将两者均转化为字符串,使两个字符串发生“拼接”,最后生成的结果也是一个字符串;如果前后都不是字符串,则转化为数字类型进行计算。
(-、*、/、%)其他算数运算的隐式转换:前后都转化为数字类型进行计算。
(!)逻辑非的隐式转换:他会将他后面的变量或表达式转换为布尔值。
(<,>)比较运算符的转换:如果前后存在一个数字,会对另一个转化为数字进行比较;如果前后均为字符串,会依次比较对应字符的编码大小,老大比老大,老二比老二,依次进行。
(&&,||)逻辑运算符的转换:先将前后都转化为布尔值再进行判断,要记住的是,只有undefined,null,0,””,NaN会转化成为false,其他都是true。
(== 、===)这里作为补充说明,null与Undefined相等但不全等,NaN与任何都不相等。
强制转换的方式:
1.转化为字符串
String(里面写待转化的内容):没什么好解释的,就是强制将你所看到的转化为你所看到的。
toString(里面写目标数字是几进制),写法为:待转化内容.toString(目标内容是几进制)。括号内不写时默认为10。
toFixed(保留小数的位数),写法为待转化内容.toFixed(保留小数的位数),存在精度误差。
2.转化为数字
Number(),只有所转化内容在肉眼看到的全是数字,才会正常转化;false会转化为0,true会转化为1;null会转化为0;undefined会转化为NaN;其他情况均为NaN。
parseInt(待转化内容,待转化内容的进制方式),与toString互为逆运算,不写的话默认为10。如果待转化内容为字符串,若以数字开头,可以从开始转换到字符前为止变成数值。布尔值,undefined,null经过转化均为NaN。
ParseFloat(),与上面一致,不赘述。
3.转化为布尔值
书写方式为Boolean(),如果上面的隐式转换你有好好看,这里很得不需要再写了。
密码强度验证
需求
首先我们需要知道需求是什么? 这很重要!
要知道 我们写的一切逻辑都是建立在需求之上
当输入框聚焦时提示密码要求
当密码符合要求时 隐藏提示 并给予反馈
密码等级低时 提示密码等级为低
密码等级一般时 提示密码等级为中
密码等级高时 提示密码等级为高
当密码不符合要求时 重新打开提示
思考如何构建函数
通过上面的需求 你能想到的函数时什么?你能想到的逻辑又是什么?
首先 提示的显示隐藏我们可以用事件绑定或者事件监听来做
其次 我们需要利用正则来判断密码等级
当密码等级为低时 显示红色
当密码等级为中时 显示黄色
当密码等级为高时 显示绿色
最后 根据密码等级来渲染页面 也就是反馈给用户的样式
建议 :
在这里 尽量把每个函数的功能区分好 构思好
不仅要让自己能看懂 还要让别人能看懂
这样的代码才是好的代码 可读性更好 可维护性更高
在提示盒子的内部写3个div 不同等级给予不同颜色不同数量的提示
密码 : <input type="text" id="ipt">
<p id="p">请输入6-20位的带有数字字母或者特殊符号的密码</p>
<div class="box">
<span></span>
<div></div>
<div></div>
<div></div>
</div>
不管样式行为再怎么花里胡哨 也一定要先把结构里要出现的元素写出来
由于考虑到等级分为三种 所以给提示盒子分3中不同的class类名
每一个类名对应的子元素的样式也不同
到js部分我们只需要操作class类名就可以了
<style>
*{
margin : 0 ;
padding : 0 ;
}
//提示盒子
.box{
position : absolute;
top : 2px;
left : 200px;
}
.box div,
.box span{
margin-right : 5px;
width : 20px;
height : 20px;
float : left;
}
//低等级
.box.low :nth-child(2){
background : red;
}
//中等级
.box.middle div{
background : yellow;
}
.box.middle :last-child{
background: #fff;
}
//高等级
.box.high div{
background : green;
}
//提示文字默认隐藏
p{
display : none;
}
</style>
<script>
//获取需要操作的元素
let ipt = document.getElementById('ipt');
let p = document.getElementById('p');
let div = document.getElementsByClassName('box')[0];
var tip = false; //聚焦显示提示的开关
//添加聚焦事件
ipt.addEventListener('focus' , () => {
//由于存在用户输入正确的密码失焦再操作的可能 所以需要验证开关
if(!tip) {
p.style.display = 'block';
}
//默认选中文字 提升用户体验
ipt.select();
})
//添加输入时的事件
ipt.addEventListener('input' , () => {
//拿到用户输入的密码字符串
let str = ipt.value;
//当密码不符合要求时 要及时给予反馈 及时清除样式
if(str.length < 6 ||str.length > 20 || /[^(\da-zA-Z\_\#\@\$\^\%\*\&\!\~\+\-)]/.test(str) || str === "") {
p.style.display = 'block';
removeClass(div);
div.children[0].innerHTML = "";
tip = true;
//如果不符合要求 就没必要判断等级了 直接结束判断
return false;
}else{
p.style.display = 'none';
}
//判断密码等级
let res = level(str);
//根据等级添加样式
randerLevel(res);
})
//判断密码等级函数
function level (str) {
let level = 0;
//当用户输入的字符串符合一定规则 让等级+1
if(/\d+/.test(str)) {
level ++;
}
if(/[a-zA-Z]+/.test(str)) {
level ++;
}
if(/[\_\#\@\$\^\%\*\&\!\~\+\-]+/.test(str)) {
level ++;
}
return level;
}
//添加样式函数
function randerLevel (level) {
//在添加样式前先清空样式
removeClass(div);
div.children[0].innerHTML = "";
//根据等级添加对应的类名
switch (level) {
case 1 :
div.children[0].innerHTML = '低';
//元素存在不止一个类名 用 += 更好
div.className += ' low';
break;
case 2 :
div.children[0].innerHTML = '中';
div.className += ' middle';
break;
case 3 :
div.children[0].innerHTML = '高';
div.className += ' high';
break;
}
}
//去等级类名函数
function removeClass(ele){
let reg = /low|middle|high/g;
if(reg.test(ele.className)) {
//不要忘记把值赋回去 replace返回的是新字符串
ele.className = ele.className.replace(reg , "");
}
}
</script>
当密码等级为低时 给予红色反馈
————————————————
版权声明:本文为CSDN博主「豆浆不好喝」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45178648/article/details/104885417
好,下面我将结合一些实例,说一下我对组合模式以及观察者模式的了解:
1、组合模式:
组合模式在对象间形成树形结构;
组合模式中基本对象和组合对象被一致对待;
无须关心对象有多少层, 调用时只需在根部进行调用;
将多个对象的功能,组装起来,实现批量执行;
想象我们现在手上有个万能遥控器, 当我们回家, 按一下开关, 下列事情将被执行:
到家了,开门
开电脑
开音乐
// 先准备一些需要批量执行的功能
class GoHome{
init(){
console.log("到家了,开门");
}
}
class OpenComputer{
init(){
console.log("开电脑");
}
}
class OpenMusic{
init(){
console.log("开音乐");
}
}
// 组合器,用来组合功能
class Comb{
constructor(){
// 准备容器,用来防止将来组合起来的功能
this.skills = [];
}
// 用来组合的功能,接收要组合的对象
add(task){
// 向容器中填入,将来准备批量使用的对象
this.skills.push(task);
}
// 用来批量执行的功能
action(){
// 拿到容器中所有的对象,才能批量执行
this.skills.forEach( val => {
val.init();
} );
}
}
// 创建一个组合器
var c = new Comb();
// 提前将,将来要批量操作的对象,组合起来
c.add( new GoHome() );
c.add( new OpenComputer() );
c.add( new OpenMusic() );
// 等待何时的时机,执行组合器的启动功能
c.action();
// 在内部,会自动执行所有已经组合起来的对象的功能
由此,我们可以总结一下组合模式的特点:
1.批量执行
2.启动一个方法,会遍历多个方法,同时执行,有点类似于递归的感觉
3.组合模式略微耗性能,但是执行方便
目前只是一个基础组合。
高级组合:
1.组合成树状结构,每个对象下,还会有自己的子对象
2.如果执行了父对象的某个方法,所有的子对象会跟随执行
3.组合模式一般建议使用在动态的html结构上,因为组合模式的结构和html的结构,出奇的一致
4.基本对象和组合对象被一致对待, 所以要保证基本对象(叶对象)和组合对象具有一致方法
2、观察者模式:
观察者模式也叫也叫Observer模式、订阅/发布模式,也是由GoF提出的23种软件设计模式的一种。
观察者模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态,或者说执行对应对象的方法(主题数据改变,通知其他相关个体,做出相应的数据更新)。
这种设计模式可以大大降低程序模块之间的耦合度,便于更加灵活的扩展和维护。
以观察的角度,发现对应的状况,处理问题。
观察者模式包含两种角色:
①观察者(订阅者):会随时更新自身的信息或状态(订阅者可以随时加入或离开);
②被观察者(发布者):接收到发布者发布的信息,从而做出对应的改变或执行。
很方便的实现简单的广播通信,实现一对多的对应关系。
核心思想:观察者只要订阅了被观察者的事件,那么当被观察者的状态改变时,被观察者会主动去通知观察者,而无需关心观察者得到事件后要去做什么,实际程序中可能是执行订阅者的回调函数。
Javascript中实现一个例子:
蓝蓝设计的小编 http://www.lanlanwork.com