<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          各家UI時代一覽

          藍藍設計的小編

          前方山高水長,我們都在路上。

          何為第一

          藍藍設計的小編

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          藍藍寫

          在班級考試的時候,在同行競標時,在工作業績評定時,大家都想贏,爭第一才有機會。很多時候,大家在為爭這個第一而煩惱。總是保持第一很難,得到后又怕失去,心情易受此情緒化。享受贏的感覺很好,但如果第一才是贏,那輸的人豈不是很多?

          得第一一旦養成習慣,做起事來會追求完美,不怕苦不怕累,但是一旦有場合一定要輸,使不想參與,覺得不公平。人生不可能每次都是考試第一,每場投標都中,每次比稿都只自己的最好,成敗是常見的事情,直面輸贏,是對心智的磨練。

          爸爸對我說,不要每次考試都讓我女兒考第一,這樣是不對的,要把身體鍛煉好,身體好了,成績自然就好。

          期中考試考前我激勵女兒:要好好學習,這次還能不能再有進步?期末考試是很重要的。女兒說:不就是期末考試嗎?有什么重要的?也不可能永遠都進步。

          我覺得他們說的話都有道理,以前每次投標我基本上是晚12點睡早五點起,睡中朦朧也會思考怎么做的更好,投完標基本上都會病一場,追求完美給自己壓力太大,影響健康。

          所以這次考試中只問女兒:今天身體怎么樣?累不累?熱不熱?放松去考,考砸了,下次再努力,女兒很高興,放松,覺得得到理解和關心。

          何為第一?今日讀到一段定義:所有的人都需要你的時候,你能夠給他們帶來所需要的,你就是第一。任何事情都有它的順序,講因緣,時節,果報,要一步一步來,時間未到,你想也沒有,時間一到,你不想它也有。

          德和得分別代表了內在和外在,它也代表了同一種東西的兩個狀態:能量和質量。

          當內在大于外在時,能量就會轉化為物質,于是財富會自動存在;當外在大于內在,也就是能量不夠的時候,物質會自動消失,對應到生活當中就是出現健康、財富等外在的損失甚至災難。

          由此就能更好地理解我們常說的“厚德載物”是什么意思,物質就是錢、地位、房子、子孫、家庭、名利。

          厚德=后得。

          厚德厚物,薄德薄物,缺德缺物,無德無物。因為能量和質量永遠要追求一種平衡。WechatIMG90.jpeg

          遵守職業道德,做人的品德是基礎,否則水里來火里去存不住物質財富,贏得第一意味著名利,意味著才華和能力能夠給帶來機會和財富,但是品德修養是更為重要的根本,決定財富持有的時間和量級。

          去掉攀比的好勝心,把視角轉向對內的反省和探索,目標不再定為得第一,而定為不斷地完善自我,完善工作品質。甘當無私的綠葉,在別人需要時幫助別人,減少狹隘的利益判斷,更寬胸懷的幫助別的公司建立設計驅動的價值。

          有德的人,不為自己求安樂,但為眾生得離苦,眾生是一個很大的團隊,如果由己及人,把團隊擴大到同事,社區,同行,胸懷越來越大,人也就會變得越來越包容,平和。追求亦也不再是自己的第一,而是帶領更多的人走向卓越,完善自我的修行之路。

          WechatIMG91.jpg


          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務



          ES6新特性Promise異步調用

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          Promise 的含義

          Promise 是異步編程的一種解決方案,比傳統的解決方案–回調函數和事件--更合理和更強大。它由社區最早提出和實現,ES6將其寫進了語言標準,統一了語法,原生提供了Promise

          所謂Promise ,簡單說就是一個容器,里面保存著某個未來才回結束的事件(通常是一個異步操作)的結果。從語法上說,Promise是一個對象,從它可以獲取異步操作的消息。 
          Promise 對象的狀態不受外界影響

          三種狀態:

          • pending:進行中
          • fulfilled :已經成功
          • rejected 已經失敗

          狀態改變: 
          Promise對象的狀態改變,只有兩種可能:

          • 從pending變為fulfilled
          • 從pending變為rejected。

          這兩種情況只要發生,狀態就凝固了,不會再變了,這時就稱為resolved(已定型

          基本用法

          ES6規定,Promise對象是一個構造函數,用來生成Promise實例

          
              
          1. const promist = new Promise(function(resolve,reject){
          2. if(/*異步操作成功*/){
          3. resolve(value);
          4. }else{
          5. reject(error);
          6. }
          7. })
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          resolve函數的作用是,將Promise對象的狀態從“未完成”變為“成功”(即從 pending 變為 resolved),在異步操作成功時調用,并將異步操作的結果,作為參數傳遞出去; 
          reject函數的作用是,將Promise對象的狀態從“未完成”變為“失敗”(即從 pending 變為 rejected),在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去。

          Promise的源碼分析:

          1.回調地獄

          曾幾何時,我們的代碼是這樣的,為了拿到回調的結果,不得不callback hell,這種環環相扣的代碼可以說是相當惡心了

          
                      
          1. let fs = require('fs')
          2. fs.readFile('./a.txt','utf8',function(err,data){
          3. fs.readFile(data,'utf8',function(err,data){
          4. fs.readFile(data,'utf8',function(err,data){
          5. console.log(data)
          6. })
          7. })
          8. })

          終于,我們的蓋世英雄出現了,他身披金甲圣衣、駕著七彩祥云。好吧打岔兒了,沒錯他就是我們的Promise,那讓我們來看看用了Promise之后,上面的代碼會變成什么樣吧

          
                      
          1. let fs = require('fs')
          2. function read(url){
          3. return new Promise((resolve,reject)=>{
          4. fs.readFile(url,'utf8',function(error,data){
          5. error && reject(error)
          6. resolve(data)
          7. })
          8. })
          9. }
          10. read('./a.txt').then(data=>{
          11. return read(data)
          12. }).then(data=>{
          13. return read(data)
          14. }).then(data=>{
          15. console.log(data)
          16. })

          2.重點開始,小眼睛都看過來

          2.1 Promise/A+

          首先我們要知道自己手寫一個Promise,應該怎么去寫,誰來告訴我們怎么寫,需要遵循什么樣的規則。當然這些你都不用擔心,其實業界都是通過一個規則指標來生產Promise的。讓我們來看看是什么東西。傳送門?Promise/A+

          2.2 constructor

          我們先聲明一個類,叫做Promise,里面是構造函數。如果es6還有問題的可以去阮大大的博客上學習一下(傳送門?es6

          
                      
          1. class Promise{
          2. constructor(executor){
          3. //控制狀態,使用了一次之后,接下來的都不被使用
          4. this.status = 'pendding'
          5. this.value = undefined
          6. this.reason = undefined
          7. //定義resolve函數
          8. let resolve = (data)=>{
          9. //這里pendding,主要是為了防止executor中調用了兩次resovle或reject方法,而我們只調用一次
          10. if(this.status==='pendding'){
          11. this.status = 'resolve'
          12. this.value = data
          13. }
          14. }
          15. //定義reject函數
          16. let reject = (data)=>{
          17. if(this.status==='pendding'){
          18. this.status = 'reject'
          19. this.reason = data
          20. }
          21. }
          22. //executor方法可能會拋出異常,需要捕獲
          23. try{
          24. //將resolve和reject函數給使用者
          25. executor(resolve,reject)
          26. }catch(e){
          27. //如果在函數中拋出異常則將它注入reject中
          28. reject(e)
          29. }
          30. }
          31. }

          那么接下來我會分析上面代碼的作用,原理

          • executor:這是實例Promise對象時在構造器中傳入的參數,一般是一個function(resolve,reject){}
          • status:``Promise的狀態,一開始是默認的pendding狀態,每當調用道resolve和reject方法時,就會改變其值,在后面的then方法中會用到
          • value:resolve回調成功后,調用resolve方法里面的參數值
          • reason:reject回調成功后,調用reject方法里面的參數值
          • resolve:聲明resolve方法在構造器內,通過傳入的executor方法傳入其中,用以給使用者回調
          • reject:聲明reject方法在構造器內,通過傳入的executor方法傳入其中,用以給使用者回調

          2.3 then

          then方法是Promise中最為重要的方法,他的用法大家都應該已經知道,就是將Promise中的resolve或者reject的結果拿到,那么我們就能知道這里的then方法需要兩個參數,成功回調和失敗回調,上代碼!

          
                      
          1. then(onFufilled,onRejected){
          2. if(this.status === 'resolve'){
          3. onFufilled(this.value)
          4. }
          5. if(this.status === 'reject'){
          6. onRejected(this.reason)
          7. }
          8. }

          這里主要做了將構造器中resolve和reject的結果傳入onFufilledonRejected中,注意這兩個是使用者傳入的參數,是個方法。所以你以為這么簡單就完了?要想更Swag的應對各種場景,我們必須得再完善。繼續往下走!

          3.異步的Promise

          之前我們只是處理了同步情況下的Promise,簡而言之所有操作都沒有異步的成分在內。那么如果是異步該怎么辦?

          3.1 callback?。。。?

          最早處理異步的方法就是callback,就相當于我讓你幫我掃地,我會在給你發起任務時給你一個手機,之后我做自己的事情去,不用等你,等你掃完地就會打手機給我,誒,我就知道了地掃完了。這個手機就是callback,回調函數。

          首先我們需要改一下構造器里的代碼,分別添加兩個回調函數的數組,分別對應成功回調和失敗回調。他們的作用是當成功執行resolve或reject時,執行callback。

          
                      
          1. //存放成功回調的函數
          2. this.onResolvedCallbacks = []
          3. //存放失敗回調的函數
          4. this.onRejectedCallbacks = []
          5. let resolve = (data)=>{
          6. if(this.status==='pendding'){
          7. this.status = 'resolve'
          8. this.value = data
          9. //監聽回調函數
          10. this.onResolvedCallbacks.forEach(fn=>fn())
          11. }
          12. }
          13. let reject = (data)=>{
          14. if(this.status==='pendding'){
          15. this.status = 'reject'
          16. this.reason = data
          17. this.onRejectedCallbacks.forEach(fn=>fn())
          18. }
          19. }

          然后是then需要多加一個狀態判斷,當Promise中是異步操作時,需要在我們之前定義的回調函數數組中添加一個回調函數。

          
                      
          1. if(this.status === 'pendding'){
          2. this.onResolvedCallbacks.push(()=>{
          3. // to do....
          4. let x = onFufilled(this.value)
          5. resolvePromise(promise2,x,resolve,reject)
          6. })
          7. this.onRejectedCallbacks.push(()=>{
          8. let x = onRejected(this.reason)
          9. resolvePromise(promise2,x,resolve,reject)
          10. })
          11. }

          ok!大功告成,異步已經解決了

          3.2 resolvePromise

          這也是Promise中的重頭戲,我來介紹一下,我們在用Promise的時候可能會發現,當then函數中return了一個值,我們可以繼續then下去,不過是什么值,都能在下一個then中獲取,還有,當我們不在then中放入參數,例:promise.then().then(),那么其后面的then依舊可以得到之前then返回的值,可能你現在想很迷惑。讓我來解開你心中的憂愁,follow me。

          
                      
          1. then(onFufilled,onRejected){
          2. //解決onFufilled,onRejected沒有傳值的問題
          3. onFufilled = typeof onFufilled === 'function'?onFufilled:y=>y
          4. //因為錯誤的值要讓后面訪問到,所以這里也要跑出個錯誤,不然會在之后then的resolve中捕獲
          5. onRejected = typeof onRejected === 'function'?onRejected:err=>{ throw err ;}
          6. //聲明一個promise對象
          7. let promise2
          8. if(this.status === 'resolve'){
          9. //因為在.then之后又是一個promise對象,所以這里肯定要返回一個promise對象
          10. promise2 = new Promise((resolve,reject)=>{
          11. setTimeout(()=>{
          12. //因為穿透值的緣故,在默認的跑出一個error后,不能再用下一個的reject來接受,只能通過try,catch
          13. try{
          14. //因為有的時候需要判斷then中的方法是否返回一個promise對象,所以需要判斷
          15. //如果返回值為promise對象,則需要取出結果當作promise2的resolve結果
          16. //如果不是,直接作為promise2的resolve結果
          17. let x = onFufilled(this.value)
          18. //抽離出一個公共方法來判斷他們是否為promise對象
          19. resolvePromise(promise2,x,resolve,reject)
          20. }catch(e){
          21. reject(e)
          22. }
          23. },0)
          24. })
          25. }
          26. if(this.status === 'reject'){
          27. promise2 = new Promise((resolve,reject)=>{
          28. setTimeout(()=>{
          29. try{
          30. let x = onRejected(this.reason)
          31. resolvePromise(promise2,x,resolve,reject)
          32. }catch(e){
          33. reject(e)
          34. }
          35. },0)
          36. })
          37. }
          38. if(this.status === 'pendding'){
          39. promise2 = new Promise((resolve,reject)=>{
          40. this.onResolvedCallbacks.push(()=>{
          41. // to do....
          42. setTimeout(()=>{
          43. try{
          44. let x = onFufilled(this.value)
          45. resolvePromise(promise2,x,resolve,reject)
          46. }catch(e){
          47. reject(e)
          48. }
          49. },0)
          50. })
          51. this.onRejectedCallbacks.push(()=>{
          52. setTimeout(()=>{
          53. try{
          54. let x = onRejected(this.reason)
          55. resolvePromise(promise2,x,resolve,reject)
          56. }catch(e){
          57. reject(e)
          58. }
          59. })
          60. })
          61. })
          62. }
          63. return promise2
          64. }

          一下子多了很多方法,不用怕,我會一一解釋

          1. 返回Promise?:首先我們要注意的一點是,then有返回值,then了之后還能在then,那就說明之前的then返回的必然是個Promise。
          2. 為什么外面要包一層setTimeout?:因為Promise本身是一個異步方法,屬于微任務一列,必須得在執行棧執行完了在去取他的值,所以所有的返回值都得包一層異步setTimeout。
          3. 為什么開頭有兩個判斷?:這就是之前想要解決的如果then函數中的參數不是函數,那么我們需要做處理。如果onFufilled不是函數,就需要自定義個函數用來返回之前resolve的值,如果onRejected不是函數,自定義個函數拋出異常。這里會有個小坑,如果這里不拋出異常,會在下一個then的onFufilled中拿到值。又因為這里拋出了異常所以所有的onFufilled或者onRejected都需要try/catch,這也是Promise/A+的規范。當然本人覺得成功的回調不需要拋出異常也可以,大家可以仔細想想。
          4. resolvePromise是什么?:這其實是官方Promise/A+的需求。因為你的then可以返回任何職,當然包括Promise對象,而如果是Promise對象,我們就需要將他拆解,直到它不是一個Promise對象,取其中的值。

          那就讓我們來看看這個resolvePromise到底長啥樣。

          
                      
          1. function resolvePromise(promise2,x,resolve,reject){
          2. //判斷x和promise2之間的關系
          3. //因為promise2是上一個promise.then后的返回結果,所以如果相同,會導致下面的.then會是同一個promise2,一直都是,沒有盡頭
          4. if(x === promise2){//相當于promise.then之后return了自己,因為then會等待return后的promise,導致自己等待自己,一直處于等待
          5. return reject(new TypeError('循環引用'))
          6. }
          7. //如果x不是null,是對象或者方法
          8. if(x !== null && (typeof x === 'object' || typeof x === 'function')){
          9. //為了判斷resolve過的就不用再reject了,(比如有reject和resolve的時候)
          10. let called
          11. try{//防止then出現異常,Object.defineProperty
          12. let then = x.then//取x的then方法可能會取到{then:{}},并沒有執行
          13. if(typeof then === 'function'){
          14. //我們就認為他是promise,call他,因為then方法中的this來自自己的promise對象
          15. then.call(x,y=>{//第一個參數是將x這個promise方法作為this指向,后兩個參數分別為成功失敗回調
          16. if(called) return;
          17. called = true
          18. //因為可能promise中還有promise,所以需要遞歸
          19. resolvePromise(promise2,y,resolve,reject)
          20. },err=>{
          21. if(called) return;
          22. called = true
          23. //一次錯誤就直接返回
          24. reject(err)
          25. })
          26. }else{
          27. //如果是個普通對象就直接返回resolve作為結果
          28. resolve(x)
          29. }
          30. }catch(e){
          31. if(called) return;
          32. called = true
          33. reject(e)
          34. }
          35. }else{
          36. //這里返回的是非函數,非對象的值,就直接放在promise2的resolve中作為結果
          37. resolve(x)
          38. }
          39. }

          它的作用是用來將onFufilled的返回值進行判斷取值處理,把最后獲得的值放入最外面那層的Promise的resolve函數中。

          1. 參數promise2(then函數返回的Promise對象),x(onFufilled函數的返回值),resolve、reject(最外層的Promise上的resolve和reject)。
          2. 為什么要在一開始判斷promise2x?:首先在Promise/A+中寫了需要判斷這兩者如果相等,需要拋出異常,我就來解釋一下為什么,如果這兩者相等,我們可以看下下面的例子,第一次p2是p1.then出來的結果是個Promise對象,這個Promise對象在被創建的時候調用了resolvePromise(promise2,x,resolve,reject)函數,又因為x等于其本身,是個Promise,就需要then方法遞歸它,直到他不是Promise對象,但是x(p2)的結果還在等待,他卻想執行自己的then方法,就會導致等待。
          
                      
          1. let p1 = new Promise((resolve,reject)=>{
          2. resolve()
          3. })
          4. let p2 = p1.then(d=>{
          5. return p2
          6. })
          1. called是用來干嘛的?:called變量主要是用來判斷如果resolvePromise函數已經resolve或者reject了,那就不需要在執行下面的resolce或者reject。
          2. 為什么取then這個屬性?:因為我們需要去判斷x是否為Promise,then屬性如果為普通值,就直接resolve掉,如果是個function,就是Promise對象,之后我們就需要將這個x的then方法進行執行,用call的原因是因為then方法里面this指向的問題。
          3. 為什么要遞歸去調用resolvePromise函數?:相信細心的人已經發現了,我這里使用了遞歸調用法,首先這是Promise/A+中要求的,其次是業務場景的需求,當我們碰到那種Promise的resolve里的Promise的resolve里又包了一個Promise的話,就需要遞歸取值,直到x不是Promise對象。

          4.完善Promise

          我們現在已經基本完成了Promise的then方法,那么現在我們需要看看他的其他方法。

          4.1 catch

          相信大家都知道catch這個方法是用來捕獲Promise中的reject的值,也就是相當于then方法中的onRejected回調函數,那么問題就解決了。我們來看代碼。

          
                      
          1. //catch方法
          2. catch(onRejected){
          3. return this.then(null,onRejected)
          4. }

          該方法是掛在Promise原型上的方法。當我們調用catch傳callback的時候,就相當于是調用了then方法。

          4.2 resolve/reject

          大家一定都看到過Promise.resolve()、Promise.reject()這兩種用法,它們的作用其實就是返回一個Promise對象,我們來實現一下。

          
                      
          1. //resolve方法
          2. Promise.resolve = function(val){
          3. return new Promise((resolve,reject)=>{
          4. resolve(val)
          5. })
          6. }
          7. //reject方法
          8. Promise.reject = function(val){
          9. return new Promise((resolve,reject)=>{
          10. reject(val)
          11. })
          12. }

          這兩個方法是直接可以通過class調用的,原理就是返回一個內部是resolve或reject的Promise對象。

          4.3 all

          all方法可以說是Promise中很常用的方法了,它的作用就是將一個數組的Promise對象放在其中,當全部resolve的時候就會執行then方法,當有一個reject的時候就會執行catch,并且他們的結果也是按著數組中的順序來排放的,那么我們來實現一下。

          
                      
          1. //all方法(獲取所有的promise,都執行then,把結果放到數組,一起返回)
          2. Promise.all = function(promises){
          3. let arr = []
          4. let i = 0
          5. function processData(index,data){
          6. arr[index] = data
          7. i++
          8. if(i == promises.length){
          9. resolve(arr)
          10. }
          11. }
          12. return new Promise((resolve,reject)=>{
          13. for(let i=0;i<promises.length;i++){
          14. promises[i].then(data=>{
          15. processData(i,data)
          16. },reject)
          17. }
          18. })
          19. }

          其原理就是將參數中的數組取出遍歷,每當執行成功都會執行processData方法,processData方法就是用來記錄每個Promise的值和它對應的下標,當執行的次數等于數組長度時就會執行resolve,把arr的值給then。這里會有一個坑,如果你是通過arr數組的長度來判斷他是否應該resolve的話就會出錯,為什么呢?因為js數組的特性,導致如果先出來的是1位置上的值進arr,那么0位置上也會多一個空的值,所以不合理。

          4.4 race

          race方法雖然不常用,但是在Promise方法中也是一個能用得上的方法,它的作用是將一個Promise數組放入race中,哪個先執行完,race就直接執行完,并從then中取值。我們來實現一下吧。

          
                      
          1. //race方法
          2. Promise.race = function(promises){
          3. return new Promise((resolve,reject)=>{
          4. for(let i=0;i<promises.length;i++){
          5. promises[i].then(resolve,reject)
          6. }
          7. })
          8. }

          原理大家應該看懂了,很簡單,就是遍歷數組執行Promise,如果有一個Promise執行成功就resolve。

          Promise語法糖 deferred

          語法糖這三個字大家一定很熟悉,作為一個很Swag的前端工程師,對async/await這對兄弟肯定很熟悉,沒錯他們就是generator的語法糖。而我們這里要講的語法糖是Promise的。

          
                      
          1. //promise語法糖 也用來測試
          2. Promise.deferred = Promise.defer = function(){
          3. let dfd = {}
          4. dfd.promise = new Promise((resolve,reject)=>{
          5. dfd.resolve = resolve
          6. dfd.reject = reject
          7. })
          8. return dfd
          9. }

          什么作用呢?看下面代碼你就知道了

          
                      
          1. let fs = require('fs')
          2. let Promise = require('./promises')
          3. //Promise上的語法糖,為了防止嵌套,方便調用
          4. //壞處 錯誤處理不方便
          5. function read(){
          6. let defer = Promise.defer()
          7. fs.readFile('./1.txt','utf8',(err,data)=>{
          8. if(err)defer.reject(err)
          9. defer.resolve(data)
          10. })
          11. return defer.Promise
          12. }

          沒錯,我們可以方便的去調用他語法糖defer中的Promise對象。那么它還有沒有另外的方法呢?答案是有的。我們需要在全局上安裝promises-aplus-tests插件npm i promises-aplus-tests -g,再輸入promises-aplus-tests [js文件名] 即可驗證你的Promise的規范。


          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          我用這個極限推敲法,有效推進視覺設計

          資深UI設計者

          每當提到設計方法論時,總難免會給人一種比較虛空偏理論,或者說比較難應用到設計實戰中的感覺;但是這一次,經過了自己的實踐之后,我覺得確實有一個比較靠譜的視覺推進方法可以分享給大家,所以才有了這篇總結。

          先直接概括一下這個方法,極限推敲法:遇到難題時,先把問題拆解成一個或者幾個維度,選取某個維度,往兩個極端進行嘗試,隨后逐漸中和極端方案,逐步找到自己想要的預期點,明確該維度的方向。

          一、使用方法

          • 第一步,提煉一個或者幾個關鍵維度,作為嘗試的方向;
          • 第二步,優先嘗試兩端極限的方案;
          • 第三步,進一步在其間琢磨并嘗試方案,直到找到符合預期的方案;
          • 第四步,若一直沒有滿意的方案,則可以繼續以某個方案為基準,精細微調方案進行探索;
          • 第五步,得出最終方向,并最終調整形成終稿。

          二、案例

          例一:雄獅的logo設計

          期望比較簡潔的同時,又不能丟了獅子的辨識度,比較糾結的是,這個度該如何把握?

          按照極限推敲法來,我們先確立「極簡」和「寫實」作為關鍵維度,然后優先嘗試兩端比較極限的方案;了解清楚兩種極限的可能性之后,繼續嘗試,加減細節,尋找一個符合預期的圖形狀態;最后的定稿,既保持了鮮明的特征和辨識度,同時也不失簡潔。

          (推進過程中出方案的順序在圖中用數字標出,「1」即為第一次嘗試,以此類推;具體推敲過程不在此贅述。)

          例二:網易郵箱大師Tab icon改版設計

          在網易郵箱大師5.0改版中,常駐底部的 Tab icon 是單獨進行推敲優化的。在之前的版本中,圖標的樣式相對比較的刻板,偏向純表意,表現力不強;在5.0視覺改版的策略中,我們是以「優雅」作為一個關鍵方向進行優化的,所以軸的兩端就定為「刻板」和「優雅」,雖然并不是完全對立的兩個方向,同時也包含了一些「表意」等其他層面的因素,但是其中有部分感受是存在對立面的,我們就以此作為關鍵點進行推敲。

          可以從圖中看出,在不影響表意的前提下,各方案間的圖標改動非常微小,在有限的空間內去做一些變化;幾經嘗試之后,還是選擇了更常規更偏表意優先,但是也適當加入曲線因素體現「優雅」的方案作為最終方向。

          例三:內容信息流列表設計

          期望內容列表的展示能給人以精品的感覺,但又不失去過多的閱讀效率。

          首先確立以信息量的多少作為關鍵維度,在形成了初步的樣式之后,繼續調整在一屏內條目的疏密以及排版來感知信息量的多少;在嘗試之后,最終討論決定,在初期內容源還不夠「精」的情況下,還是最右側方案的信息呈現更為合適,并以此做了最終調整。

          三、方法原理

          很多時候,極端情況是很難想象或者預判出來的,只有嘗試之后,才能更清楚的了解到實際會出來什么效果,達到怎樣的預期;在多次推敲之后,就能更好的了解期望的狀態到底應該在哪個「位置」,讓模糊的概念逐漸變得清晰;該方法最大的好處在于,讓嘗試變的更有目標,而不是胡亂嘗試,讓每一次嘗試都更有意義。

          這個方法也算是視覺標準可量化的一次探索,我稱之為「偽量化」,因為最后的決策仍然是依靠感官去衡量判斷的;把錯綜復雜的感官拆解成一些更具體單一的關鍵維度也是非常關鍵的一個步驟,是開始「偽量化」的前提。

          四、適用場景

          在以上所舉的例子中,有 logo設計,icon設計和界面設計(所用到的例子都是實戰,均為過往項目);其實對象可以是各種各樣的設計,只要存在某種程度把握上的糾結,無法預判或者不明確方向的情況,都可以通過這個方法有效的推進并找到當下的最優解。在實戰中,假如沒有那么多的時間和精力去細化,可以僅選取關鍵維度,然后在關鍵維度內嘗試方向探索性的方案(粗略的嘗試),只要能感受到差異,即是有效的方案;當然如果有充足的時間,那完全可以精細化出方案,這樣方案所傳達的感受也會更加精準細致。

          五、誤區

          要注意的是,這個方法并不是一種妥協的方式,也不是一種擇中方案;我們所要尋找的是在一個維度中感受符合預期的位置,如果適合,也可以是非常激進的方案。

          六、注意事項

          這個方法只是提供了一種思路,如何更有效的嘗試方案來推進視覺產出的思路;其中最主要的環節還是靠自己去摸索出方案的實踐部分,去實打實的嘗試;在這其中投入精力的多少,也受其他客觀因素的影響,例如項目截止時間等等;不過我認為個人的主觀能動性才是主導,一定不能懶,要作圖,要動起來,僅靠憑空想象方案在腦中「出圖」,一來說服不了別人,二來自己也底氣不足。只要圖形圖像語言一直存在,那么我覺得對視覺設計師來說有一句話就是永遠的真理:沒圖說個XX。

          智能汽車UI與手機UI的設計區別

          藍藍設計的小編

          隨著特斯拉智能電動汽車憑借其全新的電動能源和智能化的大屏操作系統在全球的走紅。在中國也引起了強烈的蝴蝶效應,小鵬汽車,蔚來汽車和威馬汽車等主打互聯網智能的汽車應運而生。在新的一年汽車UI可能會成為下一個設計熱點。

          么去控制瀏覽器對資源文件的處理行為

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          通常當用戶打開一個資源的url,如果瀏覽器支持這個格式的文件的情況下,瀏覽器會嘗試去再頁面里展示它而不是直接下載。例如一張圖片(jpg, png, gif等),幾乎所有瀏覽器都會去將圖片在瀏覽器里面展示。


          對于壓縮格式的文件(zip, tar, gzip等)瀏覽器總是會直接去下載它們,另外一些格式的文件,根據瀏覽器的不同也會有差異的處理方法,例如Microsoft Word文件(doc, docx)在ie瀏覽器下通常會在瀏覽器中展示,但是其他瀏覽器幾乎都會直接下載它,同樣的對于PDF文件chrome有自己的pdf 轉換器它會嘗試去在瀏覽器上展示該文件。

          強制下載文件

          對于瀏覽器這種行為,一般情況下是可以接受的,因為用戶可以在瀏覽器顯示文件后將文件保存到電腦中,但是一些情況下用戶可能希望文件直接被下載而不是在瀏覽器中被打開,比如有時候用戶想去下載一個歌曲,但是瀏覽器可能回去播放該音頻。那么怎么讓瀏覽器強制去下載文件要怎么做呢

          a標簽的download屬性

          html5中 a 標簽新增了 download 屬性,該屬性指示瀏覽器下載url的內容而不是導航到url,因此如果配置了此屬性用戶會直接下載url的內容。作為開發如果想直接觸發該事件我們可以直接用代碼模擬a標簽和點擊事件

          
              
          1. const link = document.createElement('a');
          2. link.addEventListener('click', function() {
          3. link.download = xxx;
          4. link.href = xxx;
          5. });
          6. const e = document.createEvent('MouseEvents');
          7. e.initEvent('click', false, false);
          8. link.dispatchEvent(e);
          • download屬性只在同域時候有效,當跨域請求時候該屬性將會被忽略。
          • 當前并非所以瀏覽器都支持該屬性,需要瀏覽器考慮兼容性。

          改變資源格式

          瀏覽器會根據資源類型去判斷是否支持,如果支持時會嘗試去在頁面上展示該資源。瀏覽器判斷資源類型是根據返回頭Content-Type的值,因此一方面我們在服務端可以設置返回頭字段為文件流'Content-Type': 'application/octet-stream',或者根據一些具體資源直接壓縮后傳輸,瀏覽器不能分析zip之類的壓縮文件所以會直接去下載它們。

          配置Content-Disposition

          在HTTP場景中,Content-Disposition 消息頭指示回復的內容該以何種形式展示,是以內聯的形式(即網頁或者頁面的一部分),還是以附件的形式下載并保存到本地。

          • inline 默認參數表示消息體會以頁面的一部分或者整個頁面的形式展示。
          • attachment 消息體應該被下載到本地,將參數filename的值預填為下載后的文件名

          因此當我們希望該資源被直接下載時候,我們可以設置返回頭Content-Disposition的值為attachment。

          
              
          1. //example
          2. Content-Disposition: attachment; filename="fname.ext"

          這里設置名稱時候,要注意下filename的編碼格式。

          用戶自己在瀏覽器設置

          瀏覽器既然定義了該行為,根據瀏覽器的不同用戶可能在設置頁面去配置某些格式的文件是否希望瀏覽器去展示該文件。一些有爭議的情況下,你也可以提示用戶自己根據需求去設置這些參數。

          
          
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          設計師如何洞察需求本質,做出一稿過的設計?

          資深UI設計者

          本文主要從需求類型、表現形式、如何做正確設計來分析,設計師應如何洞察需求本質?如何做正確的設計?

          前言:設計師的痛

          有這樣兩種情況在設計師工作中經常會遇到:業務方改來改去,經過幾十遍的修改最終選了第一稿;一群非專業的人或領導在設計師身邊指來指去,出發點都是「我覺得」主觀感受,沒一個能提出有點含金量的意見。

          • 客戶或業務反復改
          • 眾人指點江山

          實際工作里我們經常遇到業務方一直在針對幾個問題要求設計師在不停修改 :顏色、大小、氛圍等。但是卻很少看到設計師跟業務方溝通設計結果出現的場景?是為了達到什么目標?導致設計師一直處于不停「改改改」的苦逼狀態。

          本篇文章內容為:設計師如何洞察需求本質?如何做正確的設計?

          一、設計對接的需求來源類型

          設計師在工作中接觸到的需求一般分為三類:業務需求、用戶需求、產品功能需求。

          1. 業務需求

          業務需求是指產品和公司為了實現商業目標產生的需求。不以結婚為目的的談戀愛就是耍流氓,不以賺錢為目的的產品也是耍流氓,說來說去最終目的都是為了實現商業價值。

          業務需求多數來源老板、公司戰略、運營策略等,一般圍繞如何提升公司銷售額度、如何提升用戶量、如何提升利潤、如何提升用戶轉化、如何推廣運營等等。

          2. 用戶需求

          用戶需求是指通過調研或客服投訴搜集到的用戶反饋,一般來源于用戶在使用產品過程中的需求。在 kano模型中對用戶需求一般分為:基本需求、期望需求、魅力需求、無差異需求、逆向需求。針對這些需求公司都會結合發展戰略與優先級去分析,可分為必做、應做、可做、不做。

          3. 產品功能需求

          基于業務和用戶價值進行需求分析的結果,為滿足業務和用戶提出的一組產品功能列表,功能需求構成了一個完整的產品抽象模型,是團隊之間進行產品設計研發的基礎。

          二、三類需求常見的表現形式

          1. 業務需求常見形式

          這有個萬能的公式:銷售額=流量x客單價x轉化率

          拿某某購物中心舉個例子:銷售額就是我們聽到的某某購物中心在五一期間賣了xxx億的額度,流量就是五一期間有多少顧客進來了這個購物中心,客單價就是額度除以購買人數,轉化率是訂單除以訪客。在同等訪客量的情況下訂單越低,轉化率越低。

          這個公式換到互聯網產品中也一樣,多少用戶進入 app,有多少人產生購買行為,以及每個人購買的單價,這些因素都是決定這個產品最終的銷售額。

          業務需求是流量增長

          在產品發展初期,面臨的第一個問題就是訪問量,也就是產品的曝光率,用戶到達率。我們在生活中會經常看到一些公司請一些自帶流量的網紅、明星來做宣傳為公司帶來一些流量。在互聯網產品中常見的一些流量增長的策劃為拉新獎勵、高流量為低流量導流、免費效應等。

          拉新獎勵:推薦有獎、注冊有獎。

          導流:高流量為低流量導流。

          免費:0元購、秒殺等。

          業務需求是活躍度

          產品活躍度是指用戶每天開啟 app 的頻次,每天停留的時間。不同屬性的產品活躍度的規律也不一定,比如:新聞類、理財類、工具類的產品,針對不同用戶、不同屬性的產品提升活躍度的方式不一樣。

          比較常見的提升活躍度的策略是:獎勵刺激、有價值的內容吸引、通過成長等級來引起用戶參與。

          獎勵:補貼、答題獎勵、分享得積分、返現金、簽到、打卡獎勵。

          內容:推送激活、話題討論、焦點&熱點內容。

          榮譽感:排行榜、等級。

          業務需求是用戶留存

          經過運營渠道推廣流量提升后,倒入一些新用戶,用戶經過一段時間體驗后是否留存關鍵在于:用戶需求被滿足、以及體驗流程流暢決定的。當用戶發現產品對自己沒有價值、體驗沒有好感就會選擇離開。

          比較常見的留存策略是:翻倍獎勵、產品體驗迭代優化、評分、用戶成長體系等。

          業務需求是品牌感知

          用戶對同類產品的選擇很大程度取決于產品品牌的影響力,業務方在推廣中也會有針對品牌提升感知力。

          比較常見的有:h5的情感推廣、公益活動等。

          網易的h5活動在2017年經常刷爆全屏,他們主打的是情感系列,深入人心,不僅提升主品牌影響,也提升了用戶對網易噠噠的產品感知。

          小結:業務需求設計要點

          • 用戶感知:在設計中對設計表現要處理好文案層級關系/視覺氛圍吸引度/提升用戶注意力。
          • 效果目標:要考慮業務需求的目標是什么,通過什么形式(創意/用戶記憶/內容價值)達到拉新、留存、流量的目的。
          • 數據推導:通過數據可以讓我們理性分析出用戶關注點是什么?
          2. 用戶需求常見形式

          對于用戶提出的一些功能的需求,設計師不能盲目聽從,需要真正去識別有用的用戶、有價值的需求。我們可以通過一些調研、觀察,分析用戶的特征、習慣、場景和行為,以及期望得到什么效果,挖掘用戶的內在動機和原因,只有搞明白了用戶需求的本質,才有可能做出用戶滿意的產品。

          KANO模型定義了五類需求,我主要針對下面3類經常遇見的說下,也可以分為3個步驟去做:基本需求 — 期望需求 — 魅力需求。

          用戶基本需求

          指用戶認為產品必須要有的屬性或者功能,比如:購買流程的完整體驗、完整注冊流程,這些基本需求一般來源產品初期迭代中的優化完善。

          用戶期望需求

          用戶在主流程體驗過程中增加一些利于自己快捷、便利的需求,這些功能并不影響主流程體驗,比如:購買過程中對收藏、歷史價格對比、搜索等,這些期望需求可以轉化成一些潛在的競爭優勢。

          例如:下圖用戶需求搜集中用戶集中在對歷史價位走勢、提醒等功能的一些期望需求上。

          △ 根據用戶期望需求調整的設計構思

          用戶興奮魅力需求

          魅力需求是每一個產品追尋的方向,給用戶帶來一些超越他們預期的體驗??梢岳斫鉃樵跐M足用戶的基本需求、期望需求的基礎上給用戶創造附加價值體驗,屬于創新設計思維范圍,可以提升好感及忠誠度。比如:京東推出vr口紅試妝體驗,天貓推出試裝直播等。

          小結:對用戶需求設計要點

          • 用戶集體共性體驗:在主流程上識別有價值用戶群體,角色化的用戶的共同特征,符合用戶基本功能流暢、無障礙體驗。
          • 體驗體驗場景維度設計:對用戶使用的場景考慮,設計符合用戶的習慣的操作。比如:課堂播放,用戶使用場景是碎片時間:通勤、吃飯、健身等場景下,用戶對產品期望是儲存、收聽便捷的期望體驗。
          • 用戶情感維度設計:超越用戶預期,帶來驚喜、共情。
          3. 產品功能需求

          注冊流程簡化

          大量注冊資料讓用戶失去耐心,流程簡化提升新用戶流量。

          漏斗數據下的流程轉化

          在公司xx流程里,我們看到每個頁面的流失漏斗,發現用戶在購買決策「結果分析」那一步流失特別多,決定砍掉了介紹步驟,把之前5步改成三步決策。

          這是一個非常妙的設計:對用戶來說,直接觸達決策前的結果分析,用戶對結果的強感知轉化下一步操作,從數據來看這一步轉化率提高不少。

          △ 公司實際創新項目不做露出具體頁面

          留存

          新用戶進入 app 后,一般分為3個時期:振蕩期間、選擇期、穩定期。震蕩期用戶流失較多,經過一些市場對比后選擇留下的用戶會進入一個穩定期。一個用戶在產品內留存越久,帶來的商業價值越高。

          在產品體驗流程中根據不同需求,策略也有不同。舉一個 ofo 退押金例子:ofo 在不久前遭遇了資金問題,我在退押金這一流程體驗中誤操作了多次,最主要問題就是信息引導。

          △ 主流程中對用戶再三挽留

          △ 主流程操作中弱化強需求信息

          小結:對功能需求設計要點

          • 統一、體驗:減少用戶頁面跳轉,能1步完成不要放到3、4步完成。
          • 信息明確:在主流程中給用戶傳達正確信息關系,減少誤操作。
          • 數據驗證可用性價值:通過數據觀察用戶行為,驗證需求產生的價值。

          四、如何從需求達到設計目標

          1. 需求到設計目標的過程

          在需求發起到設計目標會經過這樣幾個過程:羅列與信息搜集?深入挖掘?聚焦核心?創新發散?實現與落地。

          這五步的節奏是:先發散 – 聚攏 – 再發散 – 聚攏。

          羅列與信息搜集

          • 需求羅列:根據佐藤可士和整理術,把需求按照類別、優先級進行。
          • 用戶調研:定性于定量調研結果得到用戶真正的訴求點。
          • 數據結果:通過數據結果能觀察用戶的行為特征。

          深入挖掘

          5w:what、when、wher、who、why這五步定位法,是讓設計師清楚需求的本質與動機。

          聚焦核心:濾 — 煉 — 導

          結合用研結果、數據結果、定位結果去除不重要、不必要的信息、提煉有價值的信息、導出核心關鍵。

          創新發散

          我們發現前三步是基于一些基礎方法論,讓設計師具備一些觀察用戶、分析用戶行為、洞悉本質、同理心的訓練,目的是讓我們把思維聚焦在核心的關鍵點上,而真正超越預期體驗的來源于第4步創新設計思維。

          • 創新設計思維:通過發散尋找針對聚焦點不一樣的方案的突破口,很多創新思維來源于多人思維火花的碰撞。
          • 移情設計:在發散后結合用戶情感的體驗,打造深入人心、愉悅的體驗感受。
          • 技術可行性。

          實現與落地

          • 草圖溝通;
          • 開發—測試;
          • 上線—迭代—優化。

          總結:設計的道與術

          • 道:設計創新、價值觀、愿景。
          • 術:思維方式、工作流程、洞察力、觀察、分析。

          對于設計師,解決問題能力遠高于單純作圖能力,而了解需求本質是解決問題的前提條件,在沒有明確需求的動機和目的,設計方向是迷茫的。洞察、分析是設計師的基本能力,勤于思考分析,做正確有價值的設計。

          互聯網行業幾點意見

          藍藍設計的小編

          在這個國家領導人都在強調打造一個網絡強國的時代,互聯網行業無疑是大學畢業生入職最好的選擇。互聯網很大,很多傳統行業都在向互聯網轉型,如果抓住這個機遇,學習一技之能,那么你就將擁有撬動地球的杠桿。

          Javascrpit之打字機效果

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          今天來看看怎么實現炫酷的打字機效果。即把一段話一個字一個字的顯示出來。

          效果圖:

          實現思路:

          首先規定好顯示字數的速度即settimeout執行間隔用來控制每個字之間輸出速度。再把判斷段落的總字數,循環段落總字數來實現一個字一個字的輸出。

          js代碼:

          
              
          1. var theNewsNum;
          2. var theAddNum;
          3. var totalNum;
          4. var CurrentPosion=0;
          5. var theCurrentNews;
          6. var theCurrentLength;
          7. var theNewsText;
          8. var theTargetLink;
          9. var theCharacterTimeout;
          10. var theNewsTimeout;
          11. var theBrowserVersion;
          12. var theWidgetOne;
          13. var theWidgetTwo;
          14. var theSpaceFiller;
          15. var theLeadString;
          16. var theNewsState;
          17. function startTicker(){
          18. // ------ 設置初始數值
          19. theCharacterTimeout = 50;//字符間隔時間
          20. theNewsTimeout = 2000;//新聞間隔時間
          21. theWidgetOne = "_";//新聞前面下標符1
          22. theWidgetTwo = "-";//新聞前面下標符
          23. theNewsState = 1;
          24. theNewsNum = document.getElementById("incoming").children.AllNews.children.length;//新聞總條數
          25. theAddNum = document.getElementById("incoming").children.AddNews.children.length;//補充條數
          26. totalNum =theNewsNum+theAddNum;
          27. theCurrentNews = 0;
          28. theCurrentLength = 0;
          29. theLeadString = " ";
          30. theSpaceFiller = " ";
          31. runTheTicker();
          32. }
          33. // --- 基礎函數
          34. function runTheTicker(){
          35. if(theNewsState == 1){
          36. if(CurrentPosion<theNewsNum){
          37. setupNextNews();
          38. }
          39. else{
          40. setupAddNews();
          41. }
          42. CurrentPosion++;
          43. if(CurrentPosion>=totalNum||CurrentPosion>=1){
          44. CurrentPosion=0;//最多條數不超過num_gun條
          45. }
          46. }
          47. if(theCurrentLength != theNewsText.length){
          48. drawNews();
          49. }
          50. else{
          51. closeOutNews();
          52. }
          53. }
          54. // --- 跳轉下一條新聞
          55. function setupNextNews(){
          56. theNewsState = 0;
          57. theCurrentNews = theCurrentNews % theNewsNum;
          58. theNewsText = document.getElementById("AllNews").children[theCurrentNews].children.Summary.innerText;
          59. theTargetLink = document.getElementById("AllNews").children[theCurrentNews].children.Summary.children[0].href;
          60. theCurrentLength = 0;
          61. document.all.hottext.href = theTargetLink;
          62. theCurrentNews++;
          63. }
          64. function setupAddNews() {
          65. theNewsState = 0;
          66. theCurrentNews = theCurrentNews % theAddNum;
          67. theNewsText = document.getElementById("AllNews").children[theCurrentNews].children.Summary.innerText;
          68. theTargetLink = document.getElementById("AllNews").children[theCurrentNews].children.Summary.children[0].href;
          69. theCurrentLength = 0;
          70. document.all.hottext.href = theTargetLink;
          71. theCurrentNews++;
          72. }
          73. // --- 滾動新聞
          74. function drawNews(){
          75. var myWidget;
          76. if((theCurrentLength % 2) == 1){
          77. myWidget = theWidgetOne;
          78. }
          79. else{
          80. myWidget = theWidgetTwo;
          81. }
          82. document.all.hottext.innerHTML = theLeadString + theNewsText.substring(0,theCurrentLength) + myWidget + theSpaceFiller;
          83. theCurrentLength++;
          84. setTimeout("runTheTicker()", theCharacterTimeout);
          85. }
          86. // --- 結束新聞循環
          87. function closeOutNews(){
          88. document.all.hottext.innerHTML = theLeadString + theNewsText + theSpaceFiller;
          89. theNewsState = 1;
          90. setTimeout("runTheTicker()", theNewsTimeout);
          91. }
          92. window.onload=startTicker;
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          這7種廣泛存在的認知偏差,影響了我們太多的決策

          資深UI設計者

          如今心理學和行為學已經是UX和產品設計領域當中諸多理論的來源和實踐的依據,它們是UI/UX設計師和產品設計師的必修課。

          系統的心理學和行為學的知識,對于設計工作其實有著極為深刻的影響。用戶體驗設計很大程度上是在心理學和行為學的研究基礎上逐漸進化和發展起來的,對于想要深耕這一領域的設計而言,心理學和行為學是繞不開的必修課。

          心理學和行為學早已并非是單獨存在的學科,它們和許多不同領域的知識交匯融合,圍繞著人性進行多維度全方位的探討。如今我們所熟知的許多優秀的產品,也大多從這些領域技汲取營養,不少四兩撥千斤借力逆襲的成功案例,也往往借助的是這些深深植根于人性的杠桿。

          這兩個宏大的命題并非簡單幾段話說得清楚,但是這當中有許多有意思的現象,非常具有啟發性。許多植根于人性本能中的非理性心理和行為,在日常生活中主導著我們作出決策,有的是一些不易覺察的心理效應,有的僅僅是不算太顯著的認知偏差,但是在設計和實際產品當中運用,則常常呈現出極為驚艷的效果。

          對于這些心理學效應和認知偏差,設計人員需要在自身進行決策時候盡量回避,避之不及確實會面臨車毀人亡的局面;在設計過程中,可以巧妙地將這些因素納入到考慮當中來,因為它們同樣可以影響用戶,成為撬動產品打開局面的重要的契機。

          幸存者偏差

          幸存者偏差(Survivorship bias)雖然被稱為認知偏差,但是實際上,它更接近于是一種邏輯謬誤下產生的一種錯誤認知。幸存者偏差指的是人往往會注意到某種經過篩選之后所產生的結果,同時忽略了這個篩選的過程,而被忽略的過程往往包含著關鍵性的信息。

          讀書無用論是一種最常見的幸存者偏差。讀書無用論中最多的說法是XX并沒有好好上學但是照樣掙大錢了,而XX努力讀書反而混得并不好。

          這些個案并不涉及到具體數據,從數據角度上來說,也不難解釋這種“主觀感受”的成因。根據第六次全國人口普查,大專及以上學歷的人口僅占總人口的8.7%,高學歷者落魄更容易受到媒體的關注,而低學歷中的成功者也常常能夠吸引普通人的目光,即使低學歷人口中涌現的成功者的比例遠低于高學歷者,由于基數差異,這個數值對比也是相當可觀的。正是因為忽略了數據中沉默的大多數,讀書無用論這種錯誤的觀點才“得以成立”。

          槍擊案中的幸存者大多傷的是手和腳,那么是否要加強手腳的保護呢?實際的情況上,在軀干和頭部中槍的人,大都沒有挺過來,相反更加需要保護是軀干和頭部。就像能活著回來的戰斗機中彈的通常都是翅膀和機身,因為引擎中彈的大都已經犧牲了。這個案例也許能夠幫你更好地理解幸存者偏差。

          對于事件發展過程中篩選機制的忽視,容易讓人產生錯誤的結論,從而導向錯誤的方向,在設計決策過程中,出現這樣的過程中,極有可能是致命的。

          在需求分析和調研過程中,如果忽視了幸存者偏差,很有可能搜集到的數據,體現的僅僅知識少部分用戶的需求和想法,最終將偽需求和小眾需求當作主要需求來作為設計易于,則可能讓產品從一開始就走向萬劫不復。

          在搜集產品的用戶反饋信息的時候,也很容易遭遇幸存者偏差。絕大多數的用戶在正常使用產品的時候,如果沒有合理的觸發機制,或者產品沒有特別突出的特點的情況下,很少會主動“好評”,相反,遭遇問題的用戶則更傾向于主動吐槽并分享糟糕的體驗和問題,這也很容易造成“這個產品哪哪兒都是問題”的錯覺。

          基本歸因偏差

          基本歸因偏差這個名詞同樣源自于心理學,比較學術表述是“對他人行為進行歸因的時候,往往會傾向于把別人的行為歸因為其內在因素,而低估了情境因素的影響,而對于自身的行為歸因的時候,則傾向于把自己的行為歸因為外在因素,而忽略自身因素的影響”,基本歸因偏差的含義表述可能有點拗口,但是并不難理解。

          基本歸因偏差是一種重要的人類心理防御機制,是人類進化過程中所產生的一種局限性的思維定勢。和復雜多樣的環境因素相比,行為者本身的問題是更容易被發現的,所以觀察者在觀察行為者的時候,諸如社會環境、社會角色、情景壓力等外部因素更難以引起注意,將問題更多歸因于行為者本身的行為舉動和個人內因。比如,當看到某個人生活拮據的時候,會簡單歸因于他不夠勤奮等等。類似的,在面對生活中的諸多不順的時候,直接歸因于“水逆”而很少會仔細思考是否有自身的原因。當事人和觀察者對于事件的歸因不同,爭議和問題往往因此而起。

          對于UX設計師而言,基本歸因偏差是矛盾和問題的常見的來源,而且這種認知偏差存在于用戶也同樣存在于設計師本身。無論是面對設計問題,還是做調研,進行測試,涉及到多方面影響因素的時候,基本歸因偏差都會對設計方案、設計決策產生影響。

          這需要設計師能夠清楚地分辨“我的觀點”和“我的行為”,能夠真正將自己從自己所處的立場、角色、職能上抽離出來,復盤整個局面,首先接納全部的狀況和現實,包括他人的想法、觀點,先不去判斷對錯,而是先接納所有的狀況和全部的元素,明白事物的動態變化過程,不再單一地去判斷,任何一個視角必然會存在一個立場,它們是當前事物諸多層面中的一方面而已。

          面對復雜多變,但是因果清晰、逐步成長變化的事物,用動態而全面的思維方式來看待,才能真正看清楚事物變化的軌跡,更有針對性地設計,作出合理的決策。

          后視偏見

          后視偏見(Hindsight Bias)則是另外一種常見的認知偏差,它指的是人在事情發生以后覺得自己在事情發生之前就已經預測到結果了,實際上,他們并不如自己想象的那樣能夠準確的進行預測。這種行為在觀察者眼中常常會被稱為“馬后炮”。

          后視偏見在很多人身上都存在,人的主觀性和記憶本身會造成這種偏差。對于設計工作者而言,厚實偏差的存在無疑是會帶來負面影響的。后視偏見會讓人沉迷于“我早就預料到了”這種感受當中,相應的無法真正從事件中真正汲取到有用的經驗,也難于使用公平的眼光來評判客觀事物和他人,主觀上也很容易選擇性忽略許多客觀條件和事實。

          后視偏見確實會給人帶來快感,相應的,會在工作中影響決策的正確性和公平性,從而帶來潛在風險。糾正后視偏見的方法并不復雜,在確知事情結果之前,記錄下自己的想法,事后做驗證,并統計成功與失敗的數據。

          事件的結果并非是最好的判斷因素。在調整好認知之后,對于事件和情況的過程和相關因素進行相對全面的衡量,盡可能少的摻雜主觀情緒來進行分析,這樣的決策的有效性會更強。

          曝光效應

          曝光效應(the exposure effect)也被稱為多看效應(和多看這款應用并沒有關系),接觸效應。曝光效應本身的描述也不復雜:人會更加偏好自己熟悉的事物。在社會心理學領域,曝光效應的另外一個稱謂是“熟悉定律”,這可能更好理解。

          自己總傾向于購買自己熟悉的品牌的產品,談戀愛的時候總會有繞不開的老同學和老朋友,這些都是曝光效應之下的人類認知偏差。我們常常說的“一旦接受了這個設定還挺帶感的”就是對于這一效應的真實側寫。

          曝光效應在廣告行業、產品營銷和社交媒體有著天然的親和力,對于營銷人員、運營人員、品牌設計師和UX設計師而言,這一效應的活學活用是非常有必要的。

          不過曝光效應本身并非是無條件的,相反它和產品屬性、品牌設計、企業形象以及運營策略有著極為緊密的關聯。

          曝光效應在許多不同的社會實驗當中呈現出一種不穩定性,可能是因為相關的影響因素多而復雜。有的研究表明,即使產品和服務曝光過程中絕大多數的內容是正面的,公司和企業本身的名氣高低和品牌形象,同樣會影響曝光效應的高低。

          曝光效應在發揮的過程中,即使曝光的內容全部是正面的,對于用戶的影響也會逐步呈現出一種矛盾性,也就是用戶會對產品或者服務產生正面聯想的同時,還會產生不利的、負面的感受。

          曝光效應發揮效果最好的時段,始終是絕大多數用戶對于產品認知不足的階段,這個時候曝光效應會最大化的對用戶產生影響。

          值得特別注意的是,一開始就讓人覺得厭惡和不適的產品是無法產生正面的曝光效應的,如果一開始存在沖突,曝光效應只會加深誤會和沖突。過量的曝光一定會帶來厭惡,由于復雜而大量不可控的影響因素,甚至會導致失控式的崩盤。

          對于UX設計師和產品的策劃和運營者而言,在合適時機加大產品的正面曝光是有效度最高的策略。深入了解曝光效應,才會明白何時放,而何時收。

          可得性偏差

          可得性偏差(Availability Heuristic)也是一種常見的認知偏差,它是啟發式偏差的一種,人們往往會根據自己認知上的易得性來判斷事情的可能性,甚至于會根據自己看到和聽到的只言片語來做決策,而不是根據統計學數據和系統化的知識來做判斷。

          可得性偏差同樣是一種廣泛存在的認知偏差,用戶認為自己熟悉的、更容易獲得的信息在復雜的系統中發揮著更大的作用,主觀上忽略其他的部分??傻眯云詈褪煜ざ桑ㄒ簿褪瞧毓庑┯行┰S共通的地方。

          可得性偏差在金融領域有著巨大的影響,許多準備上市的企業會在上市前夕吸引大量的新聞報道,讓投資者在信息的狂轟濫炸之下不知不覺地去關心,無意識地去了解,并最終購買這支股票拉高股價。這種策略就是借助投資者的可得性偏差來實現的。下面是谷歌搜索關鍵詞阿里巴巴的頻率和阿里巴巴的股價變化情況,兩者呈現出一種明顯的關聯性。

          可得性偏差的廣泛存在,使得設計師甚至可以在自己的產品中借助有有意識的設計,來引導用戶的行為。作為設計師本身而言,可得性偏差同樣是會影響到設計決策,因為可得性偏差同樣會影響產品設計中的設計決策的走向。消除可得性偏差的方法也不難,需要設計者不要被已知的信息和容易想起來的信息所左右,而是盡量深入地從多個角度來考慮問題,跳出固有的思維定勢,多角度看待問題,作出合理的決策。

          錨定效應

          錨定效應也被稱為沉錨效應,它一樣是一個聽起來高大上但是含義并不復雜的概念,它指的是人們對某人某事作出判斷的時候,容易受到第一印象或者第一信息的影響和支配。這種現象就像船只被錨固定在特定位置而無法移動,因此而得名。

          人們在做判斷的時候,往往會受到第一印象和首個接收到的信息的影響。就像鳥類會將第一個看到的生物視之為自己的母親一樣,人們往往會借助第一印象來作為后續判斷一個事物的參考標準,甚至在人際交往中都是金科玉律。即使是沒有刻意地去參考第一信息,人們也會在潛意識當中,重視第一次獲得的數據。

          錨定效應的另外一個層面是對比,當擁有了錨定的參考之后,用戶在后續會以此為基準進行對比。對比并不存在絕對意義上的好壞,但是在不同的基準之下,或者說參考的基點不同的情況下,發揮的作用其實是截然不同的。

          舉個簡單的例子,粥鋪的服務員問客人“加一個雞蛋還是加兩個雞蛋”比“要不要加雞蛋”所產生的銷售額高出不少,因為前者會人的心理基點是“要加蛋”,而后一種問法,則讓客人先思考“要不加蛋”,前者的轉化率自然更高。

          正是因為先入為主這種心理現象大量影響著用戶的決策,使得市場競爭中,許多企業和產品都不得不去力圖爭個第一,贏得主導權。

          iPhone X的劉海屏對于手機市場有多大影響想必大家有目共睹。而后續的藍綠兩廠的升降式攝像頭設計和“真·全面屏”也因為其突出性和強大的“第一印象”的構建,而贏得了無數贊譽。

          但是靜下心來想想,開機解鎖還要等待攝像頭升起,好像還是一個蠻奇怪的事情??墒亲钤绲摹罢妗と嫫痢贝_實夠驚艷。

          免費認知偏差

          優惠促銷是各種產品銷售中最常用到的一種策略,而在花樣迭出的促銷手段當中,有為數不多的集中手段,呈現出令人驚艷的效果。

          免費的贈品和滿額減免就是這其中的典型。購買產品A,贈送一款B,這種贈品策略的玩法可以說是效果極佳,早年間阿芙精油聲名鵲起的階段,其中最令用戶欲罷不能的,就是他們的“贈品”。用戶每一次購買精油產品的時候,阿芙的團隊會隨之一起發出精油的入門口袋書以及多達五六種精心挑選的精油試用裝,這種體貼且讓人覺得“狠賺一筆”的心理感受,使得許多新用戶迅速轉為穩定客戶。

          置于滿多少減多少,則同樣是一種成功的促銷策略。各種電商平臺和購物節都會采用花樣繁多的滿減服務,相應的,用戶在這種服務之下,總忍不住“湊單”。平心而論,真實的情況是,用戶購買了自己真正需要的商品,以及一系列為了湊單而同時購買的非必須商品,對于商家和平臺而言,這種策略很好的拉高了銷量,也減少了許多商品的庫存,而用戶也感覺自己賺到了,皆大歡喜。

          至于“包郵”,我就不贅述了。這個效果同樣非常突出。

          相比之下,打折促銷所產生的效果,好像就沒有那么顯著和“暴力”了。歸根結底,問題是出在“免費”的認知偏差之上。對于用戶而言,無論是贈品、滿減還是包郵,本質上都會讓用戶迅速地在大腦中形成一種“免費獲得某種東西”的感覺,贈品對應的是免費的物品,滿減對應的是免費的現金回饋,包郵則是免費的郵寄服務。

          心理學家和行為學家通過大量的實驗驗證了免費確實和折扣等其他的促銷策略有著本質的差別,它所帶來的非理性行為要明顯太多,免費的吸引力無與倫比,說是認知偏差毫不為過。

          你一定特別想點擊上面的圖片免費下載素材。不好意思它只是個圖片。

          人類本能地懼怕損失,選擇免費的贈品不會有損失,而相比之下選額其他則會讓人在潛意識中產生風險感,可能會蒙受損失。這樣一來,免費的贈品在人心中的價值就開始高于實際價值,隨之而來的就是非理性消費。

          在設計的過程中,想要讓免費的認知偏差發揮效果,讓人快速地感知到這種“免費獲得”的感受,應當是明顯的,否則很難快速地觸發非理性的反饋。

          結語

          人類先天的生物性無處不在,我們自詡的理智在現實生活中發揮的作用并沒有我們想象中那么多,無處不在的各種認知偏差主導了太多的

          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合