首页

HTML li 标签之间空白间隔的解决办法

seo达人

问题描述:

做抽屉式菜单时候,在 ie 7 下发现 li 元素之间会留白,如下图:







原以为是样式的问题,后来看到有博文写到“行框的排列会受到中间空白(回车\空格)等的影响,因为空格也属于字符,这些空白也会被应用样式,占据空间,所以会有间隔”。







解决办法:

li 标签之间的空白,可以通过设置 li 标签的 font-size 为 0,可以解决:



li{

    padding:0;

    margin:0;

    height: 30px;

    line-height: 30px;

    font-size: 0;          / 设置 font-size 为 0 即可 /

}

修改后的效果如图:



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

如何从0到1构建UI视觉层级?

涛涛

如“黄金分割”之于构图,“视觉层级”之于页面节奏,都是基础且必不可少。本文与你分享如果一步步从原型开始构建APP视觉层级。

工作中,你是否经常听到“视觉层级”这词?就犹如“用户体验”一样让人耳熟能详。抛开装逼因素,这两个词的多次提及,可见其重要程度。


音乐有节奏,好的音乐能通过音阶的高低起伏变化表达音乐情绪。

例如:《Main Title》即使你没看过《冰与火之歌》,光听音乐你是否能感觉到音乐给你营造千军万马恢弘之势。《Playing Love from The Legend of 1900》你是否想到一个宁静夜晚,佳人与你倾诉衷肠,柔情似水。

反之,节奏不好,则无法和听众达成共鸣。


绘画有节奏,张驰有度、大小对比、远近疏密变化,构成了画面的节奏。反之,没有节奏,则画面平淡。


同样的,APP UI也有节奏。页面良好的视觉层级,方便用户在浏览的过程中抓取关键信息,帮助用户快速达到目的。



那么,如何构建?


1.明确页面目的与需求主次

拿到原型,明确页面目的和需求的1、2、3层级,并理解消化。开启设计师的隐形技能:根据一句话或者一个词,在大脑开始构建画面布局。在构思阶段,建议同时浏览同类型UI设计以及交互布局,在找参考的过程中,结合自身APP的页面目的一起构思,并在纸上绘出可行性方案。 


由于,APP是为人服务。那么我们需要知道,人眼浏览习惯模式的科学依据。



2.人眼浏览模式

曾有一数据显示:如果在3S内无法吸引用户,你将流失这个用户。如今我们所在的时代快节奏、碎片化,用户的日常浏览是“扫描”而非“阅读”。所以,了解人眼浏览习惯,变得十分重要。

人眼浏览习惯有:F型;Z型;其他;


F型浏览模式

Z型浏览模式

还有,其他浏览模式,海哥HMI人机交互在他一篇文中《用户是怎么阅读的?尼尔森F模型》提到:


蛋糕模式:眼睛只关注标题和副标题时,水平一层一层;
斑点模式:跳过大块的文本和扫描,寻找特定的东西,比如按钮,数字;
标记模式:轻扫页面时,将眼睛聚焦在一个地方,呈圆形分布。(移动端会常发生);
承诺模式:通篇阅读,用户确实充满动力和兴趣。


在明白人眼视线流程后,我们开始运用视觉手段,吸引用户来看我们想给他看的内容,并按照我们的预想顺序,依次阅读。



3.设计手法


a.对比

对比,让视觉有轻重,用户看起来不累。需要强调的信息放大,没那么重要的东西缩小。如果同一层级的模块,通过颜色或者样式的变化来表达。如:字体大小对比,颜色对比;模块大小对比;图片大小对比等。 


b.字重

字体千千万形状各不相同,然而他们都有着相似之处:字重的大与小。在同一字号大小下,字重大的笔画,以面构成,会比字重小的,更具视觉冲击力。

需要强调的信息,字号变大,字体加粗,这样就能区分主与次,建立更易读的视觉层级。 


c.样式

为了各个模块间的和谐组合和视觉上的凸显与美观,我们需要灵活运用各种样式表达。卡片投影;形状;材质等; 


d.模块化整合与留白

同一类别信息,模块化整合。便于用户浏览操作,视觉上不零散,整体美观。多模块化的组合,注意留白以及页面的节奏轻重。 


以上要点,要根据实际情况灵活巧妙运用。在做的过程中,通过Mirror工具实时查看页面效果,不断改进,加强表达。


总结


宗白华说过:“一切艺术都趋向音乐”。确切说一切“广义的”艺术都趋向于音乐状态。优秀的UI视觉层级表达,就如音乐一样有节奏变化,波浪起伏,是一种视觉享受。无论是平面还是UI,视觉层级,需要像“黄金分割原理”一样,是内化进设计师的身体里一个元素。多多实战练习,不需要死记硬背,就会刻在我们的大脑深处。 

文章来源:站酷

2B SaaS 产品用户系统设计

涛涛

无论是2B产品,还是2C产品,用户系统都是基础。对于非互联网产品从业者,2C用户系统的场景和功能通过日常各类APP的使用,大家都非常熟悉。因此,笔者通过和2C产品的对比,谈谈2B SaaS产品的用户系统设计。

一、商业的本质差异,决定了产品的核心目标

2C产品面向的用户是个人,用户系统的核心是获客,因此大多2C产品的用户系统设计重点在于方便用户注册、登录,能够建立精准的用户画像,从而达到流量变现的目标。

2B产品面向的用户是企业,用户系统的核心是组织、员工精细化管理,提升人效,从而实现节约成本的目标。

二、业务场景的需求差异,决定了产品的细节功能

1. 注册场景

2C产品的注册主要用于个人用户注册场景,重点在于提供多种渠道的注册方式,如账号、手机、第三方社交应用(微信、微博等),其核心目标是既能方便用户注册,又能多渠道多平台账号打通。

2B产品的注册分为两部分:企业管理员代表企业注册和企业员工注册。

2B平台型SaaS产品,和2C最大的区别在于产品需要用户付费。因此,平台方为企业(平台租户)提供了注册入口,一方面需要方便租户能够通过其他渠道快速注册试用产品,一方面需要验证企业相关信息,识别该用户确实为潜在用户。

1)企业注册:

当企业管理员代表企业注册时,需要提供的注册信息:管理员昵称、手机号、邮箱、企业工商信息(名称、组织机构代码、地址、法人信息等)。

其中工商信息的完整度,不同的产品要求不一样,需要根据具体产品而定。如果方便注册拉新,尽量减少工商信息填写要求,如果产品安全性要求较高,可以尽量要求工商信息填写完整。

2)企业工商信息认证:

这部分并非强需求场景,取决于产品的安全性要求。一般安全性要求较高的平台产品,会在企业注册后,进入到企业工商信息认证环节。此环节要么是平台管理员人工审核,要么通过第三方认证验证企业工商信息是否合规。企业完成认证后,即可试用产品。

如非安全性要求较高的产品,可以直接跳过该环节,租户通过注册页信息填写完整后既注册成功。

3)企业员工注册:

  • 注册信息:昵称、手机号、邮箱、其他个人信息;
  • 被动邀请:一般B端产品多作为企业员工日常作业工具,因此多采用管理员开通账号制,管理员通过后台将员工信息注册至系统,员工即可登录。被动邀请制员工和公司属于强绑定关系,员工账号不可以独立存在;
  • 主动注册:员工主动注册场景中,员工主动注册产品账号,然后再申请加入企业,由企业管理员审核通过后,和企业进行关联。该方式个人用户既可以独立作为平台产品用户,又能够以某公司员工的身份作为平台用户。钉钉即为典型代表,该类产品,一个员工可同时加入多个企业;
  • 个人资料:员工注册后,该员工信息注册至系统,并能够在系统中展示、查询、完善个人信息资料。

2. 登录场景

登录场景比较容易理解,目前B端产品相较C端产品仍然比较传统,多采用邮箱/手机进行登录。

未来也希望可以实现,B端产品能够和更多C端产品平台打通,可通过通用的第三方账号进行登录,实现业务与社交的连接。

3. 用户画像

用户画像是2C产品至关重要的内容,只有精准的用户画像,才能更精准的服务好用户。无论是电商,还是资讯平台,基于用户画像的精准营销投放才是产品的核心。

2B的产品很少有讲用户画像相关的内容,事实上对于2B产品而言,用户画像也至关重要。

笔者目前从事CRM产品相关工作,CRM核心要解决的问题就是帮助你的客户获客,那么如何去建立客户的企业标签,去按照企业标签属性,借助大数据分析,帮你的客户找到他的客户群,是笔者近期在研究的课题。

  • 建立企业属性维度标签:如行业、规模、业务范围、客群范围。
  • 竞争企业标签关联性模型分析:便于了解市场环境、分析竞争企业,及时调整公司战略。
  • 潜在客群(企业)标签关联性模型分析:利用数据分析模型,帮助企业识别潜在客户,提高企业获客率。

4. 组织结构

2C的产品从本质上来讲不存在组织结构,个人用户即为产品主体,但会存在群组/社群的概念。

2B产品的应用主体是企业,而组织结构是企业运营管理的必要手段和方式。因此组织结构管理是用户系统的重要组成部分。

1)建立组织结构

组织的单元是部门,因此管理员需要能够按照企业组织结构建立、调整(编辑、合并)、删除部门。

2)部门树结构

部门作为组织结构的单元,只是组织结构的分子,而要形成组织,就要按照企业的业务形态要求形成一定的层级体系。因此部门不仅仅只是简单的信息描述,还需要有层级描述,这就需要我们在建立部门时按照层级结构建立部门,定义清楚所建立的部门是上级部门、下级部门。

3)通讯录展示

管理员通过后台创建完组织结构后,企业员工可通过前台查询按照部门结构展示的通讯录。

5. 角色管理(该部分是2B用户系统设计的重点和难点)

角色管理是B端产品的特有功能,企业员工按其所负责的业务模块划分不同的岗位职责。

由于企业数据具有较高的安全性和私密性要求,按照岗位职责的不同,不同岗位的员工对于业务数据的操作/查看权限不同。

因此,我们设计了角色管理,该角色并非严格意义上的岗位职能角色,而为了区分不同的员工不同的系统权限所设计的系统角色,这就是RBAC设计。

1)建立角色

建立角色的主要目标即为建立一个用户权限组,该权限组内的用户具有相同的权限。

2)分配角色权限

基于角色分配系统权限,以实现不同的角色下的用户拥有不同的权限。

  • 功能权限:用于设定该角色能够使用哪些产品功能,如果不属于该角色业务范畴内的功能可以直接对该用户屏蔽,避免过多的功能菜单干扰用户对产品的使用。
  • 功能操作权限:企业管理越精细,员工负责的工作越具体,一个功能内,不同的人按照其职责进行不同的操作划分,为了保证数据的正确性和安全性,需要给不同的角色分配同一功能下不同的操作权限。
  • 功能内的描述字段权限:一个业务功能中有不同的属性描述字段,但不同的角色关心的属性不一样,为了能够进行区分,需要给不同的角色去设定不同字段的读/写权限。
  • 数据权限:企业数据本质上是企业资源,既具有私密性又具有共享性。一个角色具有该功能的一定操作权限,但是他能操作该功能下哪些数据?只能操作他本人创建的数据,还是能操作其他员工创建的数据需要通过数据?这就需要用数据权限来控制。这就要求当数据被创建,该条数据也需要相应的字段来描述该条数据的所属关系,该数据属于哪个用户,属于哪个部门,最终才可实现人和数据的关联,以实现基于员工角色的权限管理。

6. 员工管理

员工管理是B端产品的特有功能,员工是企业组织的重要组成部分,员工也是产品真正的终端用户。

B端产品从本质上是要能够帮助企业员工提升工作效率,提高企业人效,以实现企业管理者降低运营成本的目标。

1)新建员工

前面提到的用户注册即为新建员工的过程。包括被动邀请主动注册两种形态,主要目标是将员工信息注册至系统,并建立员工和企业的关联关系。

2)建立员工汇报关系结构

为了实现精细化管理,企业内部一般按照组织结构设定员工的汇报关系,因此从CEO到基层员工会形成组织关系树,该结构可以和组织结构完全一一对应,即该部门下的所有员工均汇报给部门负责人,但也有部门内部分不同的小组,不同的人汇报给不同的小组负责人。

因此汇报关系和组织结构关系有一定关联,但并不是完全一一对应,所以我们需要设计员工汇报关系功能。

3)员工离职设定

为了保证企业数据的安全,员工离职后,需冻结员工账号,离职员工将不能以该企业员工的身份登录系统,以确保企业数据的安全性。

  • 设定离职将员工账号设定为离职状态,员工账号被冻结;
  • 数据转移:员工离职后,其业务需要其他员工来接替,因此该员工在职时负责的业务数据需要被转移给新的用户,此部分功能需要在数据转移功能中进行规划。

至此,2B用户系统的功能基本设计完整,其重难点在于组织结构、权限控制,需要重点关注。

文章来源:人人都是产品经理

li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?(十三)

seo达人

li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

引起这种空白间隔的原因:

浏览器的默认行为是把inline元素间的空白字符(空格换行tab)渲染成一个空格,也就是我们上面的代码



换行后会产生换行字符,而它会变成一个空格,当然空格就占用一个字符的宽度。

解决方案:

方法一: 既然是因为< li>换行导致的,那就可以将< li>代码全部写在一排,如下





<div class="wrap">

<h3>li标签空白测试</h3>

<ul>

<li class="part1"></li><li class="part2"></li><li class="part3"></li><li class="part4"></li>

</ul>

</div>

1

2

3

4

5

6

7

再刷新页面看就没有空白了,就是这么神奇~



方法二: 我们为了代码美观以及方便修改,很多时候我们不可能将< li>全部写在一排,那怎么办?既然是空格占一个字符的宽度,那我们索性就将



内的字符尺寸直接设为0,将下面样式放入样式表,问题解决。

.wrap ul{font-size:0px;}

1

但随着而来的就是



中的其他文字就不见了,因为其尺寸被设为0px了,我们只好将他们重新设定字符尺寸。

方法三: 本来以为方法二能够完全解决问题,但经测试,将li父级标签字符设置为0在Safari浏览器依然出现间隔空白;既然设置字符大小为0不行,那咱就将间隔消除了,将下面代码替换方法二的代码,目前测试完美解决。同样随来而来的问题是li内的字符间隔也被设置了,我们需要将li内的字符间隔设为默认。



.wrap ul{letter-spacing: -5px;}

1

之后记得设置li内字符间隔





.wrap ul li{letter-spacing: normal;}

1

2

详细看这篇文章 li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

9个容易忽略的iOS与Android间的交互差异

涛涛

因为现在大多数的PM/交互/UI设计师,在设计产品的时候都是以iOS为基准 思考产品上的各种功能逻辑、交互状态,而很容易忽略了某些功能在Android里并不能“一稿适应两端”,部分产品差异在安卓上是不一样的。

所以本文就讲下Android和iOS 10大产品/交互差异,希望你在日后的产品设计时,可以考虑到更多层面的知识点(可能在某些安卓高级机型里并不通用).

01 虚拟商品 支付规则和方式的不同

1. 支付规则

对在于一些虚拟商品的支付上,如vip会员、xx币,xx豆。iOS和Android就存在不同的支付规则:Android基本无限制,无抽成。而iOS限制比较多,而且要抽成大约30%的手续费。

举个例子:同样充值30元,Android端会得到300金币,而在iOS中,只有210金币。正因这个抽成规则的不同(没办法,这是苹果硬性规定的),才会出现各种平台的虚拟货币,在Android和iOS中的充值比例是不一样的,如快手:

所以对于虚拟商品在iOS端的抽成规则,在产品设计时一定得考虑清楚,因为这关系产品的商业和盈利模式。通常有2种解决思路:

A. 让用户承担30%的抽成

a. 同样的价格,iOS用户得到的商品少些

如同样充值30元,Android端会得到300金币,而在iOS中,只有210金币。像快抖音、陌陌等各种货币充值。

b. 同样的商品,iOS用户支付更高的费用

如3个月的vip会员,Android端定价是58元,iOS端则可以设为68元。如优酷、腾讯视频的vip会员价格。

B. 公司自己承担30%的抽成

如iOS端充值30元,公司实收21元,但iOS用户能得到和Android一样的300个金币(理论上是有这个解决思路,但现实中很少有公司去实现,毕竟抽成成本就摆在那里).

另外还需要注意的是:因为抽成规则的不同,对于一个ID的账户余额,在Android和iOS端中是不能通用的。因此在产品设计时需要将这个点告知用户,预防用户犯错、以及恶意刷币。

2. 支付方式

Android由于开源的特性,因此对接的都是第三方支付平台,如微信支付、支付宝、银联卡等。

而iOS出于系统的封闭性和安全性考虑,只能调用苹果自己的支付系统:登录APPle ID,然后用授权的支付方式(支付宝、银联卡)进行付款。

02 状态栏交互的不同

“状态栏”也就是我们手机界面最顶部的电池栏,它除了可以在不同背景里切换颜色外,在交互的触发上,Android和iOS中也各不相同。

  • iOS:用户在Y轴滚动了很长内容时,点击状态栏可以快速回到初始位置。
  • Android:无论用户滚动了多长内容,都是点击无任何效果。

虽然这一交互差异是iOS专有的,但它却启发我们一个新的设计思路:在必要的时候,状态栏可以为产品承载新的交互状态。如网易的LOFTER(iOS端),用户离开音乐播放界面时,状态栏就用于显示音乐信息和操作入口,方便用户在浏览其他内容时可以快速关闭音乐时,极大提升了用户的操作效率。

03 下载方式和状态的不同

这种大多应用于运营的“拉新”场景,为了能新用户得到好处(红包、优惠券、更好看的内容等)。通常会让新用户下载产品APP领取。而由于Android与iOS的下载方式不同,会带来不同的交互状态和产品逻辑。

Android

可以在当前页面(后台)下载,也可以在应用商店下载;过程中可以显示进度,且允许用户暂停下载;下载完成后调起安装页面,用户可以取消安装,也可以自动安装…

正因为Android下载软件的各种便捷性,所以才会带来各种交互状态:未下载、下载中、暂停中、已下载但未安装、已安装。这些都是交互设计师需要特别注意的,每个不同的状态背后都会不同的产品逻辑。

iOS

只能跳转到App Store里下载,所有下载流程和状态都是在那完成的,可以脱离开活动页面,相比于Android的下载方式就简单很多。跳转的方式可以是全屏幕,也可以是半屏。

04 软件更新方式的不同

Android

由于安卓的开源特性,当有新版本时都会提示用户更新,且每个产品内部都带有“版本更新”入口。而更新的方式可分2种:

  1. 引导更新:弹出提示让用户更新APP,用户点击“更新”按钮前往应用商店更新、或者在当前页面更新并显示下载进度。
  2. 强制更新:也是先提示用户更新,只不过用户点击“更新”按钮,即调起软件安装页面。(前提是产品已在用户处于wifi模式下,将安装包已下载完成)

iOS

而iOS端出于对用户体验的考虑,是禁止向用户提示版本更新信息的。这也是为什么绝大部分的iOS产品,都是没有“版本更新”入口的原因(像QQ、支付宝、百度网盘等大厂产品)。即使有,点击了也直接跳转到App Store查看版本情况。

且下载渠道都固定在App Store里。理所应当的,软件的更新方式也只能在App Store里进行,无法做到与Android的一样做到后台下载、后台更新。

05 文字发送指令 位置的不同

在手机键盘里输入文字时,iOS由于系统的限制,对文字的发送指令只能在键盘上来完成,因此iOS用户的交互操作都全部集中在键盘右下角。

而Android端就灵活很多,不仅可以在键盘上执行发送指令,也可以在输入栏/搜索栏周边新增操作入口。

06 退出浮层列表的不同

长按一张图片后,都会弹出一个列表浮层,因为iOS手机只有一个“Home键”而已,为方便用户退出浮层才增加了“取消”入口。

而Android手机本来就有“返回”虚拟键,安卓用户的退出/返回行为都习惯于通过虚拟键触发,所以多做一个“取消”的意义性不大。

07 删除方式的不同

iOS端一直教育着用户使用“左滑”删除列表信息,所有的删除功能都是支持“左滑”来实现的。

而Android系统大部分只能通过“长按”来触发编辑状态,其中就包括了删除功能。不过现在也有极少数的产品,正在逐渐打破这两端间的“删减”界限,比如网易邮箱(Android)就做到了左滑删除信息。

08 消息推送机制的不同

当我们第一次打开产品、允许了获取消息通知的权限后,所有的信息传输都会基于服务器进行推送。而两端在这块的推送机制又有所不同:

iOS

所有新信息都会实时推送到你的手机里,即使你关闭了软件,还是一样会收到提示。就算使你处于断网状态,信息也会先储存于苹果服务器,等你联网时再一次性把收到的信息推送给你。既释放手机内存,又不会让用户遗漏有新消息。

Android

而安卓则不同,你若退出了产品,数据的推送只有等你再次打开产品时,才会通知你有多少新信息。虽然减少了对用户的干扰性,但也增加了服务器数据储存的压力,还容易耽误用户接收新消息。

09 复制文字后,剪切板状态的不同

也就是我们手机的输入法键盘,在微信聊天内、手机短信里复制了一段内容后,由于Android与iOS的平台特性差异,会给两端用户带来了不同的交互差异。

iOS

复制完文字后,打开输入法键盘会显示来自剪切板的文字内容。用户只需点击,即可将文字复制在搜索栏、输入栏等需要文字填写的操作区域里,无需触发“粘贴”操作。

Android

而有些安卓机(如小米/锤子/乐视等),无论你复制了什么信息(文字、数字、网址等),都很难实现输入法里的“剪切板”功能。用户需要触发“粘贴”功能,才能输入将刚刚的复制内容。

而对于特定的信息类型:如网址。用户复制网址往往都带有极强的目标性、搜索性,一些浏览器产品会预判用户这一操作行为,将复制的网址前置展示出来,以抵消Android端对于复制文字带来的系统限制。如QQ浏览器(安卓端)就有2种解法方法:

  • 方法1:利用安卓系统的消息权限,在手机界面的顶部弹出网址栏提示,无论是在微信还是短信中,复制网址后都能快速地触达目标。
  • 方法2:复制网址后打开搜索功能,会将网址自动定位并粘贴到搜索栏中,便于用户查询。

而UC和百度也有类似的解决办法:将复制后的广泛信息(文字/数字/网址/邮箱地址等等)嵌入在搜索框下方,用户点击就能搜索。

这也是一种妥当的解决方法,因为用户可复制的信息类型特别广泛、目标不是很清晰。无法准确判断出用户一定会有搜索诉求。所以才将复制后的信息放在搜索框下面,而不是自动粘贴到搜索框中,既考虑了用户目标,又兼顾了操作效率。

总结

以上就是Android与iOS的差异总结,若有描述得不当请多指教!下面是总结文件。

文章来源:人人都是产品经理

互联网的下半场,产品经理正在离开舞台中心

涛涛

互联网发展业已进入下半场,众多互联网产品的营销比重迅速攀升,用户心智已经形成,很多产品设计方面没有太大发挥空间。未来,面对严峻现实,产品人的选择在哪里?

前段时间一款叫ZAO的换脸APP刷屏朋友圈。这款产品的主要功能是把影视片段中明星的脸换成你的脸,让你实现大片梦。

实际上,在ZAO之前,就已经有厂商开发出了同类型的换脸APP。今年的四月,一款名为颜技的App上线了IOS版,它具有和ZAO相同的图片换脸到视频功能。不同的是,它没火起来。

互联网的下半场,产品经理正在离开舞台中心

相反是由于ZAO的大火,已经上线好几个月的颜技才突然被人发现。并因此登上了娱乐免费榜的第二名,第一名是ZAO。

AppStore上有上百万个APP,想要让别人找到你的APP已经非常困难了。回顾最近火起来的那些APP,大部分都有“重营销”的影子。比如绿洲、ZAO、灵鸽等。

营销对于一款产品来说变得越来越重要

刘润老师写过一篇文章《如何判断一个行业是否值得进入》描述这种商业竞争的规律:文章里提到了一个行业的发展阶段可以用商家的竞争手段去判断。

  • 竞争早期:产品为王;
  • 竞争中期:渠道为王;
  • 竞争后期:营销为王。

实际上这个观点就是用4P的视角去理解商业规律。商业的本质实际上就是4P模型:产品、渠道、促销、价格。而且这几个点的优先级是依次递减的。

一个项目想要成功,就需要依次做好这些点。如果别家已经在某一个环节做得很好,你再想超越,就必须也做好这一环节,然后在下一个环节做得更好。

因此在某一个特定领域内,对于后来者来说,创业会越来越难。王兴在几年前说互联网进入下半场,目前看来这个下半场里,产品经理已经不在是舞台的中心。

现在越来越多的产品偏向营销驱动,这很值得我们用4P的视角去思考一下互联网的发展现状和趋势。

早期:产品为王

在移动互联网时代的早期,有很多需求可以从线下搬到了线上,或者从PC端转移到手机端。由于这类用户需求是一直存在的,用户会自发地去寻找这类型的APP。

在这个时期,“产品即营销”,只要比别人做的更早,比别人做的更好,不太需要广告的支持,用户会自带传播效应。这个时期是产品人最爱的时期,只要用心做好产品,就很容易获得成功。

最初在移动互联网上,没有一款比较方便的社交软件。然而用户实际上是有很强的社交需求的。虽然手机QQ可以解决一些问题,但是没有为移动互联网的环境做相应的优化。

另一个款产品米聊,虽然也是为了解决移动互联网的社交问题,但是产品稳定性不足,偶尔会闪退或者发不出消息的情况。

微信在那个时期是移动互联网做社交做好的产品,所以经过用户的自发传播,两个月就超过了米聊成为了最大的移动互联网社交APP。

很多人认为微信的成功是因为获得了QQ的关系链,实际上这是一种误解。

当时运营商忌惮微信,不允许微信用手机通讯录,于是微信只能用QQ登录。

但QQ登录和QQ关系链是两回事。QQ登录不等于关系链的使用,微信对QQ关系链的使用,只是添加好友时可以从QQ好友里选择。

事实上作为一款熟人社交软件,手机通讯录的价值和作用更大——因为是更真实的好友,而QQ好友里很多是陌生人。如果微信当时选择把QQ关系链复制过来,那就成了另外一个手机QQ了。

所以微信的成功,是因为它在产品为王的时代,做出了最好的移动互联网社交工具。

中期:渠道为王

在互联网时代的中期,同一个细分领域会出现了很多同质化的APP。这时,竞争考验的是各个公司的渠道能力。

你能更好地触达用户,就能更地扩展市场。

早在PC互联网时代,搜狗输入法就依靠“番茄花园”、“雨林木风”等盗版系统的预装,仅用一年时间做到了输入法领域70%的市场占有率。

在移动互联网时代,新闻类APP的同质化也比较严重,在产品端的优化很难和其他竞品拉开差距。为此搜狐早晚报(搜狐新闻的前身)依靠中兴手机的预装,一下子从几万日活提升到上百万日活。

在国外的Twitter模式兴起时,四大微博的竞争进入白热化阶段。最终新浪微博突出重围,成为了最后的赢家。

新浪微博的打法也是依靠渠道。当时新浪微博抢先与头部的手机厂商签下独家合同,激活一个用户支付厂商1.5元,很多手机厂商看到好处都选择了合作。

后来这笔钱改成了资源置换。手机厂商预装新浪微博,而微博会在用户在发布手机动态时,露出手机品牌型号。

除了预装,SEO和ASO也是非常重要的渠道来源。

今日头条早期的SEO要比其他公司效率更高。

一般我们在百度进行渠道投放时,只知道投放相关的关键字,这种常规操作的结果是量少、多家竞价、转化效果不佳,而且成本非常高。

今日头条创新性地利用每天百度新产生的大量没有人竞价的关键词进行拓词,通过技术手段自动生成聚合这些关键字的落地页,然后在百度进行投放。这样做的好处是量大而且价格便宜,落地页聚合的内容本身比百度的还好,用户转化效果自然就非常理想了,大大降低了渠道投放的成本。

优质的搜索渠道流量,也是今日头条成功的一大因素。

后期:营销为王

到了互联网时代的后期,就连渠道商的竞争也同质化,并且渠道商的价格越来越高。

在这个时期,厂家会发现争夺渠道效果已经很差了,几个大的渠道已经被巨头们把持了,想要突破必须开始争夺消费者的心智。所以这个时期的策略是通过吸引眼球的营销方案,让用户产生购买意愿。

支付宝诞生的时候是产品为王的时代,解决了用户线上支付的问题,因此作为先驱者占据了线上支付的绝大部分市场份额。

腾讯作为支付领域的后来者,想要超越支付宝,怎么办?

财付通是腾讯的第一次尝试,依靠腾讯自己的电商渠道,财付通的市场占有率一度只有3.3%。这是因为错过了产品为王的时代,而且在渠道为王的时代,腾讯的电商品牌也不是特别给力。

后来腾讯有了微信,然后有了微信支付。其中最大的使用场景是微信红包。

微信红包依靠用户的自发使用,在2014年春节达到了458万的用户峰值。但之后的几个月,用户数从峰值持续下降,再也没有回到这个数量。

照理说,微信红包的产品没问题,渠道更没问题,微信的用户量级可是比腾讯的电商用户多得多。这时腾讯要再想突破,就只能从营销端思考。

2015年,微信和春晚合作,搞了一个摇一摇抢红包的活动。那天晚上,微信红包的用户数从400万增加到了一亿,而支付宝积累一亿用户用了大概8年的时间。

在几年前,如果有人告诉你,做一个拼团类低价购物APP很有机会,你一定会对此嗤之以鼻。电商市场又不是没有人做过这件事,就算是淘宝的聚划算也没做得太成功。

但是今天,拼多多依靠社交裂变的玩法,已经成了“五亿人都在拼”的电商巨头,市值都超过了百度。

拼多多杀入市场时,电商领域的产品、渠道都已经进入了白热化的竞争阶段。拼多多从营销端发力,大力开展社交裂变的玩法实现了电商领域的突围。

虽然拼多多的玩法也有价格的因素在里面,但是同样有很多主打低价的产品却没法做到拼多多的规模,最主要的还是营销的问题。现在很多人想到买低价的产品,第一个想到的就是拼多多,这也说明了拼多多的营销成功地抢占了用户的心智。

另外,这个阶段想要超越不单单是要做好营销,而是之前的产品和渠道都不能少。

上述的两个案例都是产品本身过硬,并且凭借微信这个大渠道作为基础的。

其他的竞争阶段也是一样,必须做好前面阶段需要做的工作,再做好当前的阶段需要做的才有可能追赶领先者。

这是很多人学习4P理论时最容易忽视的点。

大后期:价格为王

如果按照4P理论,刘润老师还应该补充最后一个阶段——价格为王。

单纯价格战这事技术含量太低,似乎不值得单独来讲。不过作为一种商业趋势,目前互联网行业部分领域的竞争态势俨然已经走到了这一步。

在信息流领域,等到今日头条成长到非常大的体量后,百度才反应过来。

为了快速夺回市场,百度在2019年的春晚狂砸9亿红包“买客户”。这个活动和之前提到的微信红包活动很像,但是仔细思考还是有一些不同。

互联网的下半场,产品经理正在离开舞台中心

春晚面对的几乎是全国的观众,其中很多人平时并不太接触互联网。对他们来说,微信的抢红包活动是没见过的玩法,很新奇,很有传播性。

微信抢红包的这次活动,营销的概念其实要要大于价格的概念。但是经过了这一次的用户教育,加上之后的支付宝集五福活动,这种送钱的营销活动对用户来说已经不陌生了。

百度的红包活动更多的用户已经不是觉得好玩,而是单纯地在衡量投入产出比。为了拿到这些红包的钱,付出那么多时间划不划算。这成了单纯的买用户,单纯的价格因素。

最近微视也搞了一次这样的活动,邀请好友得3~10元的红包。这说明短视频领域也已经进入了竞争的大后期。

价格为王的阶段是其他手段都失效的情况下,不得不采用的策略。

当然前提是产品足够好,否则用户也是留不下来的。

有哪些启发?

1. 产品经理的时代可能正在过去

这里说的产品经理是那种创造性的产品设计工作,类似乔布斯、张小龙所代表的最初的产品经理的定义。

随着现状互联网解决的问题越来越多,边界越来越广,想要再通过创造性的产品设计打动用户已经非常困难了。而且很多功能模式都有了约定俗成的规范,发挥创造性的空间已经不大了。这导致现在的产品经理更多的是偏向项目管理而不是产品设计。

我的一个产品经理朋友,觉得自己原来所处的行业相对比较传统,换了一家更加迎合年轻人的行业。

但是现实马上教他做人,虽然新公司的产品更加年轻化,但是产品经理的工作其实没有太大的变化,还是以画原型、项目推进为主。

在可预见的未来,产品经理将离开互联网的舞台中心。

运营人才将接替产品经理的位置,站在在互联网的舞台中心引导之后的风向变化。当然,这里说的是大部分一线产品经理,如果你是牛人,你永远都站在舞台中央。

2. 要找到适合自己的行业

不同竞争阶段的工作重心是不一样的,所以在做职业选择时,最好选择那些适合自己发挥的行业和公司。

如果你是产品经理,那么最好是进入还在产品为王时期的行业。

如果你是渠道BD,渠道运营等,选择那些竞争中期的行业。

如果你是活动运营,那么最好去那些竞争非常激烈的行业。

在适合自己的行业中,你的重要性得到了提升,拥有更多的机会学习和实践,对于自我提升来说是事半功倍的。

3. 找到对的公司

有很多创业公司还保持着产品为王时代的思路。

它们所处的行业很可能已经在营销为王的时代,却还抱着精细打磨产品的意识,根本原因仅仅是因为领导者是产品和技术出身。

这类公司如果渠道端和营销端没有比较好的动作的话,很可能在烧光融资后就被迫关闭。而失败的原因不是因为产品做的不够好,而是没有在正确的时间做正确的事。

有一些公司好一些,它们在产品为王的时代,通过打造优秀产品而崛起。但这种公司很容易形成路径依赖,原来我们通过产品的优化成功了,那么现在就要继续做好产品这件事。

但是产品体验的护城河会慢慢被竞品攻占,如果领导者不转变身份,从“首席产品经理”变成精神领袖,那么很可能就会慢慢衰败。

因为成功的企业家与市场的用户的需求距离太远,如果太专注抓产品的单点突破,就意味着在商业格局平衡和公司长远战略上的短视,结局自然不会太理想。

文章来源:人人都是产品经理

后台返回json数据给前台和前台解析json数据(总结)

seo达人

后台返回json数据给前台和前台解析json数据(总结)

一般来说web开发中,前台采用json数据提交给后台,后台处理数据以后返回json数据给前台,前台解析json,显示数据。

总而言之,前后台直接交换的数据格式最常用的非json数据无疑了。

这里就总结一些json数据的前后台处理方式。



1.JSON数据

JSON(JavaScript Object Notation, JS 对象简谱)



是一种轻量级的数据交换格式,比xml更轻巧(由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用的带宽)。



json是javascript原生格式,就是说在javascript中处理json数据,需要引用其他API或工具包。



简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。



只需要记住!

Json是一种文本字符串!被存储在responseText属性中,而读取json数据可以使用javascript的eval函数来解析json。



2.json规则:

在 JS 语言中,一切都是对象,对象是一个无序的 “键/值” 对集合。

因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:

对象表示为键值对.

数据由逗号分隔.

花括号{}保存对象.

方括号[]保存数组.



键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:



{"firstName": "Json"}

1

这很容易理解,等价于这条 JavaScript 语句:



{firstName : "Json"}

1

对象在 JS 中是使用花括号包裹 {} 起来的内容,数据结构为 {key1:value1, key2:value2, …} 的键值对结构。



在面向对象的语言中,key 为对象的属性,value 为对应的值。



键名可以使用整数和字符串来表示,值的类型可以是任意类型。



数组在 JS 中是方括号 [] 包裹起来的内容,数据结构为 [“java”, “javascript”, “vb”, …] 的索引结构。



在 JS 中,数组是一种比较特殊的数据类型,它也可以像对象那样使用键值对,但还是索引使用得多。同样,键名可以使用整数和字符串来表示,值的类型可以是任意类型。



3.JSON 与 JS 对象的关系:

很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:

JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

如:



var obj = {a: 'Hello', b: 'World'};    //这是一个对象,注意键名也是可以使用引号包裹的

var json = '{"a": "Hello", "b": "World"}';  //这是一个 JSON 字符串,本质是一个字符串

1

2

4.后台返回json数据

一般来说,使用JsonObject来将Java类型数据转换成Json类型,首先要下载该库相关的jar包,下载地址如下:



json-jar包下载



JsonObject的使用:

后台controller部分代码:



JSONObject object = new JSONObject();  //创建Json对象

object.put("username", "张三");         //设置Json对象的属性

object.put("password", "123456");

System.out.println(object.toString());  //调用toString方法将json对象转换成json字符串



//把json数据返回给浏览器:

PrintWriter out = cu.getWriterOut(response);

out.print(object.toString());

//或者

response.getWriter().write(jsonObject.toString());



1

2

3

4

5

6

7

8

9

10

11

5.在JavaScript代码中接收Json数据:

假设result为浏览器得到的json数据,可以使用以下js代码可以将json对象转换为字符串。



比如:



通过$.get从后台获取了一段json串{“id”:“1”,“name”:“ww”},然后要拿到这里面的id和name值:



注意!注意!注意!

如果你直接这么写!



$.get(url,

     function(data) {

       alert("ID:" + data.id + "\nName:" + data.name);

     });

1

2

3

4

直接这样写的话,界面会alert提示undefined,因为没能正确解析返回的字符串。



图示:





解决方案:



1、 需要用eval()函数



将返回的串转化成可用的strig串,eval(data),但是因为原串里面是以{}开始和结束的,会被认为是可执行方法,因此需要加上()包围起来,最终形成:



var jsonobj= eval('(' + data + ')');  // 把JSON字符串解析为javascript对象

1

然后再



alert("ID:" + jsonobj.id + "\nName:" + jsonobj.name);

1

各种正常的按key取值,就能正常显示了。



2、获取的时候就直接表示返回的是json格式,用.getJSON代替 .getJSON代替.getJSON代替.get,其他代码不变,也能正常获取。



也可以直接获取json对象的属性,如下:console.log(result.username);



前端js代码:



$.ajax({

url: url,

type: "POST",

data: parameters,

dataType:"json",

async: false,

success: function(result){

var newData = JSON.stringify(result);    //将json对象转换为字符串

newData = eval("("+newData+")");   /解析json



var annualDays = newData.annualDays;

var entryDate = newData.entryDate;



$("input[name='extendDataFormInfo.value(fd_shengyu_nianjia)']").val(annualDays);

$("input[name='extendDataFormInfo.value(fd_ruzhi_date)']").val(entryDate);



}});



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

ps: 注意注释中的代码,如果少了这一句,那么直接alert(result);得到的结果会是







所以在这里stringfy()的作用是用于从一个对象解析出字符串

加上了var newData = JSON.stringify(result);这句,然后你再alert(newData);

得到的就会是你想要的结果,如下:





另外:

如果返回的json数据格式不是很规范的解决办法:



判断后台返回的数据格式是否字符串,是则转,不是则不转?



  var $obj = (typeof data.content == 'string') ? JSON.parse(data.content):data.content

1

总结:



前台发送请求,并且设置数据为json格式‘

    $.ajax({

    url:"selectByid.",

    datatype:'json',

    data:{id:id}, // 发送数据 

1

2

3

4

数据回调函数

success:function(data){

alert(data);

var json = eval("("+data+")");//将json类型字符串转换为json对象

alert("hjf"+json.name);

1

2

3

4

给对应的input赋值:

$("#id").val(json.id),

$("#name").val(json.name),

$("#age").val(json.age);

1

2

3

后台代码:返回json数据

response.getWriter().print(str);    //将数据返回前台ajax

1

6.前端ajax接不到json解决?

在前台:



async:false,                //加上这个属性就好了

1

7.返回的json字符串中有转义符解决?

比如:



"result":"{\"id\":\"60\",\"qid\":\"1\",\"bazi\":\"baiz\",\"shenxiao\":\"\",\"xingzuo\":\"\",\"wuge\":\"\",\"jianyi\":\"\",}"

1

这样我们我们使用JSON.parse(result) ,直接转化为json的话是会报错的。



解决方法:

我们先把转义符用正则表达式去掉,



   var string = result.replace("/\","");

   var getDataArray = JSON.parse(string)

1

2

这样就OK了,不过要注意有时候也是需要指定返回数据类型的

dataType:“json”



8.使用其他的json依赖包方式:

引入阿里巴巴的json依赖包:



    <dependency>

     <groupId>com.alibaba</groupId>

     <artifactId>fastjson</artifactId>

     <version>1.2.9</version>

    </dependency>

1

2

3

4

5

模拟后台:



    String params="{\"channelCode\":\"bbb\",\"accountNo\":\"121300000932\",\"message\":\"字符信息解密成功\",\"status\":\"1\"}";

    JSONObject pa=JSONObject.parseObject(params);

    System.out.println(pa.getString("message"));

1

2

3

结果:





或者:

引入net.sf.json-lib依赖包:



    <dependency>

      <groupId>net.sf.json-lib</groupId>

      <artifactId>json-lib</artifactId>

      <version>2.4</version>  

      <classifier>jdk15</classifier>

    </dependency>

1

2

3

4

5

6

后台:



String params="{\"channelCode\":\"ccy\",\"accountNo\":\"121300000932\",\"message\":\"字符信息解密成功\",\"status\":\"1\"}";

JSONObject pa=JSONObject.fromObject(params);

String accountNo=pa.getString("accountNo");

System.out.println(accountNo);

1

2

3

4

结果:





9.后台对象转换json数据返回给前台

List集合转换成json代码:



List list = new ArrayList();

list.add( "first" );

list.add( "second" );

JSONArray jsonArray2 = JSONArray.fromObject( list );

1

2

3

4

Map集合转换成json代码:



  Map map = new HashMap();

map.put("name", "json");

map.put("bool", Boolean.TRUE);

map.put("int", new Integer(1));

map.put("arr", new String[] { "a", "b" });

map.put("func", "function(i){ return this.arr[i]; }");

JSONObject json = JSONObject.fromObject(map);

1

2

3

4

5

6

7

或者在项目中加入引入JSON-lib包,JSON-lib包同时依赖于以下的JAR包:

下载地址。



  1.commons-lang.jar

  2.commons-beanutils.jar

  3.commons-collections.jar

  4.commons-logging.jar 

  5.ezmorph.jar

  6.json-lib-2.2.2-jdk15.jar

1

2

3

4

5

6

用法同上



JSONObject jsonObject = JSONObject.fromObject(message);

getResponse().getWriter().write(jsonObject.toString());

1

2

当把数据转为json后,用如上的方法发送到客户端。前端就可以取得json数据了。(可以参考最下面的实例)



10.后台返回数据给前台,json中文乱码解决方法

在实际运用场景中,当前台发起请求后,我们需要从后台返回数据给前台,这时,如果返回的数据中包含中文,则经常会出现在后台查询出来都是好好,但是传输回去就莫名的乱码了,而且即使在 web.xml 中进行编码过滤了,但还是乱码。



解决办法:

只需要在 spring-mvc.xml 配置文件中配置一次就好,省去了我们重复写的麻烦,配置内容如下:



<!--自定义消息转换器的编码,解决后台传输json回前台时,中文乱码问题-->

    <mvc:annotation-driven >

        <mvc:message-converters register-defaults="true">

            <bean class="org.springframework.http.converter.StringHttpMessageConverter" >

                <property name = "supportedMediaTypes">

                    <list>

                        <value>application/json;charset=utf-8</value>

                        <value>text/html;charset=utf-8</value>

                        <!-- application 可以在任意 form 表单里面 enctype 属性默认找到 -->

                        <value>application/x-www-form-urlencoded</value>

                    </list>

                </property>

            </bean>

            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" ></bean>

        </mvc:message-converters>

    </mvc:annotation-driven>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

加上这段配置,保存重新运行,再次访问,会发现,原先的中文乱码都已经正常显示了。



方法二:在后台的方法映射添加:



@RequestMapping(value="/getphone",produces = “text/plain;charset=utf-8”)



11.Spring MVC返回json数据的方式

  1. 采用@ResponseBody注解

    @ResponseBody 注解的作用是:



    将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。



    使用举例:





    使用@ResponseBody 注解返回响应体 直接将返回值序列化json

    优点:不需要自己再处理



    再举例:



    RequestMapping("/login")

    @ResponseBody

    public User login(User user){

    return user;

    }

    1

    2

    3

    4

    5

    使用@ResponseBody 注解返回响应体 直接将返回值序列化json。



    User字段:userName pwd,那么在前台接收到的数据为:’{“userName”:“xxx”,“pwd”:“xxx”}’,效果等同于如下代码:



    @RequestMapping("/login")

    public void login(User user, HttpServletResponse response){

    response.getWriter.write(JSONObject.fromObject(user).toString());

    }



    1

    2

    3

    4

    5

    需要在springmvc的配置文件xml中添加:



    <mvc:annotation-driven/>  

    1
  2. 采用工具类,进行json格式转换带回

    JSON-lib包是一个beans,collections,maps,java arrays 和XML和JSON互相转换的包。在本例中,我们将使用JSONObject类创建JSONObject对象,然后我们打印这些对象的值。为了使用JSONObject对象,我们要引入"net.sf.json"包。为了给对象添加元素,我们要使用put()方法。



    要使程序可以运行必须引入JSON-lib包,JSON-lib包同时依赖于以下的JAR包:



    commons-lang.jar

    commons-beanutils.jar

    commons-collections.jar

    commons-logging.jar 

    ezmorph.jar

    json-lib-2.2.2-jdk15.jar

    1

    2

    3

    4

    5

    6

    效果:



    工具类:

    ResponseUtil.java



    package com.zout.utils;

    import java.io.PrintWriter;

    import javax.servlet.http.HttpServletResponse;

    import net.sf.json.JSONArray;

    import net.sf.json.JSONObject;



    /*

     
    @class_name:ResponseUtil  

     @param: EasyUi-响应工具类

     
    @return: 返回字符串格式数据、result是JSONObject对象(json对象)

     @author:Zoutao

     
    @createtime:2018年3月8日

     /

    public class ResponseUtil {

    public static void write(HttpServletResponse response, Object result)

    throws Exception {

    response.setContentType("text/html;charset=utf-8");

    response.addHeader("Access-Control-Allow-Origin", "
    ");

    PrintWriter out = response.getWriter();

    out.println(result.toString());

    System.out.println("带回的json字符串为:"+result.toString()+"类型为:"+result.getClass().getName());

    out.flush();

    out.close();

    }



    public static void main(String[] args) throws Exception {

    /在web运用控制层中调用如下:/

    JSONObject result = new JSONObject(); //创建json对象

    JSONArray jsonArray = JSONArray.fromObject("name:zhangsan"); //字符串转为json数组

    result.put("rows", jsonArray);  //放入json数组中,并起个名字

    HttpServletResponse response = null; //jsp的response对象

    ResponseUtil.write(response, result); //result写入response带回前台,jsp按名字拿取。

    }

    }



    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    后台具体调用:



    JSONObject result = new JSONObject();

    if (resultTotal > 0) { //处理结果

    System.out.println("操作成功。");

    result.put("success",true)

    result.put("message","操作成功"); //消息语句

    } else {

    System.out.println("操作失败。");

    result.put("success", false);

    result.put("message","操作失败");

    }

    ResponseUtil.write(response,result); //带回字符串+状态码

    return null;

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    图:





    后台已经通过工具类封装为json字符串了,使用response带回需要的数据,使用result带回状态字符串或状态码。



    前台:

    这是当成返回一个json字符串,然后直接采取字符串截取的方式,取出消息语句message等消息。





    这是另外一种写法:就是解析传回来的json字符串我js的对象,然后按照key/value的取值。



      function (data) {

              var data=eval("("+data+")");  //解析json

             //alert(data.message)

                $.messager.show({

                  title:'消息',

                  msg:data.message,  //按key取值

                  timeout:1000,

                  showType:'slide',

                  height:120,

                 width:200

         });

     });

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    推荐这种方式。

    效果图:





    以上都是后台返回json数据给前台和前台解析json数据的一些总结,还有json数据的封装,工具类的使用等等,东西有点复杂有点多,挑选自己需要的地方即可。

    另外的一些常用的web开发json:



    Json–Java数据类型对照表(映射)表


javascript基础———原型、原型对象和原型链

seo达人

原型:函数中的属性prototype,她的名字就叫原型。可以通过也只能通过prototype添加可继承的属性和方法

原型对象:函数中prototype中的proto 和对象中的proto

先记住原型(prototype)和原型对象(proto)

下面用代码解释原型、原型对象、 原型链

<!DOCTYPE html>

<html>

   <head>

    <meta charset="utf-8">

    <title>对象</title>

   </head>

   <body>

    <script type="text/javascript">

       //创建一个对象和一个函数

       var obj = {}

       console.log(obj.proto)//obj有原型对象

       function objFun (){}

       console.log(objFun.prototype) //objFun 原型

       console.log(objFun.prototype.proto) //原型中有原型对象

       console.log('*华丽的分割线***')

       // 以objFun为构造函数 (为了把构造函数和普通函数做区分,通常把构造函数名首字母大写)

       // 添加属性和方法

       objFun.prototype.name='saozhu'

       objFun.prototype.say = function(){

        console.log(this.name+'-骚猪')

       }

       // 创建实例对象1

       var obj1=new objFun()

       console.log(obj1)//打印对象 空对象

       console.log(obj1.name) //骚猪 证明obj1继承了objFun函数的属性

       console.log('*华丽的分割线***')

       // 此时此刻 可以理解原型链了: 

       console.log(obj1.proto=== objFun.prototype)

       //true 

       // 原型链是有实例对象的proto(原型对象)指向构造函数函数的原型(prototype)

       console.log(objFun.prototype.proto==window.Object.prototype)

       // true

       // 然后构造函数的原型的原型对象(prototype.proto)指向window.Object.protype(对象的原型)

       console.log(window.Object.prototype.proto===null)

       // 这样的指向关系形成的链式关系就是原型链

       //链式查询,查询对象中的属性和方法,会根据这样的原型链查找,直到找到响应的属性和方法.找到window.Object.prototype.proto还没有值,就返回undeifne

       

    </script>

   </body>

</html>


产品思维·用户体验中的五个层次(下)

鹤鹤

昨天我们讲了用户体验分为五个层次,从内而外分别是:

①战略存在层 > ②能力圈范围层 > ③资源结构层 > ④角色框架层 > ⑤感知层


以下案例来自于 梁宁老师的《产品思维30讲》

苦思冥想,还是只有梁宁老师这个案例最为合适;


说到“搜索”,你会想到哪些呢


如果我没猜错,你想到的第一个词是:“百度”

研发行业的话,可能我们用的浏览器应该是:“google”居多

但你是否用过古老的“yahoo”呢?



今天,我们就来说说搜索业三大巨头的战争,

他们之间的战争,有助于我们去理解用户体验的五个层次


首先


Google与百度


说到百度与谷歌的竞争前,梁宁老师说了下雅虎:


我们做设计的最知道,色彩是非常重要的元素,如果以科技为关键词,

我们想到的第一个词,一定是蓝色,蓝色一来不会太刺眼,

又相对普遍,所以不会出现审美疲劳,

而yahoo用的是什么为主色呢,是一个我们最不会用的颜色——紫色

 


那么,假如有个用户指着那个“紫色”的“音噗忒(input)”说:“不好用”,

他指的是什么呢?


1.是感知层,不喜欢蓝色?

2.按钮的形状太突兀?尺寸太大?位置不合适?

3.还是说是框架层,内容的排列方式没有令他满意呢?


说点令人兴奋的,我们在百度搜索“大乐透”,

度娘显示的结果第一条,就是本期开奖的结果,

然后是百度百科对“大乐透”这个词条的解释,

其次的就是关于大乐透的各类新闻和各种“行业大师”对下期开奖结果的分析;


百度的框架的意义就是,能一步走完,绝对不让用户走一步半,

为什么百度能给出这么符合用户的搜索结果呢?


虽然这个结果离不开的肯定得是百度的爬虫技术是数以毫秒为单位的,

但百度爬虫技术肯Google当然还是没法比的,

最重要的什么呢,是百度不单只是去爬数据,而且他还建立数据,


当整个互联网的数据都不多的时候,

百度做了一件Google没有做的事,

就是我们刚才说到的“建立数据”

百度做了两个平台:1.百度贴吧     2.百度知道


展示下各自的装备


一个在升级技术去爬,一个在建立数据

你觉得,谁会赢到最后呢,


你说,Google为什么不跟着做呢,

Google 的性格是绝对不会的,用梁宁老师的话来说:

“以Google的清高和耿直,不会做这样的事,甚至当用户有需求时,Google还会为百度导流量,给对手送弹药”


但至此,搜索业都还是处于资源层的比拼

这一仗,百度带着它的百度贴吧和百度知道,拿到了胜利!


但三十年河东,三十年河西

百度在移动场景下输给微信,也是因为微信以百度战胜Google同样的方式,以公众号的形式建设资源;



Yahoo与Google


2004年,一批华尔街精英做了搜索引擎的比评,评测结果呢,Yahoo优于Google,Yahoo胜利,

但奇怪的是评测完之后,大家打开了Google工作,


为什么会出现这个情况呢,


他们的评测方式非常的简单,对,就是简单,


第一步:选几个关键词

第二步:在各个搜索引擎中搜索

第三步:将结果打印

第四步:比对结果,认为哪个好,就投一枚硬币


最后雅虎获得的硬币最多

简单吧,你闲的蛋疼也可以去试试,


那为什么雅虎会胜出呢,因为雅虎用的后台搜索引擎也是Google的,

雅虎只是对热门的关键词做了人工优化,

所以结果不是跟Google一样,就是比Google好,

。。扯吧,但就是这样。


那为什么这批精英日常还是会用Google呢,

竟然是因为框架层,因为Yahoo的设计比较喜欢高大尚,所以界面相对宽松,易看,

但缺点就是一屏只能显示一两条,



而谷歌的搜索结果一屏展示好几十条,

所以对于搜索引擎这个东西来说,

我们更在乎内容,

而形式恐怕稍微次要,


在感知层差别不大的情况下,Yahoo竟然在框架层就输了一局,恐怕很难想到吧



设计师,要有产品思维!

但在互联网设计的今天,可能这五个层级有了一些整合,

但是,在用户抱怨体验不好时,你能分辨,会去分辨用户是说哪个层级吗?

还是说你会跟用户讲道理,说服他们呢?


销售天然的本领就是说服,掌握各种说服的技巧:

摆事实,讲道理,打比方,举例子,要同情,装可怜,将心比心,软磨硬泡;

如果是现实中,或许你能说服用户,


但作为一个互联网产品,别说说服,你连站在旁边说句话的资格都没有,

何况,比起用自己的道理说服用户,我们更应该做的,不应该是挖掘用户真正的需求吗?


从今天起,

不再做销售:按我的来

而要做产品:顺你的意


用户没有我们这么专业,他的表达方式就是:情绪;

如果我们不能接受这个表达方式,就不可能挖掘到用户的真正需求,


总结一下:

  1. 接受用户的表达方式,通过五个层面,挖掘到用户真正的需求;

  2. 销售是按我的来,而产品是顺你的意

日历

链接

个人资料

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

存档