首页

JavaScript 的简述与基础语法

前端达人

目录

JavaScript

  1. JS 发展历史
  2. JS 的特点
  3. JS 的组成
  4. JS 的基础语法

    a. 两种引入方式 type src

    b. 三种输出方式 console.log document.write alert

    c. 变量声明 var let const typeof undefined

    d. 数据类型简介 string number boolean object undefined

    e. 运算符 + - * / % = < > && || !

    i. 全等符与不全等符 === !==

    f. 流程控制语句

    i. 条件语句 if else switch case default break

    ii. 循环语句 while dowhile fori forin forof



    JavaScript

    • JS 用于完成页面与用户的交互功能;

    1. JS 发展历史
    JavaScript 在 1995 年由 Netscape 公司的 Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为 Netscape 与 Sun 合作,Netscape 管理层希望它外观看起来像 Java,因此取名为 JavaScript。但实际上它的语法风格与 Self 及 Scheme 较为接近;
    欧洲计算机制造联盟(ECMA)在 1997 制定脚本语言规范 ECMA Script1 (ES1),2009 年发布了 ECMA Script5(ES5),在 2015 年发布了 ECMA Script 2015(ES6),所有的浏览器的都支持 ES6;

  5. JS 的特点

    JS 设计模仿了 Java 语言,不同如下:

    JS 不需要编译,由浏览器直接解释执行;

    JS 是弱类型语言,JS 变量声明不需要指明类型,不同类型的数据可以赋值给同一变量;
  6. JS 的组成

    ECMA Script 是 JS 的基础语法;

    BOM(Brower Object Model)是浏览器对象模型;

    DOM(Document Object Model)是文档对象模型;
  7. JS 的基础语法

    a. 两种引入方式 type src




    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>JS两种引入方式</title>
    </head>
    <body>
    <!-- JS两种引入方式:JS和CSS一样都需要引入到html页面中,浏览器才会解释执行,JS有两种引入方式:
        1.内嵌(内部)脚本:在script标签中写js代码,script标签推荐放置在body标签的底部,理论上和style标签一样可以放置位置任意;
        2.外部脚步:使用script标签的src属性引入外部js文件,使用注意事项: script标签使用了src属性以后内部的代码不再被浏览器解释执行,script引入外部脚本时不能使用自闭合格式 -->
    <!--告诉浏览器把解析器切换为js解析器 type="text/javascript"可以省略-->
    <script type="text/javascript"> document.write("<h1>内部脚本</h1>");//向body中追加html内容 </script>
    <script src="../js/外部脚本.js"></script>
    </body>
    </html>
    






    b. 三种输出方式 console.log document.write alert

    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>JS三种输出方式</title>
    </head>
    <body>
    <!-- JS三种输出方式:
        1.输出到浏览器控制台;
        2.输出html内容到页面;
        3.浏览器弹框输出字符 -->
    <script>
    //1.输出到浏览器控制台
    console.log("1. 输出到浏览器控制台");//开发者专用
    //2.输出html内容到页面
    document.write("2. 输出html内容到页面");//向body中追加html内容
    //3.浏览器弹框输出字符
    alert("3. 浏览器弹框输出字符");//阻塞执行
    </script>
    </body>
    </html>
    


    c. 变量声明 var let const typeof undefined


    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>JS变量</title>
    </head>
    <body>
    <!-- JS变量用来存放数据;
        es5以前变量声明使用var;
        es6之后变量声明使用let,常量声明使用const。他们用于替代es6的var声明方式;
     JS是弱类型语言: 
        声明变量时不知道变量的类型(undefined),只有在赋值之后js变量才确定类型;
        typeof(a) 或 typeof a 输出变量的类型;
        undefined表示变量未赋值,未知类型 -->
    <script>
    //字符串 Java声明 String str ="张三";
    let str ="张三";
    console.log(str);
    //整数 Java声明 int k = 5;
    let k = 5;
    console.log(k);
    //小数 Java声明 float f = 7.5;
    let f = 7.5;
    console.log(f);
    //常量 Java声明 final Integer PI = 3.14;
    const PI = 3.14;
    console.log(PI);
    //演示弱类型语言
    let a;//声明变量不需要指明类型
    console.log(typeof a);//undefined 未赋值类型,未知类型
    a = "你好";
    console.log(typeof a);//string
    a = 123;
    console.log(typeof a);//number
    a = true;
    console.log(typeof a);//boolean
    a = new Object();
    console.log(typeof a);//object
    </script>
    </body>
    </html>
    


    d. 数据类型简介 string number boolean object undefined


    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>JS数据类型</title>
    </head>
    <body>
    <!-- JS数据类型,常用数据类型:
        1.string 字符串类型;
        2.number 数字.包括整数和小数类型;
        3.boolean 布尔类型.值只有true和false两个;
        4 object 对象类型,空对象使用null表示,有两种格式:
            new Object(); 
            JSON格式.例如:{name:"张三",age:18};
        5.undefined 变量未赋值 -->
    <script>
    //1. string 字符串
    let str = "你好";
    console.log(str);
    console.log(typeof str);//string
    // 2. number 数字
    let n = 123.456;
    console.log(n);
    console.log(typeof n);//number
    // 3. boolean 布尔类型
    let boo = false;
    console.log(boo);
    console.log(typeof boo);//boolean
    // 4. object 对象类型,空对象使用 null表示
    let obj = null;//或 new Object();
    console.log(obj);
    console.log(typeof obj);//object
    // 5. undefined 变量未赋值
    let u = undefined;
    console.log(u);//值是undefined
    console.log(typeof u);//类型是undefined
    // Object类型
    let stu = new Object();//创建一个js对象,js对象的属性想要直接加上
    stu.id = 1;
    stu.name = "刘一";
    stu.age = 18;
    console.log(stu);//{id: 1, name: "刘一", age: 18}
    console.log(typeof stu);//object
    // JS对象取属性值有两种方式:
    // 1. obj.key
    console.log(stu.name);//刘一
    // 2. obj["key"]
    console.log(stu["name"]); //刘一 == stu.name
    let b = "age";
    console.log(stu[b]);//可以取不定属性的值
    </script>
    </body>
    </html>
    


    e. 运算符 + - * / % = < > && || !


    i. 全等符与不全等符 === !==


    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
       <title>JS运算符</title>
    </head>
    <body>
    <!--
    JS运算符
    js运算符和Java运算符基本相同
    只有一个特殊的比较运算符
    === 判断js变量的值和类型都相等才为true
    !== 不全等,判断js变量的值和类型有一个不等就为true
    -->
    <script> let a = 3;
    let b = "3";
    console.log(a == b);//true
    // 全等 运算符 ===
    console.log(a === b);//false
    // 不全等 运算符 !==
    console.log(a !== b);//true
    // 三元(三目)运算符 布尔表达式?真:假
    let str = a===b?"全等":"不全等";
    console.log(str);//不全等
    </script>
    </body>
    </html>
    


    f. 流程控制语句

    i. 条件语句 if else switch case default break


    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>条件语句</title>
    </head>
    <body>
    <!-- 条件语句JS的条件语句和Java语法基本一样,但是对数据类型的真假判断有些区别 JS中对各种数据类型作为布尔值的特点:(重点掌握) 1. string 空字符串""为false,其余都为true 2. number 数字 只有0为false,其余数字都为true 3. boolean 布尔类型 值只有 true和false 两个
    循环语句
  8. object 对象类型 空对象null表示false,其它对象都是true 5. undefined 变量未赋值 为false 常用语法格式 if ... else if ... else switch case break default -->
    <script>
    //if ... else
    //if(true){
    //if(""){// string 只有空字符为假
    //if(0){number 只有0为假
    //if(false){//boolean false为假 true为真
    //if(null){//object null为假
    //if(undefined){//undefined永为假
    if("undefined"){//undefined永为假
    console.log("满足条件");
    }else{
    console.log("不满足条件");
    }

    //switch case break default
    let k =1;
    switch (k) {
    case 1:
    console.log("111");break;
    case 2:
    console.log("222");break;
    default: console.log("其它情况"); }
    </script>
    </body>
    </html>


    ii. 循环语句 while dowhile fori forin forof


    <!DOCTYPE html>
    <html lang="zh">
    <head>
    <meta charset="UTF-8">
    <title>循环语句</title>
    </head>
    <body>
    <!-- 循环语句
        while,do while,fori 和Java一样;
        forin
            1.遍历出数组中的索引和元素
            2.遍历出对象中的属性和元素
        forof 
            1.遍历出数组中的元素
        forin 与 forof 区别:
            1.forin可以遍历对象,forof不能遍历对象
            2.forin可以遍历出数组中的索引,forof只能遍历出数组中的元素 -->
    <script>
    //while 和Java一样
    let k=1;
    while (k<3){
        console.log(k++);
    }
    
    //do while 和Java一样
    k =1;
    do{
        console.log(k++);
    }while (k<3)
    
    //fori 和Java一样
    for(let i=0;i<3;i++){
        console.log(i);
    }
    
    //forin 可以遍历数组和对象
    let arr = ["刘一","陈二","张三"];//JS数组使用中括号[]定义
    let stu = {id:5,name:"李四",age:18};//JS对象使用大括号定义
        //1.forin 遍历出数组中的索引
    for(let index in arr){
        console.log(index);//数组的索引 0,1,2
        console.log(arr[index]);//数组中的元素
    }
        //2.forin 遍历出对象中的属性名key
    for(let k in stu){
        console.log(k);//字符串属性 id,name,age
        console.log(stu[k]);//对象中的属性值
    }
    
    //forof 可以遍历数组
    for(let e of arr){
        console.log(e);//数组中的元素
    }</script>
    </body>
    </html>
    
    
    
    
    
    ————————————————
    版权声明:本文为CSDN博主「Regino」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Regino/article/details/105321573
    

原文链接:https://blog.csdn.net/Regino/article/details/105321573 





产品简化改版怎么做?

涛涛

编者按:这篇文章来自 Taras Bakusevych 的文章《How to simplify your design》

如今的数字产品,在不断迭代过程中,会加入更多功能,添加更多的技术支持,更新进阶的特性。而另一方面,企业对于构建简单实用的产品,也同样非常着迷。这当中当中毫无疑问是存在微妙的对抗和冲突的——如何让更好更多的信息,以更加轻量易用的方式呈现出来?这就涉及到产品的简化改版的技巧了。

到底怎么算是简单?

让产品变简单,其实一件困难的事情。

我们可以将「简单」定义为「更加易于理解或完成」,或者是「不困难」。值得一提的是,简单与否,它是主观的,对于一个人而言简单,对于另一个人而言不一定简单。通常,我们是通过下面的三个步骤来判断一件事情是简单还是困难:

在《简单法则》当中,John Maeda 提供了10条法则,这些法则能够帮你平衡商业、技术、设计所带来的复杂性——更通俗的来说,就是如何合理简化但是又能收获更多。

The Laws of Simplicity, John Maeda

Meada,作为麻省理工多媒体实验室的教授,他也是举世闻名的平面设计师。在书中,他非常慎重地探讨了「改进」这一概念,在他看来,它通常并不总意味着「更多」。无论是对于复杂度,还是简化,都只是相对概念。结合合理的培训,培养制造火箭的科学家也不是难事,但是总会有一些关键的因素,会让简单的事情变复杂,在设计中我们应该尽量去规避它们:

那么,我们在具体的产品改版中,要如何合理地简化呢?下面,是我结合这些原则来总结的21条建议:

1、创造有焦点价值的产品

有太多的产品试图让你更用户做更多的事情,每个企业都试图成为行业中的瑞士军刀。但是,如果你希望产更加简单,那么你需要有一个核心价值,并且确定产品真正针对的是谁,并非每个产品都应该成为 Facebook。你的产品的核心价值是什么?

2、删除所有不必要的内容

想要简化产品,最简单的方法,是经过深思熟虑之后再进行简化和删除。如果组件或者模块的功能、价值存疑,那么请删除。次要信息、不常用的控件、分散注意力的样式,都在这个范畴内。就这么简单。一旦采用这一的方式,你会立刻马上看到结果。当然,删除的时候,请务必深思熟虑。

「简单并非完全没有混乱,因为杂乱必然会伴随简化而存在。简单本质上是对产品的定位和目的有更精准的描述。而没有杂乱仅仅意味着这是一件不杂乱的产品,但是这并非简单。」

——乔纳森·艾维

3、将数据转换为有意义的样式

我们日常设计的绝大多数产品,都涉及到需要用户理解大量数据。当用户对于趋势和变化感兴趣的时候,请尽量使用可视化的方式来呈现信息,而不是一堆数字。尝试从数据中提取有效的内容,可视化地呈现在用户眼前,这才是有意义的简化。

4、提供对快速决策的支持

用户长期遭受复杂决策机制的折磨,帮助用户看清各种信息,更好的决策是简化的方向之一。席克定律曾经对此作出过非常经典的解释:用户做选择所需要花费的时间和精力往往会随着选项数量的增加而增加。因此,如果你希望用户决策变得简单,那么你需要简化选择,消除不必要的选项,来帮助用户进行选择。

5、太多选择会吓走用户

当前心理学理论和调研肯定了一件事,就是足够多的选择可能会给人带来积极的情绪,相应的衍生出一个流行的观点,就是选择越多越好,但是人类天性中的管理能力是不足以支撑过多选择的。

果酱实验是消费心理学当中最著名的实验之一:为消费者提供更少的选择,对于销售更加有利。这一点是至关重要的——更少的选择,能够带来更多的销量。

在这个实验当中,选择较少所带来的转化率几乎是更多选择的转化率的10倍。这是一个选择过载带来不良后果的一个重要范例——过多选择抑制了用户选择购买的想法。

6、在提供多种选择的时候,给用户以建议

如果多个选择总是无法避免,那么不妨给用户提供建议,或者告诉用户多数用户的选择。向用户清楚地传达选项之间的差别,这在定价策略上会带来更多积极的效果。

7、将用户注意力吸引到对的区域

当你了解用户流程的时候,就应该有针对性将用户注意力引导到的对的目标上去,找到关键区域,让用户在界面中优先注意到它们。

8、使用色彩和版式来呈现内容的结构层次

你应该经常会听到类似「可读性很差」这样的表述。有很多设计的确存在这样的问题。在设计当中,有太多的因素会影响信息的传达——字体的选取,大小变化、间距、大小写和配色,都会影响到层次结构,影响到用户汲取信息的方式。使用正确的配色和版式,让内容的层次结构更加清晰,最好还能反映出品牌特征,这样就更能增强吸引力和用户对它的印象了。

9、优化组织结构,便于管理

下面两张图当中,要你数清楚有多少个圆点,哪一张图会让你这个过程更快?

如同你所看到的,无序的点状方阵和有序的是截然不同的,后者的认知负担更低,识别速度更快。面对无序的信息和内容,我们需要逐个计数,但是面对有序的信息,则截然不同。

有组织的元素不仅有着更高的识别度,也更容易被记住。在数字产品当中,记住常见控件的位置和功能无疑是重要的。同样是上面这张图,如果不是计数,而是记住每个点的位置,你能不能做到?毫无疑问,缺少组织结构,这是一件艰难的事情。

10、给相关内容分组

在简化复杂页面结构的时候,对组件和内容进行分组通常是最为有效的方法之一。通过层级划分,用户每次需要处理的信息量都会更小,而不是在无关的组件中来回穿梭寻找。借助边框和卡片将相关度更高的内容整合到一起,这是非常便捷的方法。此外,关于关于分组,格式塔原理中的分组原则是非常值得借鉴的:接近性、相似性、连续性、闭合性和连通性。

11、拆分任务,按列布局

几乎任何产品当中都会涉及到不同类别的表单,这是获取用户信息的一种方式。有的时候,即使删除掉一些不必要的字段,表单依然会很长。因此,我们可以将巨大的表单或者任务拆分开来,这样一来,整个执行过程会变得简单不少。

设计表单的时候,尽量使用单列而非多列,这样更加顺畅、易于填写。用户无需思考接下来要填写什么,而是按照一条线继续操作下去即可。

12、透明清晰地展现路径和状态

不确定性让人感到焦虑,尽可能地在设计当中规避这种不确定性。这就是为什么要让用户在任何时候都清晰地知道他在流程中所处的位置,以及接下来会发生什么。总结之前所提供的信息也是个好主意,能够减轻用户的负担,避免反复检查之前的内容。

13、替用户进行计算

人脑对于涉及计算的部分通常会比较费力,对于这些不太占用计算力的内容可以交由系统来进行计算,和计算相比,人的大脑在处理具象化的信息的时候更加擅长。尝试利用系统,而不是将压力转嫁给用户。

14、用逐步展现来隐藏复杂性

渐进式的展开是用户体验设计当中的一种范式,这种方法能够让界面更容易被理解。当涉及到多屏、大量信息和操作的时候,这种逐步展现的机制,可以避免让用户感到不知所措,也可以隐藏一些无关的信息,直到最后用户可以清晰明白内在的关联性为止。逐渐展现的方法,遵循着「从抽象到具体」这样的一种概念,而 iOS 系统当中,所采用的导航方式,无疑就是这种思路的典范。一屏一个步骤,逐渐展现,最后给用户一个确切的结果。

15、善用通用的交互模式和设计范式

用户将绝大多数的精力都耗费在各种各样的其他数字产品上,这意味着用户对于其他的网站和APP的交互模式、使用方法都有着清晰的了解,对于特定的模式有具体的预期。因此,无论你是设计网站,某个 APP ,甚至是冰箱上的控制系统,都可以遵循既有的设计和交互模式。这并不是意味着停止创新,而是在很多事情上,你无需重新造轮子。

16、初次体验应当精简

在设计任何产品的时候,都应该让用户尽快感知到产品的价值。因此,除非是满足功能性的需求,在用户初次打开应用的时候,都尽量把其他的干扰去掉,因为这都是让用户了解产品价值的障碍。第一印象很重要,如果不满意,很多用户会立即离开。

如果你第一次尝试,即使是最简单的操作,可能也是有挑战性的,有时候新手使用 APP 的时候需要引导,但是最好的方法是尽量让体验和功能一目了然,搭配上下文环境的说明引导,而不是提供复杂繁琐的学习材料。

17、结合使用场景,巧用人体工程学

简约易用的产品大多能够合理地结合人体工程学的设计。绝大多数人可能会想到诸如汽车座椅、控制面板和手柄这样的案例,但实际其实远远不止。人体工程学适用于几乎所有涉及人的产品设计。

1954 年,心理学家 Paul Fitts 仔细了解了人的运动系统,并且提出了费茨定律——移动到目标所需要的时间取决于和目标之间的距离,并且和目标大小成反比。这个定律反馈到具体的界面设计上,就是尽可能让常用元素更大,并放置到更容易被触及的地方。

18、提供直接编辑功能和推荐参数

删除不必要的交互组件、视图或者是步骤,是简化过程中必不可少的部分呢。用户应该可以以最快的速度进行操作,比如在表单中直接操作,而不是在弹出框中进行编辑,这个被称为「流程状态」,「流程状态」不应当被弹出框打破。此外,对于很多需要填写的部分,最好提供参数推荐建议功能,就像搜索的实时推荐,让用户可以更为准确地输入。

19、使用智能默认值,减少认知负荷

智能默认值——或者说智能占位符是一个非常有用的策略。一方面可以帮助用户更快更精准的填写表单,另一方面,也给用户提供了相对准确的范例。只不过,默认参数的确定,需要设计师和开发团队对用户的使用场景等信息进行研究,通过测试和调研,确定用户使用状况,以此来确定默认参数应该是多少。如果需要明确地参数或者选项,那么可以将默认值设置为 90% 用户可能会选的选项,并辅以说明。

20、防止出错

出错信息会给用户带来很大的压力,为了避免用户陷入这样的状况,防止用户无法完成任务,请使用数据输入检查的功能,对于格式输入错误的表单和内容,对用户予以警报和提醒,避免错误发生。对于极为重要的操作,在用户提交之前,让用户二次确认信息,做好检查。对于某些强制性、破坏性乃至于不可恢复的操作,确保用户知道这一操作带来的影响。

21、无障碍设计

数字产品的可访问性是老话题了,要让产品和设计对于所有人——包括有视觉障碍的用户,都可以轻松地使用。最常见的,就是不要使用色彩来作为传达信息的唯一途径,确保文本和背景之间有足够的对比度,支持键盘导航操作等等。可访问性问题并不限于特定的群体,坚持不断的改善和提升,有助于每一个用户的体验。

结语

简化并创造易于理解的产品并不容易,但是这是一条几乎任何产品都要走的必经之路,简化的方法和技巧有很多,虽然零碎,但是它们最终会带着产品走向一条更好的道路。

文章来源:优设    作者:Taras Bakusevych

这份上万字的指南,帮你学会用栅格系统构建响应式设计

涛涛

今天,90% 的媒体互动都是基于屏幕的,通过手机,平板,笔记本电脑,电视和智能手表来与外界产生联系。多屏设计已成为商业设计中不可或缺的一部分,响应式设计正迅速成为常态。作为 UI 设计师,我们希望为我们的产品在不同尺寸下都能为用户提供良好的用户体验,栅格系统可以帮助我们做到这一点。

即使是我们只针对一个尺寸进行设计,我们也经常面临设计布局方面的问题。合理运用栅格系统可以帮助我们控制布局结构并实现一致和有组织的设计。栅格系统就像无形的胶水一样凝聚一个设计,即使元素看上去是彼此分离,但通过网格将它们连接在一起,实现良好的层次结构,位置关系和一致性。

设计师和开发者之间的协作过程中,栅格系统在前端开发中是被应用的很广泛一套体系,许多优秀的设计都使用了栅格系统,使用栅格系统可以加速开发并保证视觉还原。栅格系统虽然是传统设计方法中的一部分,但它仍旧能帮助我们去设计这个多终端的世界。看到这里,你可能非常想知道栅格系统在页面中是如何运作的,那么今天我们一起来学习并且实践我们的格栅系统。

「The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice.」

「栅格系统可以帮助我们设计,但却不能保证我们的设计。它有多种可能的用途,并且每个设计师都可以寻找适合其个人风格的解决方案。但是必须学习如何使用网格。这是一门需要实践的艺术。」

——Josef Müller-Brockmann《平面设计中的网格系统》作者

什么是栅格系统?

栅格系统可以让你依靠秩序与逻辑去完成设计。

早在 20 世纪初,德国、荷兰、瑞士等国的平面设计师们发现通过维持视觉秩序,从而使版面能更加清晰有效地传递信息,二战后这种理念在瑞士得到了良好的发展,直到 20 世纪 40 年代后期,第一次出现了使用网格进行辅助设计的印刷作品。由瑞士设计师大师 Josef Müller-Brockmann(约瑟夫·米勒-布罗克曼)所著的《平面设计中的网格系统》一书,自 1961 年出版以来畅销至今,对设计界有着深远的影响。史称 Swiss Typography Movement (瑞士新浪潮平面设计运动),后来成为全球风靡的 International Typographic Style (国际主义设计风格))。

△ 约瑟夫·米勒一布罗克曼 (Josef Muller-brockmann, 1914-1996)

瑞士的一位平面设计师和教师。1958 年任《新平面设计》(New Graphic Design)主编 1966 年被任命为 IBM 的欧洲设计顾问。布罗克曼因他的极简主义设计与简洁的排版、图形和色彩而闻名,他的设计对 21 世纪的众多平面设计师都产生了重大影响。

栅格系统的优势

1. 减少决策成本提高设计理解力

栅格系统在页面排版布局、尺寸设定方面给了设计者直观的参考,它让页面设计变得有规律,从而减少了设计决策成本;UI 设计也是需要理性的、客观的、具有数学逻辑美感的。熟练运用网格系统能够让你的设计更有秩序和节奏感,页面信息的展现更加清晰,提高阅读效率,从而提供给用户舒适的使用体验。加快认知速度。这意味着用户在使用产品完成特定的任务时,例如发送消息,预订酒店房间或乘车。用户能够连贯地理解并找到下一条信息或下一步要采取的步骤。

2. 响应化

因为人们使用不同类型的设备与产品进行互动,从智能手表的小屏幕到超宽屏电视,交互是流畅的,并且没有固定的尺寸。使用产品时,人们通常会在多个设备之间切换,以完成该产品的单个任务。所以响应式设计不应该是一种品,而是一种必需品。这意味着设计师不能再为单个设备的屏幕构建。多设备环境迫使设计人员根据动态网格系统进行思考,而不是固定宽度。使用网格可以跨不同屏幕尺寸的多个设备创建连贯的体验。

3. 加速团队协作设计

当多位设计师共同设计产品时,一个统一标准就变得尤为重要。如果没有一个统一的框架去约束的话,我们的产品的页面和组件的标准可能各式各样,这样的话整个产品的页面都会比较混乱。因此,网格系统有助于将界面设计工作分开,因为多位设计师可以在统一的布局下进行不同部分工作,并且无缝集成并保持连贯。

4. 加速开发并保证视觉还原

大多数设计项目的实施,涉及到设计者和开发者之间的协作。栅格化提高了页面布局的一致性和复用性;避免了设计师与开发者在细节上的反复沟通确认,从而提升了整个设计开发流程的效率、并能帮助开发者实现较为理想的设计还原。

栅格系统的基本构成

1. 列和槽(Columns and Gutters)

列(Columns) 和槽(Gutters)。列(Column)是内容的容器,水槽(Gutter)用来调节相邻两个列的间距,把控页面留白;列和列间距加上页面边距(Margin)加起来屏幕的水平宽度。列和列间距的内容区域(Content width)由 N个列和(N-1)个水槽组成。通常情况下,web 端采用 12 列,平板采用 8 列,手机采用 4 列。当然,你可以根据项目特点来设计你的网格系统,列和水槽的宽度我们可以利用 8 点网格系统来定义,下面会讲到。列的数量越多,页面就会被分割得越「碎」,在页面设计时就会越难把控,适用于业务信息量大、信息分组较多、单个盒子内信息体积较小的页面设计,列间距宽度数值对页面的影响,与外边距大体类似,即间距越大页面越轻松简单,反之亦然。用户已经习惯通过鼠标滚轮或滚动条(scrollbar)来纵向浏览页面内容,因此竖直方向可以无限延伸,所以栅格系统在竖直方向的栅格可以不体现出来,我们在执行设计时只要在水平方向保持规律的变化就可以了。

2. 页面边距(Side Margins)

页面边距就是内容区域(Content field)以外的空间,比较推荐的设计就是页面边距可以随着屏幕尺寸的增大而增大。页面边距在移动设备上通常是 12Px到 40Px 之间,在平板设备和桌面设备页面边距变化就相当多了。在响应式设计中,你选择了一个页面边距之后,缩小页面宽度时页面还是会有你设置的最小页面边距,直到到达下一个响应点(breakpoint)。当你增大页面宽度时,页面就有更多的页面边距,直到页面宽度到达下一个响应点(breakpoint)。

3. 模块(Field Elements)

模块就是你的设计区块,可以是一段文字,一张图片,或是其他更加丰富的元素。背景元素并不能算作是设计模块,所以并不需要遵循栅格系统。模块的定义是很灵活的,它可以是个小的单位或是元素,也可以是一个元素丰富的区块。

以 12 栅格系统为例,一个 12 栅格系统可以根据业务需要被 2 等分、3 等分、4 等分、6 等分、12 等分,还可以被 1:1:1、1:2:1、1:3:2、2:3:3、1:2、1:3、1:5、3:5 等不对称分割,具体采用哪种比例的组合需要我们根据自己业务需求来定。

4. 8 点网格(8pt spatial system)

栅格系统大的层面可以帮助设计者更好的进行版式设计与内容布局,而小的方面可以辅助设计师规范页面内各种元素的对齐与间距的设定。从用户体验角度来讲,这两者同等重要,从执行层面来讲,我们一般先做版式设计与布局,然后再填充内容、调整细节。

由于列跟水槽的宽度是以网格作为基本单位来增加或者减小,所以栅格化的重要一步就是需要先定义好栅格的原子单位「网格」的大小。目前最普适易用的就是 8 点网格。我们也可以利用 8 点网格法来制定产品中的间距,建立 8 点为一个单位的网格,使用 8 的倍数来定义模块的间距与元素的尺寸。8 点网格有如下几点优势:

  • 目前主流桌面设备的屏幕分辨率在竖直与水平方向基本都可以被 8 整除,使用 8 作为最小原子足够普适。可以确保不同布局之间的视觉一致性,同时可以灵活的适配多种尺寸的设计。以 8 为单位符合「偶数原则」。偶数原则可以在页面缩放中的避免类似于 0.5、0.75、1.25 等次像素的出现,从而使页面各类元素在大多数场景下都能有比较精致的细节表现。
  • 在网格系统中应该更加注重的是间距,而间距要遵循网格系统(例如使用 4、8、16、24、32 等和 8 具有规律的数字)同时在产品中的各类元素也要遵循这类原则(例如图标大小、组件大小等)。所以布局的水平和垂直节奏和各个组件的节奏会相互重叠,整体的设计将更加完整。
  • 开发工程师使用的前端开源组件库比如 Metronic、Antdesign 等也是基于 8 的原子单位来设计,因此如果设计师也使用以 8 为基本单位的栅格系统,开发与设计师相互对接就会更加方便,开发实现页面时也能更高品质地去还原我们的设计。

如果设计上没有立即可识别的间距系统时,这种设计可能会让用户感觉廉价、不一致,而且通常不值得信任。如果设计上遵循一个 8pt 网格系统时,节奏变得可预测和视觉上的愉悦。对于用户来说,这种体验是经过修饰和可预测的,这增加了用户对品牌的信任和喜爱。

无论有多少个设计师在协同合作,现在都有一个一致的间距规范,决策成本将大大降低。设计师可以轻松地从另一个设计师停止的地方开始设计,或者轻松地并行构建。我们定义下规范可以及时和开发同学沟通,因此可以为工程师节省时间。

5. 基线网格(Baseline Grid)

基线网格由密集的水平行组成,这些行提供文本的对齐和间距准则,类似于您在直纹纸上书写的方式。在下面的示例中,每 8px 行在红色和白色之间交替。

△ 基线网格

提示:将所有行高设置为基本单位(8x 或 4px)的增量非常重要,这样您的文本才能与基线网格完美对齐。

△ 字体行高

响应式设计

1. 什么是响应式?

设计师需要通过设计让内容在不同的平台上体验最大化,确保让用户在任何一个屏幕上看到内容的时候,会觉得这些内容就是为这个平台而设计的,而不是单纯的缩放而来。这种无缝的体验,才是跨屏幕设计的真正难点所在。想要制定一套针对不同设备和屏幕的设计方案,你需要一整套的策略。用户体验同时包含了性能、交互、效率等多方面内容,也就是说,对于一个线上的响应式页面,我们不仅要关注视觉上看到的,也要关注我们操作、使用时的感受,这些综合因素最终影响着用户使用时的效率与体验。

2. 响应式设计的核心步骤

确保核心的用户体验

虽然用户体验是无处不在的,但是对于特定产品,最核心的体验是存在的。产品通常是用来解决用户所面临的特定问题的,它的这一特质让产品变得有意义。关键的内容和关键的功能的组合,通常构成了产品的核心用户体验。如果你并没有想明白这个问题,不妨问问自己:用户需要完成哪些最常见/最重要的任务?找到问题的答案之后,你的产品就应当从各个方面、各个渠道,完整而全面地支撑这些功能,帮助用户完成这些任务。举个例子,Uber 的核心用户体验是随时随地叫车,无论设备的屏幕大小如何,你进行的设计全部都应该围绕着这个需求和功能来进行。叫车是 Uber 的核心功能,即使使用 Apple Watch 这种极小的屏幕尺寸都应该顺利地完成这个任务。

敲定你的产品所覆盖的设备类型

现在的移动端设备屏幕尺寸各不相同,单独为某一个设备设计内容无疑是不现实的。根据你的产品覆盖人群、受众分类、使用场景,综合考虑你的内容会优先呈现在哪些设备和平台上,然后有意识地筛选出常见的设备类型:手机,平板,桌面端,智能电视,智能手表……

不同的设备组合通常是基于不同的场景、需求和服务来构成的,用户会针对不同的屏幕进行不同模式的交互,甚至处理的内容也会有差异。比如说,在手机上,用户更加倾向于使用轻量级的任务,并且进行一定量的沟通和交流。在平板上,用户行为更多集中在内容消费上,并且目前平板的使用量被认为在逐步降低。桌面端依然是用户完成较为专业、复杂任务的首选平台,足以应付复杂多样的内容。了解各种设备类型和使用场景是用来构建用户体验的关键。

针对不同内容来匹配用户体验

并非所有的内容都符合不同设备的使用场景,比如智能手表就不适合展示大量的文本内容。你的产品所覆盖的设备组当中,每种设备的使用场景不同,应该匹配的用户体验也不一样。移动端用户和桌面端用户的需求就是不同的,场景差异也很大。以 Evernote 为例,它可以在多种不同类型的设备之间同步和切换,其桌面端版本就针对用户的内容需求进行了优化:Evernote 的桌面端应用程序针对阅读性的内容和多媒体进行了优化,而移动端的 Evernote 则强化了拍摄记录、图片和音频记录的功能:其次,不同的设备屏幕具备不同的输入方式,设计师如果忽略输入方式上的独特性,也常常会出现许多问题,这里就不扩展开来了。

优先为最小的屏幕做设计

一直以来,设计师都习惯从最大的屏幕着手设计,最后考虑最小的屏幕上的显示效果,这意味着绝大多数的设计都是从桌面端开始设计的,通常桌面端的内容和功能更全面。当桌面端的整体设计完成之后,再推进到其他设备端的设计。然而,在进行桌面端设计的时候,我们常常会遭遇「厨房水槽」困境:由于产品通常会牵涉到多个利益相关方,许多多余的功能会被加入进来。而实践经验表明,移动端优先的设计往往能够更好的专注于核心功能,更适合作为产品设计的起点。当你优先设计最小屏幕所需要的界面的时候,这种局面会强制你从最关键最重要的地方开始设计。这也是之前设计圈和产品开发领域一直所强调的「移动端优先」的策略的由来。在此之后,再进行平板、桌面和电视端的设计,就是一个自然地做加法的过程了。在绝大多数的案例当中,最小屏幕通常是手机屏幕。

测试你的设计

产品的测试环境并不一定都得是在现实世界中寻找,但是在尽可能让真实的用户来做可用性测试,并且在产品发布之前解决所有的用户体验上的问题。

3. 为何要利用栅格系统来进行响应式设计?

响应式可以响应的前提有两点:1、页面布局具有规律性、2、元素宽高可用百分比代替固定数值,而这两点正是栅格系统本身就具有的典型特点,所以利用栅格系统进行响应式的设计是顺理成章的,也比较快捷,所以响应式与栅格化天生一对好搭档。

如何建立栅格系统

第1步:确定列的数量

第一阶段先不要限制自己的列数。首先,创建一个低保真或高保真的原型。设计一些基本元素和用户流程。在此之后,就开始设计最优的列数和大小。如果在项目开始设计之后不得不改变我们的栅格系统,不要有负担,我们需要有一些试错的空间。

我们在设计页面时,用到最多的布局方式就是等分布局,即页面内容区域被 N 等分,每一份的宽度则根据屏幕宽度自适应调整。那么就从这个角度出发,思考一下页面的网格应该设置为多少列,才能的满足各种等分布局的需要。与 web 类似,移动端最方便的网格之一是 12 列网格。这个网格将允许我们在一行中同时放置偶数和奇数个元素。

对于移动端来说,12 列网格的缺点是一个列的宽度太小,你可能很少创建一个列宽度的元素。如果你选择 2、4 或 8 列网格,请记住在一行中放置奇数个元素可能会出现的问题。

Pro-Tip:

界面设计通常包含数百个不同的页面,因此,一个网格可能不适合所有的页面。如果需要,创建额外的栅格系统,但不要忘记设计的一致性。网格系统的一致性:相同的布局边距、列之间相等或成比例的水槽,以及更改列本身的宽度时其他模块也需要保持相同的比例。

第2步:定义水槽和边距

首先,让我们先翻阅目标屏幕的设计 Guideline,以找出通常页面边距(Side Margins)。目前,Android 和 iOs 的最小推荐布局边距为 16pt。web 端则依照屏幕尺寸不同而不同。这意味着,如果你希望遵循系统指南,则页面边距不应小于 16pt。(但可以更大的)

在选择 12 列网格时,列之间的水槽不应该太大,因为由于列的宽度小和它们之间的大宽度的水槽,列将在视觉上产生分裂的感觉。同时我建议你选择与8pt 间距系统成比例的水槽大小。所以布局的水平和垂直节奏会相互重叠。水槽与页面边距成比例。那么网格更加一致,也将允许我们轻松地在其中放置特殊元素,如轮播(carousel)。

第3步:定义 8pt间距系统

了帮助不同设计能力的设计者们在界面布局上的一致性和韵律感,统一设计到开发的布局语言,减少还原损耗。在大量的实践中,我们提取了一组可以用于 UI 布局空间决策的数组,他们都保持了 8 倍数的原则、具备动态的韵律感。经过验证,可以在一定程度上帮助我们更快更好地实现布局空间上的设计决策。定义网格系统方法很多,如运用 8 点网格系统、斐波那契数列、某最小原子单位的增量、从底层系统参数化定义间距等,我们以最小原子单位的增量为例去定义网格系统。最小单元格的数值选择需要从两方面考虑:

  • 一方面是该数值是否能被大多数手机屏幕的宽度整除,即广泛的适用性;
  • 另一方面是在具体使用时是否具有一定的灵活性。

在适用性方面,4、6、8、10 这四个数值都是基本可以满足的,在灵活性方面,4px 表现最佳,但是页面就会被分割的非常细碎,在设计时比较难于把控。因此我们需要根据 APP 的实际情况选择合适的数值,4px 或 6px 单元格比较适合页面内容信息较多,布局排版比较复杂的产品。而 8px 单元格对一般的设计场景都可以很好的满足,比较适合大多数的 项目,因此是比较推荐使用的。

那么假设我们以 8 为基准的去延展系统间距,得到如下间距系统:

1、2、8、16、24、32、40、48、56、64、72、80、88、96、192 等,这里都是 8 的倍数或能被 8 整除

但是目前间距数量太多,过于细碎也会导致间距比较乱,所以我们继续优化梳理(以 6 为基准,前面个数是后面个数的 2 倍递增),得到以下间距系统:

1、2、8、16、24、32、48、64、80、96

第4步:sketch布局设置

利用 sketch 的布局设置功能,即可快速搭建出网格系统的参考布局,在平时做设计的过程中,可以经常使用 Ctrl+L 快捷键切换布局的显示,提高设计效率。

我们来解释一下这些设置分别是什么:

  • Total Width:就是内容区域(Container)的值;
  • Offset:表示栅格的偏移量,我们只要设定完成以后按 Center 按钮即可,会自动居中;
  • Number of Columns:就是栅格数;
  • Gutter on outside:是非常重要的设置,勾选以后才能跟前端的栅格算法匹配;
  • Gutter Width:就是栅格之间的间距;
  • Columns Width:就是栅格的宽度。

如何做到响应式?

在传统的栅格化系统设计中,列的宽度和水槽的宽度是保持不变的,只是列的「数量」发生变化。为什么要这么处理呢?这是为了让设计更简单。如果一组三张卡片分别放在桌面的四列上,那么在平板电脑上,会显示两张卡片,并把第三张卡片进行折行显示在第二行上。不需要做任何的调整,因为已经知道它位于第四列上了。在手机上,答案也很简单,只需要一张卡片,其他的就会自动堆到下面的行中。但是目前我有更多的响应策略,例如当视窗(Viewport)发生变化时,内容区域的元素如何去响应,具体到我们当前的栅格系统,就是 Columns、Gutters、Margins 以及由 Columns 跟 Gutter 组成的盒子(BOX)四者的值(主要是宽度)如何变化,以及在这种变化之下我们页面的布局如何调整。

1. 固定栅格或是断点系统(Fixed boxes or breakpoint system)

固定网格,列宽和水槽宽不会改变,只是改变列的数目,当窗口缩放时,排版布局不会发生任何改变,只有当达到一个临界值(开发那边设置好的固定的值),界面才会发生改变。在此之前界面排版都是不变的,就像一部分被切掉了。

如果开发那边写了一个固定栅格,当你从桌面缩小到平板电脑,就像是在桌面的浏览器宽度时,你不会看到任何变化,设计就像是被剪掉了一样。但当达到平板屏幕尺寸临界点时,设计布局马上就会改变,平板电脑上的显示效果就会好起来。如果继续减小这个值,同样的事情也会发生,在到达另一个临界值之前,设计看起来都是不变的。下面是常见的断点系统(Breakpoint System)

如图,响应式是以视窗的最小宽度作为基本依据来制定每种宽度下 Columns、Gutters、与 Margins 的响应策略,也就是说 Viewport Min-width 是做出响应的触发条件,视窗每达到一个最小宽度,就会触发该宽度下预设的页面布局方式,而每种布局都是在该宽度下的最佳布局,也是因此,响应式才会在各种复杂分辨率条件下都能给用户比较好的体验。
每个视窗宽度的最小值是触发响应的关键值,因此我们给这些用于触发的关键值起了个名字叫「Breakpoint」,每个 Breakpoint 触发一种响应策略。

2. 流动栅格(Fluid Grid)

流动栅格系统是编辑内容,仪表板,图像,视频,数据可视化等理想的响应策略。当窗口缩小时,内容将动态地发生变化,文本会进行换行,元素也会变窄。然而,这些元素在内容宽度缩小到下一个临界值之前,布局是不会变化的。在各种情况下,对用户来说,扩展内容的大小比扩展可见内容的数量更有用。

所以我想说的是,断点 BreakPoint 只是一个更改布局的参考点。这就是为什么列宽和水槽的数量不会改变的原因,因为我们想让设计师在考虑布局时能够更容易地创建一致性。内容宽度会随着窗口的缩放而发生改变,例如图片会缩小,文本会换行。水槽的宽度不一定是固定的,可以随着页面宽度变化。

在每个断点处,列计数是固定的,列宽度是最小网格 8PT 的倍数。行高是列大小的倍数,遵循推荐的纵横比。边距和填充是小单位的固定倍数。在断点之间,实际列宽是网格区域的百分比,而不是一个小的单位倍数。内容尺度流畅。

首先从所以屏幕大小中选择一个基本尺寸,然后按照推荐的纵横比以基本大小的倍数构建每个响应式尺寸。当每个块使用相同基础大小的倍数时,就会出现网格。遵循此方法可确保栅格系统一致性,甚至跨产品的一致性。

3. 混合栅格(Hybrid Boxes)

在实际项目中,使用流动网格和固定网格的组合也是常见的做法。网站通常是流动网格,因为它要去适应各种不同终端的大小。后台系统设计、工具型的界面设计就比较经常使用网格和流动网格组合的形式。例如的后台管理系统(dashboard)侧边栏是固定网格,右侧内容是流动网格。混合栅格在每个维度上有不同的缩放规则,所以它们不使用统一的缩放比。当用户需要调整浏览器的大小以使内容在一个维度上伸缩而在另一个维度上不伸缩时,便使用混合网格。

面板对栅格系统的影响

1. 灵活面板(Flexible panels)

灵活的面板允许折叠和扩展状态。面板的展开状态为固定宽度,用户无法调节。当用户将鼠标悬停在折叠的面板上时,面板就会展开。当灵活的面板扩展时,它们要么压缩内容和网格,要么将内容推到浏览器边缘之外。

2. 固定面板(Fixed panels)

固定面板保持静态宽度,不能折叠,也存在于响应网格之外。

3. 悬浮面板(Floating panels)

此面板样式漂浮在主要内容区域之上,不影响响应网格。浮动面板将任何 UI 元素隐藏在其下方,用户必须将其移除。内联菜单、下拉菜单和工具提示也是浮动的。

总结

写这篇文章的目的是想提供一些关于如何在响应式设计中使用栅格系统,我知道对于我自己来说,我花了很多时间理解网格是如何工作的。我在 YouYube 上看了很多视频,也阅读了大量的文章,但每个人都在关注它为什么重要,却不去注重到底怎么在自己的项目中使用这些原则。

你要做的最好的事情就是从现在开始注意那些优秀设计是如何对齐元素的,你将会开始阅读这些设计系统。为了帮助理解,这里有一些设计系统概述了它们的网格使用:

在完全理解了网格的工作原理之后,你将成为了一名更好的设计师,因为你知道了你的设计将如何在临界值之间进行转换。你也可以落地你的设计,使它们能够达到像素级完美。这样的规范带来了更一致,更简洁的设计,当用户从一个界面到另一个界面流转时,这真的提升了产品的档次。我建议在你的设计中去应用这些网格,并和开发同学一起,以实践的方式将它们落地,这将会是一个非常不错的进步。

文章来源:优设    作者:IvanZheng

免费可商用!这款中文楷体太适合做封面字了!

涛涛

有时候做国风的设计作品,如果选择黑体和宋体可能太过端正,但选择书法字体的话,可能因为飞白或过度连笔导致字体不容易识别,那选什么字体呢?我建议大家选择楷体,注意不是选系统自带的楷体,而是今天推荐的演示悠然小楷,字体手稿由一位美丽女生书写,其字体有着悠然自得、闲情逸致的气质。

「演示悠然小楷」是由 keynote 研究所 x 秋叶 PPT 联合发布的一款免费商用字体,推荐设计师们收藏或下载。下载地址见文末。

字体案例演示

1. 青春/知识

△ By@伟崇

2. 文学/历史

△ By@伟崇

3. 游戏/小说

△ By@小敏

4. 中式地产

△ By@伟崇

5. 商务风

△ By@伟崇

8. 主视觉设计

△ By@画生

△ By@画生

9. 海报物料

△ By@画生

△ By@画生

△ By@画生

10. 电商广告

△ By@画生

△ By@画生

△ By@画生

11.文字排版

△ By@画生

△ By@画生

12. 品牌形象设计延展

△ By@画生

△ By@画生

△ By@画生

字体搭配

1. 思源宋体

△ By@澄音

2. 方正宋刻本秀楷

清刻本悦宋用得多了,不如试试这款有些相似但又有不同的「方正宋刻本秀楷」,较之前者字形更为周正,笔画更为果决,娟秀之中蕴藏力量。

△ By@画生

3. Garamond

Garamond 是一款古朴传统的衬线字体,在西文体系中历史悠久,恰因没有特殊的个性而被广泛使用,是老式衬线体中最具代表性的字体,与同样以端正工整为名的楷书作搭,最能相互映衬。

△ By@画生

4. 阿里巴巴普惠体

基础黑体的字体没有复杂的修饰,进一步弱化次要信息,强烈对比下让主角得以更好的突显,也让画面层次感更加丰富,而基础型的黑体,必然首推阿里巴巴普惠体。

△ By@画生

字体下载

  • 字体名称:演示悠然小楷字体
  • 系统名称:slideyouran(有的软件显示不出中文字体,就用这个来搜索)
  • 网页 CSS 字体属性:font-family:slideyouran
  • 字体版权:永久免费,包括商用

下载地址:https://pan.baidu.com/s/1ohOK2RSEA9vsfHAbfvpZmw 提取码:ypae

如何让深色模式更精致?

涛涛

通过一些案例进行比较与实验,探索如何将 UI 深色模式设计得更好。

iOS 作为 UI/UE 设计的风向标,一直是行业的引领者,不管你愿不愿意承不承认,他的每一次更新变化总能带动 UI 设计行业的一些大大小小的变革,并且产生更多的追随者,比如当年的 iOS7 开始的扁平化设计风格,对后续设计风格的影响直到现在已经 7 年了。

在最近半年,iOS 在 UI 设计风格上最大的变革莫过于 DarkMode(深色模式),在 DarkMode 之前,我们熟悉的 UI 界面往往都是浅白色界面为主,而从 iOS13 开始正式使用了 DarkMode,界面突然可以变深色了,苹果官方说这样设计可以让眼睛更舒服地长时间阅读,为革命保护视力,而且更加省电增长续航,具体结果我们不得而知,需要科学家们去验证了,但是对于我们设计师来说带来的挑战就是要「黑白无常」了。

其实 DarkMode 从测试版算起已经差不多推出了有半年的时间了,一些知名的 APP 产品早已经有了自己的兼容方案,同时 iOS 原生界面也给了我们很多最佳实践案例,按道理大家对于 DarkMode 的设计方式方法应该已经掌握了差不多了,但直到这几天微信正式推出了自己的 DarkMode 兼容方案,才发现对 DarkMode 的探索还需要设计师们多多努力。谨以此文表达一下自己的观点,不妥之处敬请海涵。

从一个「列表页面」说起

列表视图(TableView)是 iOS 中最常见的界面组件,一般常见于设置与栏目列表页面:

iOS 设置界面的浅色模式和深色模式看起来都非常协调。

下面我们看看微信发现页面,这个页面和 iOS 设置是很相似的。

如果单独看微信发现页面的浅色模式实际效果还是不错的。

但是直接转换到深色模式下就感觉突然差的很多了,甚至可以说是有点难看,这次微信真的做了一次黑天鹅?

到底是什么原因让微信发现页面在深色模式下视觉体验如此之差呢?

我们不妨将两个功能布局都相似的深色进行放在一起进行一下比较:

组成色彩分析:

在色彩这块在这两个页面中微信和 iOS 基本保持一致,四层灰度设计能更好的保持页面整体干净整洁且层次分明,但是在 A 背景色上,微信的背景色选择了黑色偏绿的颜色,应该是微信设计师还是想体现出产品的标志色原色。

文字的颜色也较 iOS 略微深一点,但是在整体上影响并不大。

看来在主要色彩上并没有什么问题,那么为什么微信这个界面与 iOS 界面比起来视觉上要感觉差一些呢?

下面来看一下图标

图标设计分析:

图标上的差别主要在于线宽与外框,微信采用无外框统一线宽的线形图标,iOS 采用的是有外框剪影图标。

我们我们把图标进行互换会怎么样呢?

观察到了吗?别看错了!

是的,我故意把位置做了对调,左边是 iOS,右边是微信。替换图标后的微信明显加分不少,整个界面都整齐多了,而 iOS 换了图标后明显变得不够整齐了,潦草很多。

那么结论是微信的无框线性图标在深色模式下兼容有问题?是的,的确如此。但是等一下,还有一些细节你注意到吗?换了图标的微信界面和之前的 iOS 界面比起来明显还是有点不够整齐,为什么呢 ?

我们回过头来从细节再看一下 iOS 界面。

我们按照这个思路把刚才微信替换图标界面再排序一下!

△ 界面视觉体验明显整齐了很多是不是!

疑问:

为什么细线图标和无框图标会在深色背景表现不够好,而在浅色背景下就没问题呢?

是不是所有的 UI 都会存在这样的问题呢?

我们再来看一些例子:

看来结论是一样的,线性图标在深色背景下的表现都是差强人意,反观带框图标适应性很强,浅色和深色模式下均能良好的适配,我来分析一下原因。

当年伽利略用望远镜往天上看,发现木星比金星大,换成肉眼看后金星则比木星大。他认为是眼睛的某种视觉特性造成了这种现象。

德国物理学家赫尔曼把这种错觉称为辐照错觉,就是说在黑暗背景下,亮度越高的物体看起来面积越大。

再来看一张图片

哪个圆圈看起来更大,显然是黑色背景下的白色圆形,实际上这只是一种错觉,所有圆圈是一样大。

光亮刺激会使得神经元产生非线性放大作用,导致刺激比实物本身看起来更大,白色圆形更亮,所以看起来更大一些。

线性图标是用线条勾画图案达到隐喻效果,一般线粗是 2px~6px 像素。

设计师在设计时都是以最终视觉作为参考,而设计稿本身多是浅色背景,所以在浅色背景的映衬下图标视觉会显得稍大,视觉基本是平衡的,假如设计是 4px 而呈现出的效果其实是 6px 左右。

是不是觉得哪里有点不对了?按照这个逻辑黑色背景下白色线图标不应该是视觉更大、更明显吗?

我们还需要考虑一个因素,那就是色彩,之前的几个界面案例的线性图标都是彩色的,特别是黑色背景下,不同色彩的图标放在一起,会有明显的忽大忽小的感觉,会让界面感觉非常凌乱。

是不是感觉黄色最大,红色的最小?但是其实是一样的,这还是相同形状的,要是图标形状不同感受会更明显。

看一个实际中的例子:

由于都是单色线性图标,在浅色和深色下表现还都不错的,但是单色图标略显界面单调,并不太建议这么设计。

毫无疑问,未来的 UI 场景需要适配多背景色风格,图标除了具备好看隐喻之外,更需要具备抗干扰性。

带框图标是一个不错的解决方法,大胆预测带框图标会将成为未来一段时间图标设计主流!

结论

  • 深色模式中灰度色阶在一个界面最多可分为四层。
  • 为了适配深色模式,今后有框图标将会成为图标设计风格主流。
  • 同样为了适配深色模式,细线图标将会被淘汰,剪影和粗线图标会流行起来。

  • 图标除了个体设计上用心,在排列上也会极大影响到页面的整合视觉,光谱排列法是个不错的选择。

  • 文章来源:优设    作者:残酷de乐章

关于HTTP请求出现 405状态码 not allowed的解决办法

seo达人

发现httppost请求目标网站会出现405 状态码,原因为 Apache、IIS、Nginx等绝大多数web服务器,都不允许静态文件响应POST请求

所以将post请求改为get请求即可

跨域,请求按要求配置完毕之后,options预请求老是报错。原因是webapi 默认的web.config有配置

有这么个配置,导致不行。要把他删掉,还要加上

浅谈JavaScript实现可视化展示冒泡排序过程

seo达人



<!DOCTYPE html>

<html>

<head>

<title>JavaScript实现可视化展示冒泡排序过程</title>

<style>

#boxes{

border:1px solid grey;

width:1320px;

height:300px;

margin-top:10px;

position:relative;

}

.box{

background:red;

width:20px;

line-height:30px;

text-align:center;

font-family:Microsoft Yahei;

font-size:15px;

color:white;

margin:0 1px;

position:absolute;

}

</style>

</head>

<body>

<div id="boxes"></div>

<script>

function random(){

var numbers = [];

for (var i = 0; i < 60; i++) {

var number = Math.floor(Math.random() 90 + 10);

numbers.push(number);

var divElement = document.createElement("div");

var parentElement = document.getElementById("boxes");

divElement.style.left = i
20 + i 2 + "px";

divElement.style.top = 300 - 3
number + "px";

divElement.style.height = 3 number + "px";

divElement.setAttribute("class","box");

parentElement.appendChild(divElement);

}

return numbers;

}

function sort(){

var numbers = random();

var parentElement = document.getElementById("boxes");

var i = 0, j = 0;

var time = setInterval(function() {

if (i < numbers.length) {

if (j < numbers.length - i) {

if (numbers[j] > numbers[j + 1]) {

var temp = numbers[j];

numbers[j] = numbers[j + 1];

numbers[j + 1] = temp;

parentElement.innerHTML = "";

for (var k = 0; k < numbers.length; k++) {

var textNode = document.createTextNode(numbers[k]);

var divElement = document.createElement("div");

divElement.appendChild(textNode);

divElement.style.left = k
20 + k 2 + "px";

divElement.style.top = 300 - 3
numbers[k] + "px";

divElement.style.height = 3 * numbers[k] + "px";

divElement.setAttribute("class","box");

parentElement.appendChild(divElement);

}

}

j++;

}

else{

i++;

j = 0;

}

}

else {

clearInterval(time); 

return;

}

}, 100);  

}

sort();

</script>

</body>

</html>

————————————————

版权声明:本文为CSDN博主「筱葭」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/zhouziyu2011/java/article/details/53899692

http的状态码(中英文)

seo达人

 1**:请求收到,继续处理

2**:操作成功收到,分析、接受

3**:完成此请求必须进一步处理

4**:请求包含一个错误语法或不能完成

5**:服务器执行一个完全有效请求失败

100——客户必须继续发出请求

101——客户要求服务器根据请求转换HTTP协议版本

200——交易成功

201——提示知道新文件的URL

202——接受和处理、但处理未完成

203——返回信息不确定或不完整

204——请求收到,但返回信息为空

205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件

206——服务器已经完成了部分用户的GET请求

300——请求的资源可在多处得到

301——删除请求数据

302——在其他地址发现了请求数据

303——建议客户访问其他URL或访问方式

304——客户端已经执行了GET,但文件未变化

305——请求的资源必须从服务器指定的地址得到

306——前一版本HTTP中使用的代码,现行版本中不再使用

307——申明请求的资源临时性删除

400——错误请求,如语法错误

401——请求授权失败

402——保留有效ChargeTo头响应

403——请求不允许

404——没有发现文件、查询或URl

405——用户在Request-Line字段定义的方法不允许

406——根据用户发送的Accept拖,请求资源不可访问

407——类似401,用户必须首先在代理服务器上得到授权

408——客户端没有在用户指定的饿时间内完成请求

409——对当前资源状态,请求不能完成

410——服务器上不再有此资源且无进一步的参考地址

411——服务器拒绝用户定义的Content-Length属性请求

412——一个或多个请求头字段在当前请求中错误

413——请求的资源大于服务器允许的大小

414——请求的资源URL长于服务器允许的长度

415——请求资源不支持请求项目格式

416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求

也不包含If-Range请求头字段

417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下

一级服务器不能满足请求

500——服务器产生内部错误

501——服务器不支持请求的函数

502——服务器暂时不可用,有时是为了防止发生系统过载

503——服务器过载或暂停维修

504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长

505——服务器不支持或拒绝支请求头中指定的HTTP版本

==========================================================

英文版:

100:Continue

101:Switching Protocols

102:Processing

200:OK

201:Created

202:Accepted

203:Non-Authoriative Information

204:No Content

205:Reset Content

206:Partial Content

207:Multi-Status

300:Multiple Choices

301:Moved Permanently

302:Found

303:See Other

304:Not Modified

305:Use Proxy

306:(Unused)

307:Temporary Redirect

400:Bad Request

401:Unauthorized

402:Payment Granted

403:Forbidden

404:File Not Found

405:Method Not Allowed

406:Not Acceptable

407:Proxy Authentication Required

408:Request Time-out

409:Conflict

410:Gone

411:Length Required

412:Precondition Failed

413:Request Entity Too Large

414:Request-URI Too Large

415:Unsupported Media Type

416:Requested range not satisfiable

417:Expectation Failed

422:Unprocessable Entity

423:Locked

424:Failed Dependency

500:Internal Server Error

501:Not Implemented

502:Bad Gateway

503:Service Unavailable

504:Gateway Timeout

505:HTTP Version Not Supported

507:Insufficient Storage

完整的 HTTP 1.1规范说明书来自于RFC 2616,你可以在rfc-editor在线查阅。HTTP 1.1的状态码被标记为新特性,因为许多浏览器只支持 HTTP 1.0。你应只把状态码发送给支持 HTTP 1.1的客户端,支持协议版本可以通过调用request.getRequestProtocol来检查。

本部分余下的内容会详细地介绍 HTTP 1.1中的状态码。这些状态码被分为五大类:

100-199 用于指定客户端应相应的某些动作。

200-299 用于表示请求成功。

300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。

400-499 用于指出客户端的错误。

500-599 用于支持服务器错误。

HttpServletResponse中的常量代表关联不同标准消息的状态码。在servlet程序中,你会更多地用到这些常量的标识来使用状态码。例如:你一般会使用response.setStatus(response.SC_NO_CONTENT)而不是 response.setStatus(204),因为后者不易理解而且容易导致错误。但是,你应当注意到服务器允许对消息轻微的改变,而客户端只注意状态码的数字值。所以服务器可能只返回 HTTP/1.1 200 而不是 HTTP/1.1 200 OK。

100 (Continue/继续)

如果服务器收到头信息中带有100-continue的请求,这是指客户端询问是否可以在后续的请求中发送附件。在这种情况下,服务器用100(SC_CONTINUE)允许客户端继续或用417 (Expectation Failed)告诉客户端不同意接受附件。这个状态码是 HTTP 1.1中新加入的。

101 (Switching Protocols/转换协议)

101 (SC_SWITCHING_PROTOCOLS)状态码是指服务器将按照其上的头信息变为一个不同的协议。这是 HTTP 1.1中新加入的。

200 (OK/正常)

200 (SC_OK)的意思是一切正常。一般用于相应GET和POST请求。这个状态码对servlet是缺省的;如果没有调用setStatus方法的话,就会得到200。

201 (Created/已创建)

201 (SC_CREATED)表示服务器在请求的响应中建立了新文档;应在定位头信息中给出它的URL。

202 (Accepted/接受)

202 (SC_ACCEPTED)告诉客户端请求正在被执行,但还没有处理完。

203 (Non-Authoritative Information/非官方信息)

状态码203 (SC_NON_AUTHORITATIVE_INFORMATION)是表示文档被正常的返回,但是由于正在使用的是文档副本所以某些响应头信息可能不正确。这是 HTTP 1.1中新加入的。

204 (No Content/无内容)

在并没有新文档的情况下,204 (SC_NO_CONTENT)确保浏览器继续显示先前的文档。这各状态码对于用户周期性的重载某一页非常有用,并且你可以确定先前的页面是否已经更新。例如,某个servlet可能作如下操作:

int pageVersion =Integer.parseInt(request.getParameter("pageVersion"));

if (pageVersion >;= currentVersion) {

response.setStatus(response.SC_NO_CONTENT);

} else {

// Create regular page

}

但是,这种方法对通过刷新响应头信息或等价的HTML标记自动重载的页面起作用,因为它会返回一个204状态码停止以后的重载。但基于JavaScript脚本的自动重载在这种情况下仍然需要能够起作用。可以阅读本书7.2 ( HTTP 1.1 Response Headers and Their Meaning/HTTP 1.1响应头信息以及他们的意义)部分的详细讨论。

205 (Reset Content/重置内容)

重置内容205 (SC_RESET_CONTENT)的意思是虽然没有新文档但浏览器要重置文档显示。这个状态码用于强迫浏览器清除表单域。这是 HTTP 1.1中新加入的。

206 (Partial Content/局部内容)

206 (SC_PARTIAL_CONTENT)是在服务器完成了一个包含Range头信息的局部请求时被发送的。这是 HTTP 1.1中新加入的。

300 (Multiple Choices/多重选择)

300 (SC_MULTIPLE_CHOICES)表示被请求的文档可以在多个地方找到,并将在返回的文档中列出来。如果服务器有首选设置,首选项将会被列于定位响应头信息中。

301 (Moved Permanently)

301 (SC_MOVED_PERMANENTLY)状态是指所请求的文档在别的地方;文档新的URL会在定位响应头信息中给出。浏览器会自动连接到新的URL。

302 (Found/找到)

与301有些类似,只是定位头信息中所给的URL应被理解为临时交换地址而不是永久的。注意:在 HTTP 1.0中,消息是临时移动(Moved Temporarily)的而不是被找到,因此HttpServletResponse中的常量是SC_MOVED_TEMPORARILY不是我们以为的SC_FOUND。

注意

代表状态码302的常量是SC_MOVED_TEMPORARILY而不是SC_FOUND。

状态码302是非常有用的因为浏览器自动连接在定为响应头信息中给出的新URL。这非常有用,而且为此有一个专门的方法——sendRedirect。使用response.sendRedirect(url)比调用response.setStatus(response.SC_MOVED_TEMPORARILY)和response.setHeader("Location", url)多几个好处。首先,response.sendRedirect(url)方法明显要简单和容易。第二,servlet自动建立一页保存这一连接以提供给那些不能自动转向的浏览器显示。最后,在servlet 2.2版本(J2EE中的版本)中,sendRedirect能够处理相对路径,自动转换为绝对路径。但是你只能在2.1版本中使用绝对路径。

如果你将用户转向到站点的另一页中,你要用 HttpServletResponse 中的 encodeURL 方法传送URL。这么做可预防不断使用基于URL重写的会话跟踪的情况。URL重写是一种在你的网站跟踪不使用 cookies 的用户的方法。这是通过在每一个URL尾部附加路径信息实现的,但是 servlet 会话跟踪API会自动的注意这些细节。会话跟踪在第九章讨论,并且养成使用 encodeURL 的习惯会使以后添加会话跟踪的功能更容易很多。

核心技巧

如果你将用户转向到你的站点的其他页面,用 response.sendRedirect(response.encodeURL(url)) 的方式事先计划好会话跟踪(session tracking)要比只是调用 response.sendRedirect(url) 好的多。

这个状态码有时可以与301交换使用。例如,如果你错误的访问了某路径信息不完整),有些服务器就会回复301状态码而有些则回复302。从技术上说,如果最初的请求是GET浏览器只是被假定自动转向。如果想了解更多细节,请看状态码307的讨论。

303 (See Other/参见其他信息)

这个状态码和 301、302 相似,只是如果最初的请求是 POST,那么新文档(在定位头信息中给出)药用 GET 找回。这个状态码是新加入 HTTP 1.1中的。

304 (Not Modified/为修正)

当客户端有一个缓存的文档,通过提供一个 If-Modified-Since 头信息可指出客户端只希望文档在指定日期之后有所修改时才会重载此文档,用这种方式可以进行有条件的请求。304 (SC_NOT_MODIFIED)是指缓冲的版本已经被更新并且客户端应刷新文档。另外,服务器将返回请求的文档及状态码 200。servlet一般情况下不会直接设置这个状态码。它们会实现getLastModified方法并根据修正日期让默认服务方法处理有条件的请求。这个方法的例程已在2.8部分(An Example Using Servlet Initialization and Page Modification Dates/一个使用servlet初始化和页面修正日期的例子)给出。

305 (Use Proxy/使用代理)

305 (SC_USE_PROXY)表示所请求的文档要通过定位头信息中的代理服务器获得。这个状态码是新加入 HTTP 1.1中的。

307 (Temporary Redirect/临时重定向)

浏览器处理307状态的规则与302相同。307状态被加入到 HTTP 1.1中是由于许多浏览器在收到302响应时即使是原始消息为POST的情况下仍然执行了错误的转向。只有在收到303响应时才假定浏览器会在POST请求时重定向。添加这个新的状态码的目的很明确:在响应为303时按照GET和POST请求转向;而在307响应时则按照GET请求转向而不是POST请求。注意:由于某些原因在HttpServletResponse中还没有与这个状态对应的常量。该状态码是新加入HTTP 1.1中的。

注意

在 HttpServletResponse 中没有 SC_TEMPORARY_REDIRECT 常量,所以你只能显示的使用307状态码。

400 (Bad Request/错误请求)

400 (SC_BAD_REQUEST)指出客户端请求中的语法错误。

401 (Unauthorized/未授权)

401 (SC_UNAUTHORIZED)表示客户端在授权头信息中没有有效的身份信息时访问受到密码保护的页面。这个响应必须包含一个WWW-Authenticate的授权信息头。例如,在本书4.5部分中的“Restricting Access to Web Pages./限制访问Web页。”

403 (Forbidden/禁止)

403 (SC_FORBIDDEN)的意思是除非拥有授权否则服务器拒绝提供所请求的资源。这个状态经常会由于服务器上的损坏文件或目录许可而引起。

404 (Not Found/未找到)

404 (SC_NOT_FOUND)状态每个网络程序员可能都遇到过,他告诉客户端所给的地址无法找到任何资源。它是表示“没有所访问页面”的标准方式。这个状态码是常用的响应并且在HttpServletResponse类中有专门的方法实现它:sendError("message")。相对于setStatus使用sendError得好处是:服务器会自动生成一个错误页来显示错误信息。但是,Internet Explorer 5浏览器却默认忽略你发挥的错误页面并显示其自定义的错误提示页面,虽然微软这么做违反了 HTTP 规范。要关闭此功能,在工具菜单里,选择Internet选项,进入高级标签页,并确认“显示友好的 HTTP 错误信息”选项(在我的浏览器中是倒数第8各选项)没有被选。但是很少有用户知道此选项,因此这个特性被IE5隐藏了起来使用户无法看到你所返回给用户的信息。而其他主流浏览器及IE4都完全的显示服务器生成的错误提示页面。可以参考图6-3及6-4中的例子。

核心警告

默认情况下,IE5忽略服务端生成的错误提示页面。

405 (Method Not Allowed/方法未允许)

405 (SC_METHOD_NOT_ALLOWED)指出请求方法(GET, POST, HEAD, PUT, DELETE, 等)对某些特定的资源不允许使用。该状态码是新加入 HTTP 1.1中的。

406 (Not Acceptable/无法访问)

406 (SC_NOT_ACCEPTABLE)表示请求资源的MIME类型与客户端中Accept头信息中指定的类型不一致。见本书7.2部分中的表7.1(HTTP 1.1 Response Headers and Their Meaning/HTTP 1.1响应头信息以及他们的意义)中对MIME类型的介绍。406是新加入 HTTP 1.1中的。

407 (Proxy Authentication Required/代理服务器认证要求)

407 (SC_PROXY_AUTHENTICATION_REQUIRED)与401状态有些相似,只是这个状态用于代理服务器。该状态指出客户端必须通过代理服务器的认证。代理服务器返回一个Proxy-Authenticate响应头信息给客户端,这会引起客户端使用带有Proxy-Authorization请求的头信息重新连接。该状态码是新加入 HTTP 1.1中的。

408 (Request Timeout/请求超时)

408 (SC_REQUEST_TIMEOUT)是指服务端等待客户端发送请求的时间过长。该状态码是新加入 HTTP 1.1中的。

409 (Conflict/冲突)

该状态通常与PUT请求一同使用,409 (SC_CONFLICT)状态常被用于试图上传版本不正确的文件时。该状态码是新加入 HTTP 1.1中的。

410 (Gone/已经不存在)

410 (SC_GONE)告诉客户端所请求的文档已经不存在并且没有更新的地址。410状态不同于404,410是在指导文档已被移走的情况下使用,而404则用于未知原因的无法访问。该状态码是新加入 HTTP 1.1中的。

411 (Length Required/需要数据长度)

411 (SC_LENGTH_REQUIRED)表示服务器不能处理请求(假设为带有附件的POST请求),除非客户端发送Content-Length头信息指出发送给服务器的数据的大小。该状态是新加入 HTTP 1.1的。

412 (Precondition Failed/先决条件错误)

412 (SC_PRECONDITION_FAILED)状态指出请求头信息中的某些先决条件是错误的。该状态是新加入 HTTP 1.1的。

413 (Request Entity Too Large/请求实体过大)

413 (SC_REQUEST_ENTITY_TOO_LARGE)告诉客户端现在所请求的文档比服务器现在想要处理的要大。如果服务器认为能够过一段时间处理,则会包含一个Retry-After的响应头信息。该状态是新加入 HTTP 1.1的。

414 (Request URI Too Long/请求URI过长)

414 (SC_REQUEST_URI_TOO_LONG)状态用于在URI过长的情况时。这里所指的“URI”是指URL中主机、域名及端口号之后的内容。该状态是新加入 HTTP 1.1的。

415 (Unsupported Media Type/不支持的媒体格式)

415 (SC_UNSUPPORTED_MEDIA_TYPE)意味着请求所带的附件的格式类型服务器不知道如何处理。该状态是新加入 HTTP 1.1的。

416 (Requested Range Not Satisfiable/请求范围无法满足)

416表示客户端包含了一个服务器无法满足的Range头信息的请求。该状态是新加入 HTTP 1.1的。奇怪的是,在servlet 2.1版本API的HttpServletResponse中并没有相应的常量代表该状态。

注意

在servlet 2.1的规范中,类HttpServletResponse并没有SC_REQUESTED_RANGE_NOT_SATISFIABLE 这样的常量,所以你只能直接使用416。在servlet 2.2版本之后都包含了此常量。

417 (Expectation Failed/期望失败)

如果服务器得到一个带有100-continue值的Expect请求头信息,这是指客户端正在询问是否可以在后面的请求中发送附件。在这种情况下,服务器也会用该状态(417)告诉浏览器服务器不接收该附件或用100 (SC_CONTINUE)状态告诉客户端可以继续发送附件。该状态是新加入 HTTP 1.1的。

500 (Internal Server Error/内部服务器错误)

500 (SC_INTERNAL_SERVER_ERROR) 是常用的“服务器错误”状态。该状态经常由CGI程序引起也可能(但愿不会如此!)由无法正常运行的或返回头信息格式不正确的servlet引起。

501 (Not Implemented/未实现)

501 (SC_NOT_IMPLEMENTED)状态告诉客户端服务器不支持请求中要求的功能。例如,客户端执行了如PUT这样的服务器并不支持的命令。

502 (Bad Gateway/错误的网关)

502 (SC_BAD_GATEWAY)被用于充当代理或网关的服务器;该状态指出接收服务器接收到远端服务器的错误响应。

503 (Service Unavailable/服务无法获得)

状态码503 (SC_SERVICE_UNAVAILABLE)表示服务器由于在维护或已经超载而无法响应。例如,如果某些线程或数据库连接池已经没有空闲则servlet会返回这个头信息。服务器可提供一个Retry-After头信息告诉客户端什么时候可以在试一次。

504 (Gateway Timeout/网关超时)

该状态也用于充当代理或网关的服务器;它指出接收服务器没有从远端服务器得到及时的响应。该状态是新加入 HTTP 1.1的。

505 (HTTP Version Not Supported/不支持的 HTTP 版本)

505 (SC_HTTP_VERSION_NOT_SUPPORTED)状态码是说服务器并不支持在请求中所标明 HTTP 版本。该状态是新加入 HTTP 1.1的。


如何衡量设计价值?

涛涛

本文来和大家讨论数值框架提取与数据分析运用是怎么相辅相成来推动游戏化项目,帮助设计团队提升设计专业性和展示产品思维的。分为 2 大块:如何在设计中平衡效益、如何衡量设计价值。下面会从这 2 个游戏项目:独立小游戏《嘛哩嘛哩汪》、会员游戏《天天加速》来剖析。

如何在设计中平衡效益

要了解这件事,首先需要简单介绍下什么是数值,在游戏公司里有个职位叫数值策划,他是解决游戏里数值平衡和经济平衡的。在这里,我们不用专业术语,我们的也没游戏公司的那么难。我总结一下电商里容易理解运用的,就是这么一条公式:

下面讲的时候大家可以用这个思路(文中都叫数值框架)来理解并试试能不能运用。

1. 快速理解游戏的玩法(数值框架的运用)

举个例子,我们之前做的独立小游戏《嘛哩嘛哩汪》,用户可以领到一只同样的小土狗,通过不同的社交玩法:比如战斗,发送偷偷告白的小纸条等等,最终把自己的狗狗变成一只的萌宠换装养成游戏。

它的主要功能模块有采金(收金币)、对战、魔法屋(换装)。

有货币系统(金币、钻石、氪金)、等级系统(阶级经验值)、任务系统、道具系统(商店、背包)、社交系统(打 call、好友、消息)等。

这样乍一看,是不是觉得有点复杂?其实只要抓住关键流向节点,比如主要货币金币、成长体系的经验值,这种流入流出最频繁的地方就是关键流向节点,再把游戏主要功能系统串起来,主要功能就是关键流向节点流向最多的地方。这样串联起来就非常简洁明了,一眼就知道这个游戏怎么玩(如下图),通过采金、pk(主要功能)得到金币(关键流向节点),可以用来购买新装备去换装(主要功能),但需要靠做任务(社交、互动)去提升经验值(关键流向节点),才能不断解锁新装备,养成一只的狗仔。

当提取了最简单的框架后,再去细分支线数值,会清晰很多,最后细化的数值从系统的组成和期望去架构数值表和体系:如何实现、从哪里获取数据、如何方便又泛用化表格、精简配置、去除冗余数据等;大白话就是解决比如:升阶太慢,要调整;金币太快,装备很快买完了,玩不下去了,要调整;用户可操作太少了,要调整;装备售价多少金币,多少钻石适合?道具使用时长多久?任务成就奖励怎么设定,要送用户什么?等等这些问题…….

而这些在项目后续可能会困扰的问题其实在初期设计的时候就可以先规划,照顾到。

2. 数值框架在其他项目中的运用

这样的思路也很适合分析运营活动,快速抓住别人玩法中最吸引用户的点,包括自己设计的时候也可以在前期就自我评估项目成本。大家可以拿淘金币和叠猫猫用这个思路试试看,这边是比较早期的分析,淘宝的迭代太快了。

先看看 19 年 6 月前的淘金币,已经有在大促的时候开垦土地,我们不说视觉,先来分析下它的布局思路。

用公式代入看看,业务的诉求植入在领水滴任务中,关键流向节点是水滴和金币,节点流向最多是种地(图中种子,这里讲功能),投金币。非常清晰的框架。而且棒的是大促期间只需要复用同一套框架变成种宝贝,这对多方来说效益是高的。我们可以看到现在很多都在做这个模式,也就是把框架工具化了,换皮不换骨。19 年双十一的全民开喵铺几乎把它套用到所有的阿里旗下产品,(下方图左)底部的任务入口(领喵币)和辅线内容(领组队红包)均根据产品来配置,设计的时候规划得很清晰。(下方图右)当养成思路之后在活动刚出体验的时候就可以分析它的设计框架意图,无需过度依赖网上分析也能知道它好在哪,自己设计的时候也会有好的借鉴。

那在做游戏化产品的时候,里面就有很多东西需要考量植入业务诉求后的平衡了,但游戏玩法肯定是相对简单些的。

3. 理解业务诉求和游戏玩法关系

拿游戏化产品-会员游戏《天天加速》举个例子。

天天加速是一款宇宙救援世界观的游戏,以加速为核心玩法。把产品的各项目标植入到加速的道具中,用户如需获得道具需要完成产品目标,获得奖励,从而实现双赢。

拿主线来说,如下图展示我们植入业务诉求的时候,按那条公式思路来思考,业务层级越高(越难做,比如购买),游戏中设定层级越低(不强推),但游戏和现实中反馈都越多/强,去激励用户做重任务。这样简单罗列,就可以让双方同学都容易理解,并提前规划后台配置和配置的数值建议,给运营同学留出后续自运营配置的空间。

副线射击游戏也是,按照这种思路,把成本均衡到,几乎相同的玩法,不同的配置成本差别是很大的,下表是对玩法影响最小的,这些产出比都会影响业务方是否为你的功能玩法买单。

当建立了数值框架后,对后续上线的数据分析和推导下一步的迭代有很好的指导作用,因为你清楚知道数据的用户操作行为、可以知道用户是怎么流失的,再综合客户的投诉建议,用研同学的调研,可以较全面的整合处理。

如何衡量设计价值

这里还是拿游戏化产品-会员游戏《天天加速》举个例子。主要从以下3个方面,通过《会员游戏-天天加速》这个项目不同版本迭代来讲。(具体数据均不能透露)。

1. 建立数据体系,验证设计价值—1.0版

前面已经介绍过游戏是怎么玩的,这里直接讲 1.0 数据结论:在上线 7 天的时候就超额完成 kpi 了,其中 pv 是 kpi 预期 2.5 倍,任务完成率是 kpi 3 倍,近 90% 的用户都来打卡签到。超出我们预期挺多的。

但是数据好=我们的价值么?这也是我们从开始做就很想验证的,我们来看看方式。

建立数据体系、量化设计指标

在前期就和业务方达成共识,把他们的 kpi 指标任务活跃和用户上行,拆解成了游戏中的具体指标。再根据指标,对应到游戏中用户完成操作的行为流程,便可对应 kpi 的数据埋点。

最后,等埋点数据出来了,再用工具具体分析。流程可以看下图~

每周根据数据,发现规律、解决问题

具体的分析,我给大家举个例,这里是各个 kpi 数据的长线跟踪,一个点的数据是说明不了问题的,重点在怎么去维持和提高。第一张图可以看到,项目上线后,uv、pv 稳定上升,但在第 6 周开始回落,我们需要敏感地察觉,并且进行分析,作出反应。当我们快速调整上线 2.0 的时候,在第 11 周数据又开始回涨。

所以需要我们对数据敏感,有解读能力,和对项目的深刻理解。不然数据就只是数据,结论可能是因人而异的,当然有现成后台直接看数据结论最好,但没有的时候也得能处理,野外求生技能还是得有的。

构建合适的数据分析框架

我把如何分析数据的全流程复制下来,每周都会把收集的数据进行梳理,按照流程把各 kpi 的数据梳理一遍,发现问题就去沟通解决推动。这样也保证项目数据能持续稳定地增长。

其实做到这一步,我们已经是项目密不可分的一部分了,谁又能否定我们的价值呢。

那数据分析除了能验证设计的价值,还能做什么?

我们再来详细说说,是如何通过分析数据指标提升游戏体验的。我们按版本迭代来看看。

2. 分析指标数据,提升游戏体验

首先,我们可以把数据分成两个层面去看:用户操作数据和产品目标达成数据,业务方更多关注的肯定是产品目标的达成数据,那我们就多分析用户操作数据,2 边汇集,能更好地推动项目。

我们举些例子~

刚说了数据需要长线跟踪,需要发现变化规律,那如图,到了第 7 周,发现数据开始回落,但依旧超过了 kpi。我们去梳理原因,最大的原因是游戏 1.0 只上线了最简单的核心玩法,用户回访多,但没有太多可操作的内容,久而久之,回访自然会下降,所以我马上拉着产品讨论稳住 pv 的方案,同时还满足产品新诉求,植入发放优惠券,并且需要快速上线。这就是 2.0 版稳住 pv 的方案,事件系统,就是画面一中,右下角的小信封。用户每次回访,都有事件系统可操作,系统里会根据问答随机给到优惠券或者游戏道具。保证用户每次回访都有事可做,有利可图。

的确上线后数据开始回涨,也是首次破 8,数据是暂时稳定了,但是我们也明白这个版本下用户没有长线留存的理由。我们必须给用户带来积累感和晋升感,才能让用户对自己的付出有感知。于是我马上策划和实现了长线粘性的新增玩法,让用户除开机械的事件操作,还有主动的互动操作。
在图一主页面的左下角,有了一个寻宝行动的入口,是个射击游戏,用户可以通过击落陨石获得高分开宝箱,得到更多用于飞船升级的核能源,积累越多可以换取越高阶的飞船,对应更丰厚的奖品,因此长线的留存在游戏中。

3. 拓宽设计边界,提升产品目标

前两点,我都在不断地去帮助产品达成目标。那我们是不是可以再去拓宽设计的边界,提升产品的目标呢?

当我们上线 1 个多月时,得到了向好的业务数据,但是我们知道,这是基于用户的基数大,11% 的转化已经可以带来这么大的订单额,如果我们能撬动另外 90% 的用户呢?因此我去分析了游戏用户,发现对促销敏感度高的用户,不管是在全量用户还是核心用户中,都超过 70%,是相当明确的用户类型。

于是有了这三者的考虑:

优化转化目标、寻找合作可能性更高的业务方向、结合我们核心用户的促销敏感度高的特点,也去挖掘了一些方向。考虑产品运营成本实现的方式去出了 2 个方案,

第一个方案:转化入口的优化。

用户要得到虫洞道具,需要去购买商品。业务诉求有发券的 kpi,那在购买同时配合得到类目优惠券,这样就能大大的提升用户的购买诉求。

第二个方案:植入事件系统

系统事件,之前是只有送优惠券的功能,现在加入跨品类低价商品的推送+对应优惠券的功能,再次打游戏用户对价格敏感的痛点,目标是提升两者的转化。
当然业务有更多深入的考量,我们既然有一些想法能共同推进项目,那就多多沟通交流。

那到这里,文章终于要结束了,通篇其实是在通过实际的项目告诉大家数据框架(开篇那条公式思路)和数据分析能怎么贯穿整个项目,怎么去平衡各方成本,相辅相成地去推动项目、验证设计价值的。

最后一点小体会,在做这 2 类项目中,我最深刻的感受是独立小游戏里游戏内容是绝对主角,难点在没接触过的游戏引擎技术的攻克和数值的实现打通(游戏资质和法务问题也很麻烦),而游戏化产品里业务诉求和游戏化的包装是双主角,难的是两者的紧密结合和推动落地。第二种在策划的时候很容易把玩游戏当成主题,但电商公司做游戏化最主要是想让用户多回访,在平台购物,带来商业效益。因此,前期都比较阉割,需要看到它为业务带来实际效益,才有后续的为「趣味性」买单的资源研发投入,这个「游戏」的取舍其实挺难过的。

文章来源:优设    作者:JellyDesign

国内顶尖网课平台CC talk ,是如何做好网师分层体系设计的?

涛涛

项目背景

网师分层对平台的重要性不言而喻,诸如阿里这类的电商平台都有完善的商家分级体系,明确了不同等级的权益和运营策略。

2019 年底 CCtalk 平台的网师数量达到了一定规模,平台的基础能力建设也相对完善,因此网师分层的事宜被提上日程。此前我们评估网师的方式是按照流水,将网师分为普通网师、中部网师和大 V 网师 3 类,不同网师对产品功能需求及运营要求差别很大。这种粗略的划分方式可以帮助简单评估网师,但并没有产品化,而且只有单一的 GMV 维度,不够全面客观。有些客单价较低的网师也有大量的购课学生,他们对平台的价值也高。因而我们需要推出一套综合网师流水、招生数量、内容质量等多个维度的方法来进行分层运营。

面对以上问题,相应的解决方案是:

  • 建立商户等级体系
  • 等级权益差别化
  • 增加权益购买触点

价值分析

既然是涉及全平台网师的重大升级调整,当然要从全局的角度来进行价值分析。我在这个项目中探索了用于多角色价值分析的「三维价值分析法」,从整个关系链的角度来解析网师分层对网师和平台的价值。

Step1.列出相关利益者

分别包括:CCtalk平台、网师、学生。

△ 列出相关利益者

Step2.设定中心点并建立关系

分析连接这3种角色的关键点是什么。我们CCtalk作为一个在线教育平台,最核心的因素是内容,因而将中心点设定为「内容」。(注意,如果此时是做某个具体功能相关的项目,那么中心点可以是这个具体的功能,例如「作业」或「直播」)设定中心点后,建立不同角色和中心点之间的双向关系。

△ 设定中心点并建立关系

Step3.进行全局价值分析

在上一步的关系网的基础上,用圆弧连接相邻角色的价值走向关系,从全局的角度进行不同角色间的价值分析。

△ 进行全局价值分析

从上面的三维图中可以看出网师分层对于平台和网师的价值。
对网师来说,有助于:了解成长路径,获得更多产品运营支持,获取更多功能权益。

对平台来说,可以:筛选网师,激励网师自驱动,增加收入。另外,还有一些间接的价值,包括通过督促网师生产高质量的内容来提升平台的价值,通过督促网师积极招生来扩大用户规模。

△ 网师分层对于平台和网师的价值

项目拆解

刚接到需求时,我内心的 OS 是:大项目!概念大,范围广,都有点不知从哪里入手。

冷静下来分析,网师分层本质是一套针对商户端的激励体系。从下往上拆解:由底层商户活跃度来计算经验值,根据经验值划分商户等级,并赋予不同等级不同的权益,权益包括教学核心功能:直播时长,素材存储空间,课程人数等。再向上衍生到不同权益对应的使用场景,以及权益的扩展方式。

△ 分层拆解

从设计层面,分为信息展示和场景触达两部分。这么一看,其实又挺简单。

设计落地

由于项目涉及的底层逻辑多,时间周期跨度大,因此拆分成 3个小版本来实现:商户权益改造,经验值等级底层 & 商户等级外显。前期的功能实现后,先预埋在版本中。等到经验等级上线时统一发布。其中经验值等级底层项目是纯技术,不涉及设计。

所以下面将从功能权益分层和等级经验值外显两部分来讲解具体的设计过程。

Part1. 功能权益分层

功能权益分层是权益的使用层面,包括多场景触达和引导购买增量包。设计时分为场景梳理→设计要点→细化直播场景→具体设计这 4 步来实施。

Step A.场景梳理

拆解权益的生命周期,可分为三个阶段:充足可用,即将不足,已用尽。而功能的使用场景——直播,也分为三个阶段:直播前,直播中,直播后。

Step B.设计要点

将权益生命周期和直播场景结合进行交叉分析,列出设计要点和具体的设计拆解。

△ 不同阶段的设计要点及拆解

Step C.细化直播场景

发起直播的入口很多,除了「立即直播」的主场景之外,还有由预告进入直播的 3 种场景,如果在每个入口都做功能禁用判断的话,不仅逻辑会很复杂,开发实现起来成本也比较大。

于是将直播前的流程细化,发现「直播检测」是进入直播间的必经环节,因此将功能禁用的判断节点缩减为 2 处:「立即直播」&「直播检测」。

△ 细化直播场景

Step D.具体设计

有了前期的分析后,具体设计环节就相对容易了。下面以点击「立即直播」时的功能余量判断为例。

点击「立即直播」按钮,在按钮原有的逻辑上加上新的判断逻辑,此处要注意写清楚他们之间的优先级关系。如果在不了解背景的情况下,很可能就直接写点击按钮进行可用直播时长的判断,那需求宣讲的时候开发就会问你,和原来按钮上的逻辑是什么关系呢,此时就会一阵紧张。

△ 立即直播时判断剩余可用直播时长

Part2. 等级经验值

等级经验值属于展示层。对网师用户来说,最重要的是了解自己当前处于哪个等级以及相应的权益有哪些。对平台来说,除了明确每个等级及相应的权益,重要的是要引导网师升级,以激发他们的自驱力。

由此推导出相应的设计方法:锚定目标、降低门槛和利益点吸引。

△ 设计方法

在设计方法的指导下进行落地,分为网师后台首页的展示,以及等级详情页的设计两部分。

网师后台首页-个人信息模块的展示

由于等级和权益挂钩,涉及网师切身利益,因而在网师后台首页的个人信息模块,增加当前的经验值和相应等级的展示。同时,通过利益点吸引等方式,引导网师向下一个等级努力。

△ 个人信息模块展示

等级详情页的设计

点击等级进入详情页,除了 Lv0 是将所有权益无差别展示,其他等级都是优先展示新增部分,包括新获得的普通权益和附赠的高级功能。另外,用「箭头」和「NEW」的图标帮助用户区分是老权益的内容升级,还是新增的权益。

总结反思

1. 前期缺乏深入调研

由于涉及网师的切身利益,因而此功能受到了网师们前所未有的关注。上线前一周,运营以邮件、通知等形式向网师预热,3 月 5 日会上线这么一个功能。于是还没上线就有网师来咨询在哪里可以查看。刚上线就收到了大量的用户反馈,网师反馈群里的消息简直是秒速级地在刷屏。

其中,网师对每月直播时长限制的反响最为强烈,部分网师表示平台应该鼓励多直播,不能接受对直播时长的限制。因为直接关系到上课这个核心功能,时长不够课都上不了,网师们的言辞非常激烈。所以我们又重新评估了平台的直播成本,经过深入讨论,全面放开了每月的直播可用时长限制。

带来的反思是,如果前期有通过问卷、访谈等方式进行深入的用户调研,了解他们对核心权益的态度,那么在进行权益设置时就能有更全面的考量。

2. 中高等级跨度太大,缺乏激励效果

游戏任务的上手难度曲线一般是先平缓,再慢慢陡峭,越往上难度越大。我们的等级体系其实也是这个逻辑。初级到中级还较为容易,但再往上要非常难,要经过长时间的积累,一看就无望,难有激励效果。

因而我们之后的优化方向是在相邻等级中间设定一些小目标,达到可以提前赠送下一等级的新权益,以此来提高激励效果。

文章来源:优设    作者:鱼游设计

日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档