首頁

node系列之?dāng)?shù)據(jù)接口注冊接口的實現(xiàn)(token驗證登陸)

seo達(dá)人

node系列之?dāng)?shù)據(jù)接口注冊登陸接口的實現(xiàn)

1、使用express腳手架創(chuàng)建項目

2、了解項目的目錄結(jié)構(gòu)

3、準(zhǔn)備數(shù)據(jù)庫相關(guān)文件

4、編寫注冊接口

5、編寫登陸接口

6、驗證登陸實現(xiàn)

7、預(yù)告

1、使用express腳手架創(chuàng)建項目

// 安裝腳手架,只需安裝一次

npm i express-generator -g

// 創(chuàng)建express項目

express myapp --view=ejs

cd myapp

// 安裝依賴

npm i 

// 安裝需要使用的模塊

// 數(shù)據(jù)庫模塊 用戶唯一id模塊 密碼加密模塊 token模塊

npm i mongoose node-uuid bcryptjs jsonwebtoken -S



2、了解項目的目錄結(jié)構(gòu)

bin

www ------- 服務(wù)器啟動

node_modules ------- 項目的依賴文件

public ------- 靜態(tài)資源文件夾

images ------- 靜態(tài)圖片

javascripts ------- 靜態(tài)的js文件

stylesheets ------- 靜態(tài)的樣式表文件

routes ------- 路由文件

index.js ------- 默認(rèn)的路由

users.js ------- 用戶相關(guān)的路由

views ------- 路由對應(yīng)的頁面

index.ejs ------- 默認(rèn)的首頁

error.ejs ------- 錯誤頁面

app.js ------- 使用中間件,注冊路由

package.json ------- 描述文件

3、準(zhǔn)備數(shù)據(jù)庫相關(guān)文件

大勛在node系列之?dāng)?shù)據(jù)庫mongoose的封裝中給大家介紹了如何封裝mongoose,可以先行查看如何封裝,封裝的文件夾為sql,如果不想看的,可以直接通過網(wǎng)盤下載該文件夾



將該sql文件放置項目的跟目錄下


  • myapp

    - sql

    - collection

    users.js

    db.js

    index.js



    4、編寫注冊接口

    目標(biāo)文件: myapp/routes/users.js



    實現(xiàn)思路:使用post提交數(shù)據(jù)的方式,先以手機號查詢有沒有該用戶,如果有該用戶,提示用戶該賬號已經(jīng)注冊過了;如果沒有該用戶,則可以完成注冊,首先得將密碼加密,加密完成后插入數(shù)據(jù)庫



    代碼實現(xiàn):



    // 找到用戶集合

    var User = require('./../sql/collection/users');

    // 找到數(shù)據(jù)庫封裝文件

    var sql = require('./../sql');

    // 狀態(tài)碼的封裝

    var utils = require('./../utils')

    // 用戶唯一標(biāo)識的id

    var uuid = require('node-uuid');

    // 密碼加密模塊

    var bcrypt = require('bcryptjs');

    var salt = bcrypt.genSaltSync(10); // 加密級別



    // 實現(xiàn)注冊接口 -- post提交方式

    router.post('/register', (req, res, next) => {

      // 1、先獲取表單信息

      let { username, password, tel } = req.body;

      // 2、根據(jù)手機號查詢 用戶集合中是否有該用戶,如果有,返回有該賬戶,如果沒有注冊繼續(xù)

      sql.find(User, { tel }, { id: 0 }).then(data => {

        // 2.1 判斷有沒有該用戶

        if (data.length === 0) {

          // 2.2 沒有該用戶----繼續(xù)完成注冊操作

          // 2.2.1 生成用戶的id

          let userid = 'users
    ' + uuid.v1();

          // 2.2.2 對密碼加密

          password = bcrypt.hashSync(password, salt)

          // 2.2.3 插入數(shù)據(jù)庫

          sql.insert(User, { userid, username, password, tel}).then(() => {

            res.send(utils.registersuccess)

          })

        } else {

          // 2.3 已有該用戶

          res.send(utils.registered)

        }

      })

    })



    附 狀態(tài)碼封裝模塊 myapp/utils/index.js

    module.exports = {

      registered: {

        code: '10000',

        message: '該用戶已注冊,請直接登錄' 

      },

      registersuccess: {

        code: '10101',

        message: '注冊成功' 

      }

    }



    5、編寫登陸接口

    目標(biāo)文件 myapp/routes/users.js

    實現(xiàn)思路:根據(jù)手機號查詢有沒有該用戶,如果沒有,提示用戶未注冊,如果有該用戶,使用bcryptjs模塊驗證密碼的有效性,如果有效,生成token,返回給前端相應(yīng)的token值。

    var jwt = require('jsonwebtoken');

    // 實現(xiàn)登陸功能

    router.post('/login', (req, res, next) => {

      // 1、獲取表單信息

      let { tel, password } = req.body;

      // 2、依據(jù)手機號查詢有沒有該用戶

      sql.find(User, { tel }, { _id: 0 }).then(data => {

        // 2.1 判斷有么有該用戶

        if (data.length === 0) {

          // 2.2 沒有該用戶

          res.send(utils.unregister)

        } else {

          // 2.3 有該用戶,驗證密碼

          // 2.3.1 獲取數(shù)據(jù)庫中的密碼

          let pwd = data[0].password;

          // 2.3.2 比較 輸入的 密碼和數(shù)據(jù)庫中的密碼

          var flag = bcrypt.compareSync(password, pwd) // 前為輸入,后為數(shù)據(jù)庫

          if (flag) {

            // 2.3.3 密碼正確,生成token

            let userid = data[0].userid

            let username = data[0].username

            let token = jwt.sign({ userid, username }, 'daxunxun', {

              expiresIn: 606024// 授權(quán)時效24小時

            })

            res.send({

              code: '10010',

              message: '登陸成功',

              token: token

            })

          } else {

            // 2.3.4 密碼錯誤

            res.send({

              code: '10100',

              message: '密碼錯誤'

            })

          }

        }

      })

    })



    6、驗證登陸實現(xiàn)

    目標(biāo)文件: myapp/app.js

    實現(xiàn)思路:很多的數(shù)據(jù)請求都需要登陸之后才能獲取到,在此統(tǒng)一封裝驗證登陸

    // 引入token模塊

    var jwt = require('jsonwebtoken');

    // 全局的路由匹配

    app.use((req, res, next) => {

     // 排除登陸注冊頁面

      if (req.url !== '/users/login' && req.url !== '/users/register') {

      // 不同形式獲取token值

        let token = req.headers.token || req.query.token || req.body.token;

        // 如果存在token ---- 驗證

        if (token) {

          jwt.verify(token, 'daxunxun', function(err, decoded) {

            if (err) {

              res.send({ 

                code: '10119', 

                message: '沒有找到token.' 

              });

            } else {

              req.decoded = decoded;  

              console.log('驗證成功', decoded);

              next()

            }

          }) 

        } else { // 不存在 - 告訴用戶---意味著未登錄

          res.send({ 

            code: '10119', 

            message: '沒有找到token.' 

          });

        }

      } else {

        next()

      }

    })




想讓視覺層次更加清晰?來看這篇視覺間隔方法完全梳理!

資深UI設(shè)計者

在網(wǎng)頁和移動端界面中,內(nèi)容和信息是否能夠經(jīng)過系統(tǒng)性、有效的整理和組織,對于內(nèi)容的可用性和實用性,都是意義巨大的。而在呈現(xiàn)信息的時候,視覺間隔是組織信息的關(guān)鍵因素。它說起來并不難理解,但是在實際的運用當(dāng)中,卻是千變?nèi)f化,今天我們來梳理一下流行的視覺間隔的方法。

什么是視覺間隔

視覺間隔是一種布局元素,它有助于將內(nèi)容分隔成為清晰的分組、選項和部分。它可以讓設(shè)計師更好地組織內(nèi)容的視覺體驗,處理信息的層級,也有助于用戶理解內(nèi)容,明白內(nèi)容之間的關(guān)系。

視覺間隔和頁面上的其他內(nèi)容在一起,構(gòu)成視覺層級,這是它最重要的作用。在視覺間隔的幫助之下,用戶可以輕松地感知內(nèi)容之間的關(guān)系,明白各個信息片段之間的關(guān)系是相似,并列,承襲,從屬,還是其他。

視覺間隔的可用性也同樣重要:在很多時候,有的視覺間隔元素看起來是可點擊,可交互的,這在移動端界面上,是非常重要的。

視覺間隔的種類

談到視覺間隔,我們可以從兩方面來進行拆解分析:視覺間隔的外觀和功能。按照視覺特征,視覺間隔有5種基本的類型:

  • 線條
  • 色彩
  • 負(fù)空間
  • 陰影/體積
  • 圖片

下面我們分別針對這5種類型進行說明。

線條

很長時間以來,在排版印刷領(lǐng)域,線條就一直是一種用來分隔內(nèi)容的方法。線條的分隔功能是認(rèn)可度最高的一種間隔方式,用戶幾乎不用思考,就能夠理解和感知它,并且發(fā)揮作用。

另一方面,這種間隔方式也很容易顯得過于簡單,并且和應(yīng)有的形態(tài)相去甚遠(yuǎn)。這也是為什么設(shè)計師在想盡辦法去尋求別的視覺間隔形態(tài)。太多的線條間隔會讓屏幕上的視覺干擾太多,并且?guī)聿槐匾囊曈X噪音。

所以,能夠?qū)⒕€條間隔用得微妙、恰到好處、出神入化,是設(shè)計師功力的一個重要體現(xiàn)。

在這個網(wǎng)站產(chǎn)品頁面中,使用深色的線條間隔來分割產(chǎn)品信息,用來組織和間隔信息內(nèi)容。

在這個頁面當(dāng)中,線條分隔了不同的內(nèi)容區(qū)塊,讓頁面的結(jié)構(gòu)更易于被掃讀。

這個電商網(wǎng)站將不同級別的視覺內(nèi)容進行了分離,借助簡單的水平線將價格、CTA按鈕以及承載相關(guān)信息的表單分隔到不同的區(qū)域。

負(fù)空間

負(fù)空間,也就是留白,也是最為常見的一種視覺分隔元素。留白絕不是對空間的浪費,和屏幕上其他的元素一樣,它同樣發(fā)揮著重要的作用,拱衛(wèi)支撐著整個用戶體驗。負(fù)空間是最為流行的視覺分隔之一,尤其是在極簡主義風(fēng)格為主導(dǎo)的設(shè)計當(dāng)中。負(fù)空間本身遵循著格式塔原理,尤其是其中「接近原理」和「相似原理」是負(fù)空間在設(shè)計中,發(fā)揮分隔作用的核心所在。合理地運用負(fù)空間,還能強化頁面的呼吸感。

上面這款旅行規(guī)劃 APP當(dāng)中,使用留白將不同的條目分開,沒有使用額外的具體視覺元素,僅僅只靠留白。

Health Blog 的列表的排版層次是基于負(fù)空間來實現(xiàn)的,看起來清晰又充滿呼吸感。

色彩對比

高對比度的色彩,同樣能夠帶來清晰的視覺間隔效果。在 UI 界面中高對比度的色彩有著極為明顯視覺表現(xiàn)潛質(zhì),它們能夠增強網(wǎng)站的信息和內(nèi)容的表現(xiàn)力,分割區(qū)塊,營造氛圍。對比度是影響頁面和屏幕可讀性的關(guān)鍵因素之一。在具體的應(yīng)用當(dāng)中,不同的色彩會有效地分離不同的選項、條目和區(qū)域,這意味著它作為視覺分隔的作用非常強。這也是近年來分屏式設(shè)計如此流行的原因所在。

這是一套移動端菜單的概念設(shè)計,強烈的色彩對比讓信息清晰可見。

即使是在這樣的柔和的設(shè)計當(dāng)中,色彩的對比度也發(fā)揮了相當(dāng)?shù)淖饔茫阂环矫妫瑥娏业纳蕦Ρ茸孋TA按鈕和輸入框之間有了明顯的區(qū)分,另一方面,右側(cè)的主視覺元素的背景也同樣借由不同色彩的對比,做到了突出的效果。

在 GNO Blankets 這個網(wǎng)站當(dāng)中,強烈的明暗對比將網(wǎng)站元素分隔成為精美而清晰的區(qū)塊。

陰影和體積

陰影和體積也是一種非常常見的視覺間隔方式,通過營造在「高度」或者說高程上的視覺差異,從而達(dá)到分層的效果,而這種設(shè)計也是符合人類一直以來的認(rèn)知習(xí)慣。這種方法有利于保持整個設(shè)計的平衡和易讀性,另一方面,它又能保持足夠的微妙和自然,不會那么引人矚目從而讓人覺得出戲或者受到干擾。

這個APP的目錄頁面所有元素都采用了白色的背景,而陰影讓布局呈現(xiàn)出了縱深層次,讓內(nèi)容足以展現(xiàn)又不顯突兀。

這款提供定制化花束服務(wù)的APP也采用了類似的陰影元素,讓整體看起來清晰又通透。

圖片

圖片在 UI 界面當(dāng)中,同樣也是一種非常有效的視覺間隔,尤其是在包含大量文本內(nèi)容的界面中。無論是博客、在線媒體網(wǎng)站還是其他類型的網(wǎng)站當(dāng)中,圖片的間隔作用都非常明顯。無論是照片、插畫、3D圖形,它們作為圖片都可以很好的平衡文本內(nèi)容,提高內(nèi)容的識別度和可讀性,有效地劃分層級,并且提高情感吸引力。

這個比特幣網(wǎng)站的著陸頁就使用了帶有3D效果「了解更多」動態(tài)圖片,圖片和文本在內(nèi)容和功能上都清晰地分隔開來。

在這個餐廳 APP 當(dāng)中,圖片作為劃分內(nèi)容的關(guān)鍵元素而存在。

按照功能劃分

如果從功能的角度上來劃分視覺間隔,可以根據(jù)它所處的層次來進行劃分。

全出血間隔

使用線條作為全出血間隔是最為常見的,它會很跨整個屏幕布局來作為信息層級的劃分。

這個畫廊圖庫 APP 的藝術(shù)家目錄當(dāng)中,使用線條作為全出血間隔,來區(qū)分藝術(shù)家。

這個名為完美食譜的APP也使用了全出血間隔線來區(qū)分內(nèi)容。

在這個財務(wù)APP當(dāng)中,也使用了全出血間隔線來區(qū)分條目。

在這個電影APP的結(jié)帳頁面當(dāng)中,也使用了線條來作為全出血間隔。

嵌入式間隔

嵌入式間隔的功能是將相關(guān)性較高的內(nèi)容分割開,并且它通常會和標(biāo)題或者其他的特定元素保持對齊或者對應(yīng),它們通常是進行某個大區(qū)塊內(nèi)不同組件的分隔,或者將多個同類的元素分隔開。

這個網(wǎng)站當(dāng)中,使用橫向的短分隔線來區(qū)分表單中的參數(shù)條目。

中間分隔

這種分割線通常會置于布局的中間某處,同樣是分隔相關(guān)的內(nèi)容,但是通常它們在屬性上不一定是一致的,但是層級近似。

在這個出售草藥的電商網(wǎng)站的右側(cè),使用中間分隔線將文本和可交互的區(qū)域清晰地分隔開。

值得思考的問題

上面對于不同類型的視覺分隔方式都有描述,在此之外,還有兩個問題需要注意:

  • 保持微妙:視覺分隔不應(yīng)該醒目、太過引人矚目,它們不應(yīng)該分散用戶的注意力,它們應(yīng)該支撐布局的同時,微妙而不那么抓人眼球。

  • 中等頻率:這和上一點是相輔相承的,過多的分隔線會變成視覺噪音,讓用戶瀏覽的時候感到疲倦。因此,應(yīng)該仔細(xì)考慮使用頻率,盡可能使用負(fù)空間,而不是線條。不要過度使用太多色彩,應(yīng)該盡量保持整體的協(xié)調(diào)一致。

文章來源:站酷

通知系統(tǒng)的設(shè)計規(guī)則全面分析

資深UI設(shè)計者

我們通過門鈴聲兒得知門外有人來訪,也能通過電話鈴聲得知正被人呼叫。短信通知也有著類似的作用,包括各類產(chǎn)品的消息推送。

但不同的是,消息推送的重要性隨著「通知」被濫用而變得不那么重要了。它們變得不像門鈴或電話鈴聲起到的作用性那么大,包括短信現(xiàn)在也大多是垃圾信息。

而且,通知越來越多地通過各種方式去觸達(dá)用戶。比如消息未讀的紅點提示,或者顯示消息的數(shù)字統(tǒng)計,以及手機使用過程中的頂部提示與聲音或震動的提醒,等等。

但我們還是無法抑制點擊圖標(biāo)的沖動,這僅僅是因為它具有未讀的計數(shù)或紅點提示,即使我們已經(jīng)知道當(dāng)中的內(nèi)容并不重要。

而我要說的是,當(dāng)通知內(nèi)容變得次要且被濫用之后,它仿佛成了一種違背設(shè)計原則的功能 —— 中斷用戶當(dāng)前行為。因為它打破了用戶與產(chǎn)品之間的層級關(guān)系,破局至產(chǎn)品之外來吸引用戶的注意力,這是一個非常打擾的行為。如果我在看書,突然收到一條并不重要的消息,那我一定會非常反感。

所以,為了不被「紅點」支配,以及不讓通知所打擾,我會把手機里所有產(chǎn)品的消息推送都給關(guān)了。

但是,以上內(nèi)容并不能說明通知的無用論。同樣有許多用戶還是沉迷于通知的使用上,它所控制的是用戶對于某個產(chǎn)品的控制欲,擔(dān)心錯過某條消息,就好像我在豆瓣寫了篇隨筆,就想看別人給我點贊評論的消息,但我又不可能一直盯著,所以通知這時候就起到了一個很好的作用。

以至于對于優(yōu)秀的產(chǎn)品人或設(shè)計師,包括運營來說,利用好通知,就能掌握用戶心理,巧妙的將用戶留在產(chǎn)品中。它們甚至有助于與打算放棄產(chǎn)品的用戶建立聯(lián)系并促進互動。

那么,我們應(yīng)該如何更合理的設(shè)計通知呢?下面我們通過「通知的組成部分」以及「通知的使用類型與規(guī)則」來詳細(xì)做一次拆解。

通知的組成部分

關(guān)于通知的簡單定義:它是一種吸引用戶注意的功能模式,讓用戶獲悉新事件的信息動態(tài)。產(chǎn)品將其發(fā)送給用戶并與用戶產(chǎn)生交流。

因此從這個定義中我們可以知道,通知有兩種形式,分別是被動只讀型和操作反饋型。

被動只讀型,是指該信息可讀,但不可進行操作;操作反饋型,是指用戶可對該通知進行操作,如某寶訂單支付成功后的地址信息確認(rèn)通知。

所以在梳理組件的時候也要注意掉這個差異。

1. 消息中心

這里的消息中心,是一個信息匯總中心,但并不一定是信息來源。意思是,信息來源可能是有很多用戶在你的文章下面點贊了,而這個點贊行為被匯總到了消息中心,再用消息中心指引作者去到文章頁面查看具體詳情。

所以它是一個匯總表。但也有可能它就是信息來源點,比如一些系統(tǒng)通知,告知要升級,因為它沒有其他功能可承載,所以只會在消息中心里出現(xiàn)。

或者類比 iOS 系統(tǒng)的通知中心,如果通知是 App 推送的,那么它會指引用戶進入某個 App;如果通知是系統(tǒng)行為,如勿擾模式,「6:00 前來電和通知將會靜音」這個通知,是只可在通知中心進行操作的。想要更改,就需要手動打開設(shè)置。

2. 通知指示符

它可以是點,也可以是計數(shù)器,只要表明目前消息中心有新的信息就可以。我個人一直覺得這就是讓我們多數(shù)人養(yǎng)成強迫癥的罪魁禍?zhǔn)住?

3. 信息標(biāo)題

它主要是指該信息來自于誰或?qū)儆谑裁醋宇愋?,比如用戶互動點贊消息,評論消息,系統(tǒng)消息等等。用戶可以通過標(biāo)題來獲悉該信息類型,再通過內(nèi)容摘要來判斷內(nèi)容是否重要。

當(dāng)然,這里的摘要如果過長,就需要省略處理,引導(dǎo)用戶進入消息源或消息中心。

4. 推送時間

推送時間是一個看起來簡單,實際上也好像不是很復(fù)雜的邏輯。只要說明該通知的發(fā)送時間即可,但是需要注意的是時間段問題。比如幾分鐘前,幾小時前,幾天前,這里的邏輯是按照時間推進規(guī)則持續(xù)增加來告知用戶該消息的推送時間節(jié)點的。也就是過得越久,時間概念就越大。

5. 通知圖標(biāo)

上面講到消息類型,我們也經(jīng)常會在各類產(chǎn)品中發(fā)現(xiàn)不同通知的類型會匯總在各自的類型下。包括用戶所接收到的信息,通常也會告知用戶該信息屬于什么類型。有時候,標(biāo)題可能會更細(xì),但是用戶通過圖標(biāo)可以判斷該信息屬于什么類型,甚至都不需要仔細(xì)查看標(biāo)題與內(nèi)容。

但是,并不是所有產(chǎn)品的信息都可以通過圖標(biāo)來判斷,有時候圖標(biāo)只是一個大方向,如果手機鎖屏,相對于用戶來說,這條通知只是告訴用戶該信息是由什么產(chǎn)品推送,而并不能指向至該產(chǎn)品的什么類型的信息。所以在使用的過程中,同樣需要根據(jù)業(yè)務(wù)的場景,謹(jǐn)慎地選擇圖標(biāo)。

6. 閱讀指示器

它就像是上面提到的紅點,這里指的是進入 App 的消息中心之后,所顯示的內(nèi)容。

7. 操作行為

這里的操作行為分兩種,分別是 App 外與 App 內(nèi),它們之間的操作邏輯是不同的。iOS 系統(tǒng)通知的清除操作,只是在系統(tǒng)的通知中心將該信息清除,進入具體 App 后,這條消息還是會存在。而在 App 內(nèi)刪除該條信息,則該信息才會真正消失。

所以從上面可以看到,通知推送,是有兩大類別的,分別是 App 外與 App 內(nèi),它們之間的邏輯關(guān)系與展示形式會有所差異,需要根據(jù)具體情況進行設(shè)計分析。

8. 小結(jié)

對上面的內(nèi)容進行總結(jié),可以得到這樣一幅畫像:

大部分系統(tǒng)或產(chǎn)品的通知組成,都可以通過此圖概括,唯一不同的是,它們會隨著不同的業(yè)務(wù)而發(fā)生變化。

比如豆瓣的推送消息告知用戶近期有新的電影上映,那么通知來源要么是電影模塊的功能詳情頁,要么是通知中心的系統(tǒng)消息;而通知類型就是內(nèi)容更新;詳情則根據(jù)具體內(nèi)容來組合排列;最后送達(dá)至用戶。

而其中的差別就是,如果是通知中心推送的,用戶點擊之后則是進入通知中心列表。如果是具體功能推送的,那么用戶點擊進入的就是具體功能頁面。如下圖所示:

從這里可以看出,通知是有具體模式的。

一旦確定了通知的主要目標(biāo),以及想要解決的問題,包括它們?nèi)绾螌I(yè)務(wù)產(chǎn)生作用以及對用戶形成吸引力,就可以確定通知的具體樣式了。

在這一節(jié)里只要知道通知的組成部分與通知模式如何指引用戶進入 App 即可。后面我來帶大家理一遍邏輯,以及在設(shè)計通知時要注意哪些問題。

通知的使用方法

聊完上面的內(nèi)容之后,我相信大家對通知的組成與使用模式已經(jīng)有了全新的認(rèn)識,但也僅此而已,我們還是不知道一個優(yōu)秀的通知功能應(yīng)該從哪些方面去提升用戶體驗。這里面所包含的不止是表象,還有內(nèi)在的規(guī)則邏輯。所以從這一節(jié)開始,我們仔細(xì)來梳理一遍。

從我們平時使用到的,以及上文提到的,可以大概先梳理出幾類常見的通知類型。

1. 用戶信息類通知

這種類型的通知有很多,比如微信消息發(fā)送,知乎私信,手機短信等等,它們主要由用戶主動生成發(fā)送至其他用戶被動接收,作用就是促進用戶與用戶之間的互動關(guān)系,以提升用戶使用產(chǎn)品的頻率與時長。

這種通知,可給予用戶操作也可不給予操作,不操作就是讀取,并回復(fù);操作就是可對該用戶的信息進行屏蔽、已讀、刪除等設(shè)置。

這是最常見的通知類型,在多數(shù)社交產(chǎn)品與有社交特性的產(chǎn)品里都能看到。

說明

之所以給予用戶信息的操作行為,是因為用戶信息可分為感興趣的與不感興趣的,它主要取決于人。不感興趣的人,頻繁的發(fā)送信息,會影響用戶對產(chǎn)品的好感度,畢竟有很多用戶消息并不是用戶想要接收的,所以在社交產(chǎn)品里,用戶可刪除好友,或拉黑好友;在有社交屬性的產(chǎn)品里,用戶可拉黑賬戶,以達(dá)到不被騷擾的訴求。

如果沒有到達(dá)刪除好友的程度,也可對該好友的信息進行屏蔽,甚至對該好友信息做已讀而實際上未讀的處理;或者對重要信息做未讀而實際上已讀的處理。

當(dāng)然,用戶還能對群消息做更復(fù)雜的設(shè)置。這就是產(chǎn)品對這類通知的一種優(yōu)化方式。

2. 系統(tǒng)推送類通知

我們經(jīng)常會在手機上收到一種系統(tǒng)類通知,或者在 App 中也會收到類似的系統(tǒng)通知。大多是關(guān)于系統(tǒng)升級,密碼更新等。

這類通知多數(shù)是用戶被動接收,且對于系統(tǒng)與用戶來說是較為重要的。當(dāng)然也有不重要的,比如 App 更新說明的通知,告知用戶新功能有什么變化,或系統(tǒng)更新了什么等等。

對于這類通知,用戶大多無法進行設(shè)置,因為它們比較強制,沒有可以商量的余地,類似于告知用戶:我們有新的消息,比較重要,你來看看,即使你不打算更新或執(zhí)行也來看下。

說明

系統(tǒng)類通知,通常來說較為被動,要么強制用戶執(zhí)行操作,要么就是提醒用戶系統(tǒng)近期做了更新,或者是一些并不重要的信息提示,比如勿擾模式。

強制類系統(tǒng)通知不能頻繁,否則會給用戶造成控制欲反制的副作用。類似于本身用戶使用產(chǎn)品需要對產(chǎn)品享有控制權(quán),現(xiàn)在反而被產(chǎn)品控制了。這是不行的。

3. 通用推送類通知

這類通知就是第一節(jié)中提到的那些,比如點贊/評論,內(nèi)容更新等等,這類通知如果是忠實用戶,那么或許不會反感它的頻率,當(dāng)然還是需要適當(dāng)。但如果是普通用戶,那么造成的影響就是直接關(guān)閉該 App 的所有通知。

我們現(xiàn)在的很多人,之所以開始反感通知的主要原因,就是這類通知所造成的。內(nèi)容不斷更新,隨著時間的推移,每天推送多條對于該用戶來說無用的通知。包括只適合一些符合條件的用戶參與的活動通知也推送給所有人,那么用戶就會逐漸對這類產(chǎn)品的通知失去興趣,造成無法彌補的損失。

即便像某團一樣,經(jīng)常彈出開啟通知的彈框,也依然無法召喚回用戶。這就是很典型的下場。

說明

通用型通知,如果是業(yè)務(wù)很復(fù)雜的產(chǎn)品,就必須建立通知推送的功能模塊,給予用戶進行選擇接受哪類信息的權(quán)力。允許用戶進行相應(yīng)的設(shè)置,如活動類推送可拒絕接收。

在很多產(chǎn)品中都已經(jīng)置入這樣的推送模塊設(shè)置,如下圖。

這類內(nèi)容就是針對于產(chǎn)品的具體業(yè)務(wù)進行細(xì)分。

比如興趣精選,私信消息等做好類別劃分。用戶可對自己感興趣的通知做選擇性的推送接收。

另外就是,在相同賬戶的不同設(shè)備之間,推送應(yīng)該同步推送與被處理。不能這邊推送了,那邊沒推送,或者這邊處理了,那邊沒被處理。

4. 智能推送類通知

不知道大家是否有印象,在使用如大眾點評等產(chǎn)品時,只要你切換了城市,產(chǎn)品就會推送通知告知用戶該城市有哪些值得游玩的景點與品嘗的美食。

雖然這類通知還算不上多少智能,但至少在用戶群體中是存在這類訴求的。而這類訴求有時候并不能主動感知,因為用戶可能會想不起來通過哪類產(chǎn)品來查找附近美食。當(dāng)這么一條通知出現(xiàn)的時候,正好解決了用戶的問題,反而提升了用戶對于產(chǎn)品的好感度。

現(xiàn)在很多產(chǎn)品的通知都逐漸智能化,不會像以前那樣,三更半夜發(fā)來一條無關(guān)緊要的通知。而出現(xiàn)這類問題的主要原因還是在于產(chǎn)品、設(shè)計、運營,在這方面沒有下過功夫,只將通知作為一種普通的工具來使用。導(dǎo)致用戶開始排斥通知,將其強制關(guān)閉。之后,就很難再讓用戶開啟了。同理心效應(yīng),當(dāng)做這類功能的時候,可以回想一下自己是如何被其他產(chǎn)品打擾的。

隨著大數(shù)據(jù)的發(fā)展,我相信未來的通知系統(tǒng)會更加全面,且能做到千人千面的模式,不過在此之前,各位產(chǎn)品設(shè)計師,還需要對通知下一番功夫才是。

5. 小結(jié)

我們還可以繼續(xù)舉例說明,但是基本大同小異,所以到這里為止,我再對上面的內(nèi)容做一次總結(jié),梳理出一個好的通知應(yīng)該是如何設(shè)計的。

干擾最小化:通知本身具有強制性和干擾性。它的目的是把用戶的注意力吸引到產(chǎn)品上來,所以要認(rèn)真思考發(fā)送通知的內(nèi)容、時間、頻率;不要提醒用戶當(dāng)前屏幕上已經(jīng)處于展示狀態(tài)的內(nèi)容;也不要推送與用戶無關(guān)的系統(tǒng)信息。

跨設(shè)備:當(dāng)用戶讀過了某條信息,這條信息應(yīng)該不再做展示。同理,用戶也應(yīng)該能夠在其它更適合接收消息的設(shè)備上找到已讀信息。用戶通知應(yīng)該在所有設(shè)備上進行同步。

允許設(shè)置:允許用戶在「設(shè)置」中禁止或調(diào)整通知的形式。如案例一,通過選擇推送內(nèi)容,來影響接收推送的頻率。案例二,可選消息提醒的形式是紅點+數(shù)字,或僅是紅點。

時效性:良好的通知應(yīng)盡可能實時推送。而不是等這件事情都過去很久了,才推送給用戶知道。

支持匯總:把同類型的通知合并為一條,并顯示信息未讀數(shù)量。也可以考慮一鍵展開通知,顯示信息詳情。

可操作性:把通知和操作結(jié)合在一起,讓用戶不需要打開首頁就能對特定通知進行常規(guī)操作。操作應(yīng)該清晰明了,且僅在未重復(fù)默認(rèn)操作時提供。同時操作應(yīng)該是有意義、實時、和內(nèi)容對應(yīng)的,并且能讓用戶完成某個任務(wù)。如案例一,可以在不打開郵件的情況下,直接對通知進行管理、查看和清除。案例二中的操作針對的是未讀郵件,可便捷地在通知板面進行回復(fù)、刪除、標(biāo)為已讀或垃圾郵件。

總結(jié)

對本篇文章的拓展總結(jié):

  • 通知具有召喚屬性,但是頻率過多就會變成打擾,所以要注意通知的頻率與內(nèi)容重要性;
  • 設(shè)計師或產(chǎn)品經(jīng)理應(yīng)該將通知的內(nèi)容分類梳理出來,以便維護或新增必要需求可能需要用到的推送信息。
  • 通知一般為兩種類型,一類是推送只讀型,一類是操作反饋型;設(shè)計師需根據(jù)不同類型的通知做好對應(yīng)的設(shè)計,針對具體問題具體分析;
  • 想要利用好「通知」,也需要對業(yè)務(wù)有詳細(xì)的了解,再代入本文所列舉的注意點,就可以設(shè)計出一個體驗更佳的通知模式。
  • 通知規(guī)則不會脫離本篇文章的范圍,所以只要詳細(xì)研讀,必會有所收獲。

文章來源:站酷

如何創(chuàng)建精致的UI界面布局篇

ui設(shè)計分享達(dá)人

前言

前面已經(jīng)完成這個系列的 “排版和圖形”兩篇文章,本周接著后面的 布局篇幅,我們知道布局的好壞直接影響產(chǎn)品美觀度,不同形式的布局,給用戶帶來的感受是不一樣的,產(chǎn)品也將會有不一樣的性格,因為布局直接影響界面空間疏密程度,不同產(chǎn)品都有著不同空間,那么我們要如何做,才能更好的去布局,并且能在激烈的競爭中脫穎而出,現(xiàn)今大部分產(chǎn)品基本都是長得差不多,作為設(shè)計師更應(yīng)該去多研究一些布局趨勢,并能將其融匯在自家產(chǎn)品中。 




為什么要重視布局

- 
布局對界面設(shè)計來說十分重要,不僅是我們常說的在移動端或者web端的設(shè)計中,他在車載中、電視端UI或者VR設(shè)計同樣有很大影響。我們知道界面設(shè)計中最關(guān)鍵的五大基礎(chǔ)語言;形,色,字,質(zhì), 構(gòu),其中 構(gòu)(結(jié)構(gòu))即是我們所說的布局,五個維度之前已經(jīng)和大家分享了 圖形和字體篇,今天我們可以看下布局對界面設(shè)計的影響,以及我們該如何通過布局來使界面設(shè)計看起來更加有范,更有自己的視覺特征點在里面。 




目前主流布局趨勢是怎樣的

-

前面在向大家介紹布局的重要性和他對界面設(shè)計的影響,那么如果我們需要做出一些比較有創(chuàng)新的布局來提高界面精致度,該如何去下手呢?我們可以通過觀察目前主流一些趨勢做法,了解國外設(shè)計師如何找到更有創(chuàng)意的方式來設(shè)計他們的布局 - 并將一些創(chuàng)意運用到界面設(shè)計中的,下面我們一起看下。 





偏移與疊加網(wǎng)格布局

-

網(wǎng)格布局我相信大部分人都知道,很熟悉,那么今天所說的偏移疊加網(wǎng)格布局是什么樣子的呢?其實就是我們在設(shè)計界面時候,把最底層基礎(chǔ)網(wǎng)格搭建好后,上層的內(nèi)容排版,通過錯落疊加方式來布局,這種布局的優(yōu)點是留白空間大,呼吸感強,圖文錯落交織一起,形式感增強。缺點是,運用的范圍會小一些,承載內(nèi)容少,一般Web端運用比較多。當(dāng)然也有一些移動端設(shè)計個性化產(chǎn)品存在這樣的布局 (Rover APP)可以去下載體驗下。 


上圖文字與圖片交疊錯落排版,圖片與圖片之間也是網(wǎng)格交錯



上面移動端設(shè)計,設(shè)計師通過留出左側(cè)空網(wǎng)格,整體內(nèi)容往右側(cè)偏移,導(dǎo)航相對內(nèi)容來說做了差異化設(shè)計,并未進行偏移設(shè)計(看我上圖紅框部分)  。這樣做的目的是因為,我們點擊漢堡菜單的時候,本來整體就要往右側(cè)移動,如果再繼續(xù)移動,那么內(nèi)容會顯示不下,同時視覺效果并沒有很好



半偏移網(wǎng)格布局,界面中并非所有的內(nèi)容都偏移底層網(wǎng)格,而是部分模塊這樣去做,原因是內(nèi)容多的情況下。





分屏布局

- 

分屏布局,顧名思義就是將屏幕進行幾種不同區(qū)域的劃分,然后內(nèi)容分布排版在里面,分屏布局解決的主要問題將屏幕大的設(shè)備進行合理劃分空間設(shè)計,一般是在橫屏運用比較多,比如PAD,或者WEB或者車機中控屏,下面一起看下分屏布局在實際設(shè)計中的具體表現(xiàn)



上圖界面設(shè)計采用了1/2分屏布局,將圖片與內(nèi)容文字進行區(qū)域劃分,下圖是將主文案擺放在分割區(qū)域中間(文字較少情況下可以這樣去做)增強形式感。當(dāng)然分屏布局可以有多重形式,列如,2/3,1/3,3/4等等,可以根據(jù)內(nèi)容進行選擇合適分屏





Z軸視差布局

-

視差布局,在web app或者web端布局常用比較多的一種,運行方式當(dāng)滑動頁面內(nèi)容時內(nèi)容與內(nèi)容之間運動速率會有時間差,同時Z軸空間位置也會有深度差異,這樣就形成了視差效果,視差布局一般在H5界面出現(xiàn)比較多,用于營銷場景會多一些,當(dāng)然WEB端倒是比較常見 


地址:https://www.stereo.ca/project/clinique-dentaire-gagnon/





內(nèi)容重疊布局

- 
內(nèi)容重疊布局,打破了傳統(tǒng)平整的極簡注意風(fēng)格,扁平化設(shè)計將會加入Z軸空間元素,使得整體設(shè)計有了新穎的布局方式,這也是一種區(qū)分競爭產(chǎn)品的布局方式,一般內(nèi)容重疊產(chǎn)品大多出現(xiàn)在偏雜志化設(shè)計的產(chǎn)品中,如之前我介紹圖形篇時候提到 韓國29cm
他們詳情頁,運營頁面運用了重疊布局。 



地址:https://www.stereo.ca/project/clinique-dentaire-gagnon/






卡片布局

- 
為什么要把卡片布局拿出來講?卡片布局應(yīng)該是我們見過最多的布局了,卡片布局也會有很多種方式去布局,根據(jù)產(chǎn)品內(nèi)容復(fù)雜程度去建立卡片容器大小,卡片作為承載內(nèi)容的容器,對于響應(yīng)式布局也是非常有利的支持,我們看appstore,behance的移動端,都是卡片布局。 



卡片布局還有一個最大好處就是,他能夠封裝內(nèi)容,使得畫面布局整潔,所有內(nèi)容都往容器里面放,信息之間保持很好的區(qū)分



全封閉卡片布局,內(nèi)容之間通過卡片封裝,中間無空隙





自由式網(wǎng)格布局

- 
這種網(wǎng)格布局相對來說比較開放性的,布局上多以卡片承載內(nèi)容為主,卡片跟隨隱形網(wǎng)格隨機分布在畫板中,有點類似我們說的暴瀑流布局方式,這種會比較靈活,一般會在攝影類,雜志類,文藝類產(chǎn)品居多。 







如何運用這些布局進行創(chuàng)新設(shè)計

-

上面已經(jīng)列舉了目前比較流行的一些布局,可能部分人還是感覺不會使用,也不會很好的去利用在自己設(shè)計中。要么就直接把別人布局抄襲過來,其實是有方法的,我們可以把自己認(rèn)為比較好的一種布局拿出來,然后拆解他,拆解完后,再來重新組裝,組裝的時候,你可以參考下其他布局,兩者集合起來,就像樂高積木一樣,你可以有很多種組合方式。 


上面利用樂高積木思維重新對布局進行拆解組合,當(dāng)然一切的布局都是基于當(dāng)前你的主旨,你的產(chǎn)品內(nèi)容,找到合適布局,然后去研究他,并且拆解,然后重新搭建屬于自己產(chǎn)品一套布局規(guī)則





總結(jié)

-

全文向大家介紹5種布局思路,當(dāng)然其實不止這5種,但是其他布局相對來說會運用少一些,這些布局我們可以加以學(xué)習(xí)利用,可以運用在任何設(shè)計中去,當(dāng)然運用的時候,一定要清晰知道自己產(chǎn)品的主旨目標(biāo),用戶群體,合理運用布局,做出創(chuàng)新設(shè)計!


轉(zhuǎn)自:站酷-設(shè)計TNT 

如何讓你的設(shè)計更有說服力?掌握這五個體驗設(shè)計原則··

ui設(shè)計分享達(dá)人

從數(shù)個項目中總結(jié)出的體驗設(shè)計原則,包括詳細(xì)的舉例說明

李笑來說過一句話:審美常常并不需要知道原理,但創(chuàng)造美的人必須有方法論,否則不可能持續(xù)創(chuàng)造。但是很多人總覺得背方法論是笨工夫,高手難道不應(yīng)該根據(jù)場上局面隨機應(yīng)變嗎?但事實是,隨機應(yīng)變才是笨辦法,方法論和成語典故、數(shù)學(xué)定理一樣,是人腦思維中的快捷方式,“聰明人”之所以能做到隨機應(yīng)變,是因為他們腦中存有足夠多方法論,當(dāng)遇到事情時,這些方法論像神經(jīng)一樣互相連接,給出最優(yōu)的解決方案。

 

今天就跟大家分享設(shè)計的方法論——設(shè)計原則,在方案輸出時,可以將設(shè)計原則作為方案的自檢工具,這樣在方案內(nèi)審時,面對領(lǐng)導(dǎo)和同事的質(zhì)疑,除了說“大廠都是這么做的”這樣蒼白無力的解釋外,還有更多的設(shè)計原則做支撐。

 

一、一致性

一致性的益處:對用戶來說,一致性可以降低學(xué)習(xí)成本,對開發(fā)團隊來說,可以減少錯誤,降低產(chǎn)品的維護成本,提高代碼和設(shè)計的復(fù)用率。對企業(yè)來說,一致性意味著產(chǎn)品的不同模塊要有相似的外觀、感覺和行為,這種特性會被擴展到企業(yè)其他產(chǎn)品中(比如Adobe旗下的產(chǎn)品都嚴(yán)格保持著相同的標(biāo)準(zhǔn)),有利于強化用戶對品牌的認(rèn)知,建立品牌忠誠度。

 

一致性的弊端:很多設(shè)計師容易被這一原則而禁錮,進而成為設(shè)計師偷懶的借口,設(shè)計師有時為了強調(diào)一致性而忽略了特定情境下的用戶行為和使用模式,所以在設(shè)計時不能只關(guān)注用戶的感覺和品牌認(rèn)知,要根據(jù)特定場景敢于創(chuàng)新。

 

一致性可以從以下幾個維度分析:

 

1、交互行為一致性,交互行為一致性又包括操作方式,控件,控件位置等。拿最近做的項目舉例,「轉(zhuǎn)到銀行卡」和「信用卡還款」雖兩個不同功能,但盡量使模塊內(nèi)控件,控件位置及操作方式保持統(tǒng)一。


2、視覺表現(xiàn)一致性,包括風(fēng)格,色彩,文字,圖標(biāo),圖片等。風(fēng)格和色彩的統(tǒng)一比較容易理解,這里詳細(xì)說一下圖標(biāo)和圖片如何保持統(tǒng)一。


圖標(biāo)的統(tǒng)一性:

1)一款產(chǎn)品在各個平臺上的圖標(biāo)要一致

2)多款產(chǎn)品在一個平臺上的圖標(biāo)之間的風(fēng)格或規(guī)范要一致

3)一款產(chǎn)品的每個圖標(biāo)的風(fēng)格、細(xì)節(jié)、體量感上要一致


如何做到每個圖標(biāo)風(fēng)格,細(xì)節(jié),體量感上的統(tǒng)一?

1)保持圖標(biāo)的復(fù)雜程度或簡約程度統(tǒng)一

2)不使用潦草、手繪的造型,幾何形更容易達(dá)到統(tǒng)一

3)保持圖標(biāo)的維度統(tǒng)一(二維/三維)

4)保持圖標(biāo)陰影、漸變等樣式統(tǒng)一或均無樣式

5)保持圖標(biāo)顏色或圖標(biāo)背景的顏色統(tǒng)一

6)保持圖標(biāo)的尺寸和比例統(tǒng)一(體量感)

7)保持圖標(biāo)線的粗細(xì)統(tǒng)一

8)保持圖標(biāo)圓角大小統(tǒng)一


如何做到圖片的一致性:

1)圖片的處理方式一致(尺寸比例,圓角,投影)

2)圖片的風(fēng)格一致,圖片風(fēng)格是否保持統(tǒng)一視產(chǎn)品屬性而定,像淘寶這樣的電商平臺想要保持圖片風(fēng)格的統(tǒng)一性簡直要了店家的命,但是圖片的處理方式可以做到統(tǒng)一,比如淘寶的商品圖大部分是灰色背景等。

 

3、文案的一致性,文案的人稱,風(fēng)格保持一致,網(wǎng)易云音樂的文案都是用的第二人稱,且具有很強的趣味性。

二、優(yōu)先級

優(yōu)先級可以從以下幾個維度分析:


1、功能優(yōu)先級:把握核心需求,突出亮點功能,拿最近做的項目舉例:轉(zhuǎn)賬主頁面功能優(yōu)先級最高的是「轉(zhuǎn)到銀行卡」「微轉(zhuǎn)賬」,所以在頁面布局、所占比重上強調(diào)這兩個功能,同時上滑時兩個按鈕變小凍結(jié)在頁面頂部,方便用戶快捷使用。


2、內(nèi)容優(yōu)先級:內(nèi)容分級,突出核心內(nèi)容。拿最近做的項目舉例:代金券詳情頁,根據(jù)用戶使用卡券的場景,以及數(shù)據(jù)分析得出的內(nèi)容優(yōu)先級對內(nèi)容進行布局與設(shè)計。將優(yōu)先級最高的代金券二維碼放在用戶視線觸達(dá)的位置,當(dāng)用戶上滑時,底部出現(xiàn)全局浮動的按鈕,可快速顯示二維碼。


再比如,轉(zhuǎn)賬后的狀態(tài)頁面,用戶最關(guān)心的內(nèi)容是轉(zhuǎn)賬后的狀態(tài)及轉(zhuǎn)賬金額,其次是收款方信息以及轉(zhuǎn)賬備注,將信息進行整理、歸類、隱藏、刪減,避免不重要信息對用戶獲取重要信息時的干擾。點擊箭頭可查看更詳細(xì)的轉(zhuǎn)賬信息,最后的頁面設(shè)計如下:


3、交互優(yōu)先級:主要路徑清晰,減少干擾和分支。如下轉(zhuǎn)賬流程中,根據(jù)用戶每一步驟的目的與使用場景進行信息呈現(xiàn),該出現(xiàn)的時候出現(xiàn),不該出現(xiàn)時隱藏,分步驟進行,使轉(zhuǎn)賬這一主路徑清晰明了,減少其他信息對用戶的干擾。


4、視覺優(yōu)先級:重要的視覺信息第一眼看到,主要次要信息有所區(qū)分。如微信錢包頁面,收付款和錢包的視覺優(yōu)先級明顯高于下方的騰訊服務(wù)。美團首頁上方雖都是功能按鈕,通過圖標(biāo)的體量、大小、位置拉開彼此層級,突出展示「掃一掃」「付款碼」「紅包/卡券」「騎單車」這些功能,很好的引導(dǎo)了用戶視線,完成產(chǎn)品目標(biāo)和用戶目標(biāo)。


三、易讀性

易讀性可以從以下幾個維度分析:


1、使用用戶語言而不是開發(fā)者語言,貼近生活實際而不是學(xué)術(shù)概念。圖1是改版前的頁面,頁面的核心目的是通過圖表、止鼾次數(shù)、分貝向用戶傳達(dá)止鼾器的止鼾效果,呈現(xiàn)方式不直觀,且用戶對分貝并沒有確切的概念,圖二將分貝巧妙的轉(zhuǎn)化成蜜蜂的聲音,增強了易讀性,在這里蜜蜂的聲音就是用戶語言,分貝即開發(fā)語言。


2、符合用戶認(rèn)知與心智,延續(xù)約定俗成概念。蘋果的首席設(shè)計師喬納森·艾弗說:“好的設(shè)計無需認(rèn)知門檻”,好的設(shè)計不需要任何指示用戶就知道如何操作。如下圖蘋果系統(tǒng)的亮度設(shè)置,向上滑動是提高亮度,向下滑動是降低亮度,而不是向下是提高,向上是降低。


再比如,根據(jù)我們的正常認(rèn)知,下一步應(yīng)該在右,上一步在左。


3、保持簡潔,不給用戶造成困擾與疑惑。還是拿之前做的項目舉例:微轉(zhuǎn)賬不同于普通的銀行卡轉(zhuǎn)賬,需要給用戶進行解釋說明,改版前的說明直接將大段的解釋文字展示給用戶,可讀性差,改版后將大段的解釋轉(zhuǎn)化成4個直觀的步驟,對用戶來說更容易理解。

四、容錯性

容錯性可以從以下幾個維度分析:


1、操作前可預(yù)知:有預(yù)防用戶出錯的措施,關(guān)鍵操作有確認(rèn)提示,及早消除誤操作。如圖1輸入轉(zhuǎn)賬金額時提前告知用戶銀行卡余額,避免余額不足讓用戶重復(fù)輸入;圖2提前告知用戶提取的金額是50的倍數(shù),避免用戶出錯。



分期還款時,提前告知用戶一個賬單周期只能申請一次分期,且在用戶二次確認(rèn)的彈出框再次提示。



2、操作中有反饋:給用戶明確的錯誤信息,并協(xié)助用戶方便從錯誤中恢復(fù)工作。如在分期金額輸入錯誤時及時告訴用戶出錯的原因。



3、操作后可撤消:允許用戶撤消錯誤操作,如mac系統(tǒng)垃圾箱中「放回原處」功能:



微信對話中的「撤回」功能,這些都體現(xiàn)了系統(tǒng)的容錯性。


五、可控性

可控性可以從以下幾個維度分析:


1、記憶及預(yù)測用戶行為,幫助用戶做些事情,減輕用戶記憶負(fù)擔(dān)。如mac系統(tǒng)的密碼管理可以幫助用戶記住常用的賬戶密碼:

郵件中,輸入收件人的姓,軟件能自動檢索出該姓下曾出現(xiàn)過的所有用戶的郵件地址。


2、對操作給予及時反饋,用戶能了解操作是否已生效,用戶在界面上的任何操作,不論是單擊、滾動還是按下鍵盤,或者操作狀態(tài)變化,界面應(yīng)及時給出反饋。


3、將操作狀態(tài)或進度顯示出來,用戶能了解當(dāng)前系統(tǒng)狀況,如讓用戶實時了解貨物的物流信息,會減輕用戶等待的煩躁感,同時增加可控感。


4、用戶清楚知道自己當(dāng)前在哪里,退路在哪里,可以去哪里,如分頁控件就能明確的告訴用戶自己在哪,退路在哪,還能去哪。




5、提供適時幫助、必要的信息提示,如最常見的功能引導(dǎo)



回顧:


一、一致性

1、交互行為一致性:操作,控件,位置。

2、視覺表現(xiàn)一致性:風(fēng)格,色彩,文字,圖標(biāo),圖片。

3、文案措辭一致性:提示語,功能按鈕等。


二、優(yōu)先級

1、功能優(yōu)先級:把握核心需求,突出亮點功能。

2、內(nèi)容優(yōu)先級:內(nèi)容分級,突出核心內(nèi)容。

3、交互優(yōu)先級:主要路徑清晰,減少干擾和分支。

4、視覺優(yōu)先級:重要的視覺信息第一眼看到,主要次要信息有所區(qū)分。

 

三、易讀性

1、使用用戶語言而不是開發(fā)者語言,貼近生活實際而不是學(xué)術(shù)概念

2、符合用戶認(rèn)知與心智,延續(xù)約定俗成概念。

3、保持簡潔,不給用戶造成困擾與疑惑。

 

四、容錯性

1、操作前可預(yù)知:有預(yù)防用戶出錯的措施,關(guān)鍵操作有確認(rèn)提示,及早消除誤操作。

2、操作有反饋:給用戶明確的錯誤信息,并協(xié)助用戶方便從錯誤中恢復(fù)工作。

3、操作后可撤銷:允許用戶撤銷錯誤操作。



五、可控性

1、記憶及預(yù)測用戶行為,幫助用戶做些事情,減輕用戶記憶負(fù)擔(dān)。

2、對操作給予及時反饋,用戶能了解操作是否生效。

3、將操作狀態(tài)或進度顯示出來,用戶能了解當(dāng)前系統(tǒng)狀況。

4、用戶清楚知道自己當(dāng)前在哪里,退路在哪里,可以去哪里。

5、提供適時幫助、必要的信息提示。


-希望此文對你有一點幫助


轉(zhuǎn)自:站酷-poppy



干貨|尼爾森十大可用性原則案例解析

ui設(shè)計分享達(dá)人

尼爾森的十大可用性原則,它們被稱為「啟發(fā)式」,<br>被奉為交互設(shè)計師的入門法則。

開篇靈魂拷問:


你認(rèn)為一個怎樣的產(chǎn)品才算是一個好的產(chǎn)品?

這個問題耳熟嗎?面試的時候是不是有被問到過?
我們經(jīng)常使用的那些產(chǎn)品,哪些是好的產(chǎn)品呢?

當(dāng)我們談?wù)撘粋€ APP 產(chǎn)品時,
作為用戶你最關(guān)心的是什么?
一般都是是這個產(chǎn)品好用嗎?功能復(fù)雜嗎?
而不是這個產(chǎn)品用戶界面顏色好看嗎?
交互的動效酷炫嗎?

互聯(lián)網(wǎng)已經(jīng)深入到每個人的生活當(dāng)中,
時刻影響著我們;
一個好的產(chǎn)品會給我們帶來便捷,
使我們的生活變得簡單而又美好;
也會有一些產(chǎn)品使用時會感到不舒服,
糟糕的產(chǎn)品體驗會讓我們的生活變得復(fù)雜而又煩惱。
所以,決定一個產(chǎn)品好不好用,
能不能長期使用都是用戶體驗直接決定的。
用戶體驗關(guān)注的是在滿足用戶需求的同時帶給用戶美好的感受。

接下來我們來聊一聊「尼爾森十大原則」,
這十大原則是具體而又全面的用戶體驗可行性檢驗方法。

    
尼爾森是誰?
雅各布·尼爾森(Jakob Nielsen)是畢業(yè)于哥本哈根的丹麥技術(shù)大學(xué)的人機交互博士,他擁有79項美國專利,專利主要涉及讓互聯(lián)網(wǎng)更容易使用的方法。于1995年1月1日發(fā)表了「十大可用性原則」。1995年以來,他通過自己的 Alertbox 郵件列表以及 useit.com 網(wǎng)站,向成千上萬的 Web 設(shè)計師傳授 Web 易用性方面的知識,盡管他的一些觀點可能帶來爭議,至少在 Web 設(shè)計師眼中,他是 Web 易用性領(lǐng)域的頂尖領(lǐng)袖。2006年4月,并被納入美國計算機學(xué)會人機交互學(xué)院,被賦予人機交互實踐的終身成就獎。他還被紐約時報稱為“Web 易用性大師”,被 Internet Magazine 稱為 “易用之王”。
        
尼爾森的十大可用性原則,它們被稱為「啟發(fā)式」,      
    
    
是廣泛的經(jīng)驗法則,而不是特定的可用性指導(dǎo)原則。
雖然是1995年提出來的,
但是至今仍然被奉為交互設(shè)計師的入門法則,
我們不能把它上升為一種標(biāo)準(zhǔn),
而只當(dāng)做一種經(jīng)驗來學(xué)習(xí),
然后跟現(xiàn)實中的設(shè)計結(jié)合來使用。
因為尼老師是從 web 設(shè)計提出的十大可用性原則,
我們要結(jié)合的是目前移動互聯(lián)網(wǎng)的特點,

然后在「尼爾森十大原則」的結(jié)構(gòu)下探討在用戶體驗上達(dá)到的目標(biāo)。


尼爾森十大可?用性原則為:

01. 狀態(tài)可見原則 

02. 環(huán)境貼切原則 

03. 撤銷重做原則

04. 一致性原則 

05. 防錯原則

06. 易取原則 

07. 靈活原則 

08. 易掃原則 

09. 容錯原則 

10. 人性化幫助原則


下面我們就針對每一條來單獨分析一下吧~


 ·.  狀態(tài)可見原則 
系統(tǒng)應(yīng)該讓用戶知道發(fā)生了什么,
在適當(dāng)?shù)臅r間內(nèi)做出適當(dāng)?shù)姆答仭?/span>
不要蒙蔽用戶;
溝通是所有關(guān)系的基礎(chǔ),無論?還是設(shè)備。

示例:在淘寶里,我下拉時他告訴我「松開刷新」,也就是現(xiàn)在還沒有開始刷新;我松開后狀態(tài)變更成「刷新中」,表示現(xiàn)在正在刷新。
這樣的設(shè)計告訴我們,界面現(xiàn)在是什么狀態(tài),現(xiàn)在在干嘛,在整個功能的變化過程中我們都能看到對應(yīng)的文字描述。


其他示例:下拉刷新時的加載中,加載完成提示,收藏成功、支付成功、實付失敗等提示。


·. 環(huán)境貼切原則

功能和服務(wù)貼近用戶使用的場景,

符合當(dāng)前場景用戶的體驗。

產(chǎn)品的功能和服務(wù)應(yīng)該貼近真實世界,

讓信息更自然,邏輯上也更容易被用戶理解。


示例:我們在店里買東西的時候經(jīng)常會聽到這樣的聲音「支付寶導(dǎo)致:5元」就是貼近環(huán)境的設(shè)計。
商家需要確認(rèn)你是否付錢,
但是又經(jīng)常忙于手頭的事情無法及時查看;
而這樣功能的設(shè)計,商家即使在忙著手頭的事情依然能通過聲音來確認(rèn)已經(jīng)收到你的錢了。
這樣的設(shè)計對于商家和消費者是友好便捷的。


 ·.  撤銷重做原則 

在使用產(chǎn)品時了解和掌控當(dāng)前頁面。

如果用戶誤操作,可以隨時撤銷,用戶在使用產(chǎn)品時足夠自由。


示例1:我們用微信和對方聊天時,當(dāng)我們寫了很多字,發(fā)出去時卻發(fā)現(xiàn)其中有錯誤,這時我們可以使用微信的撤回功能,體驗更好的是,撤回消息旁邊有「重新編輯」功能,可以讓之前編輯的文本回到對話框重新編輯再發(fā)送。如下圖:


示例2:iOS系統(tǒng)照片的刪除和撤回


·. 一致性原則

同樣的文字、狀態(tài)、按鈕,都應(yīng)該觸發(fā)相同的事情,遵從通用的平臺慣例。也就是,同一用語、功能、操作保持一致。主要包括以下五個方面:


1. 結(jié)構(gòu)一致性

保持一種類似的結(jié)構(gòu),新的結(jié)構(gòu)變化會讓用戶思考,規(guī)則的排序能減輕用戶的思考負(fù)擔(dān)。

示例:微信中每個模塊的條目都有統(tǒng)一的「圖標(biāo)+文字信息」的結(jié)構(gòu)樣式,能讓用戶快速了解每一個模塊;


2. 色彩一致性

產(chǎn)品所使用的主要色調(diào)應(yīng)該是統(tǒng)一的,而不是換一個頁面,顏色就不同。

示例:淘寶的圖標(biāo)顏色與界面的主色均為橙色,也包括其中一些標(biāo)簽和強調(diào)的文字顏色都是橙色色。整個界面除了圖片的有效信息外,都通過灰、白、橙色色來呈現(xiàn),界面保持了很好的一致性;


3. 操作一致性

能在產(chǎn)品更新?lián)Q代時仍然讓用戶保持對原產(chǎn)品的認(rèn)知,減小用戶的學(xué)習(xí)成本。

示例:微信在對話框和通訊錄都采用了左滑出操作的交互,如下圖:


4. 反饋一致性

用戶在操作按鈕或者條目的時候,點擊的反饋效果應(yīng)該是一致的。

示例:QQ的每個分組點擊后都是向下展開組內(nèi)成員列表;


5. 文字一致性
產(chǎn)品中呈現(xiàn)給用戶閱讀的文字大小、樣式、顏色、布局等都應(yīng)該是一致的。
示例:例如微信幾個關(guān)鍵界面的字體:三個主界面內(nèi)容結(jié)構(gòu)不盡相同,但是,列表的標(biāo)題字體和間距都一樣,這樣讓整個APP視覺上看起來很舒服;


 ·.  防錯原則
比出現(xiàn)錯誤信息提示更更好的是,用設(shè)計防?止這類問題發(fā)生。在用戶選擇動作發(fā)?生之前, 就要防止用戶容易混淆或者錯誤的選擇。

1. 限制操作范圍與條件;
示例:未輸入驗證碼前,底部的登錄按鈕是置灰不可點擊的,只有填寫完整,底部的登錄按鈕才會變?yōu)榭牲c擊狀態(tài)。這就是為了防止用戶犯更多錯誤;


2. 對有風(fēng)險的操作進?二次確認(rèn);
示例:刪除個好友時,通過二次彈窗給出防錯措施。

·. 易取原則

減少用戶記憶負(fù)荷,在適合的時機給用戶需要獲取的信息。
1. 為用戶提供歷史記錄、關(guān)注、收藏等功能;
示例:愛奇藝為用戶提供了看過記錄和我的收藏,幫助用戶記憶:



2. 選擇而不是輸入,盡量降低輸入成本;

示例1:打車軟件自動獲取當(dāng)前位置;

示例2:iOS系統(tǒng)收到驗證碼后自動帶入到鍵盤,點擊直接輸入;


·. 靈活原則

對于新用戶來說,需要功能明確、清晰,對于老用戶需要快捷使用高頻功能。不可為了某一種用戶,把不必要的信息占據(jù)重要部分。主要體現(xiàn)在3個方面:

1. 自定義功能或模塊的展示位置;

示例:支付寶首頁的應(yīng)用是可以根據(jù)自身喜好自定義的,包括定義常用應(yīng)用、排序、刪除、新增等等。這樣用戶可以根據(jù)自己的個人興趣定制自己適合的應(yīng)用分布方式,這就叫做用戶定制常用功能,如下圖:


2. 將“常用”自動歸納以提升使用效率;

示例:微信聊天界面表情彈窗中會有一個「最近使用」的模塊,它把個人平時使用頻率或者次數(shù)最多的表情進行歸類。當(dāng)用戶使用的時候,能很快的找到自己喜歡或者常用的表情,提高了聊天效率;包括餓了么的「我的訂單」里的每一個訂單都可以通過再來一單重新一鍵下單,如下圖:


3. 縮短操作路路徑,提升使?用效率與體驗;

示例:微信的對話框,當(dāng)點擊「+」調(diào)出下面的操作選項時,會默認(rèn)彈出剛截圖或拍照的照片,方便用戶直接調(diào)取,還有APP長按后出來的快捷操作列表,如下圖:


·. 易掃原則

直譯:美學(xué)和簡約的設(shè)計;頁面不應(yīng)包含不相關(guān)或很少需要的信息,頁面中的每個額外信息都會降低主要內(nèi)容的相對可見性。

示例:如下圖列表中出現(xiàn)的信息都是用戶比較關(guān)注的信息,比如配送費,配送時間,距離等;攜程的選擇機票界面講最重要的時間和機票價格放大突出,讓用戶能一眼看到,如圖:


 9 ·. 容錯原則

直譯:幫助用戶識別、診斷和從錯誤中恢復(fù);我們盡量避免用戶出現(xiàn)錯誤,但當(dāng)出現(xiàn)錯誤時,我們應(yīng)該盡量去安撫用戶的挫敗感。

?配圖+文字代替「404」,明確告訴用戶哪?錯了和解決方案。

示例:界面加載失敗時的刷新提示,還有登錄時的手機號碼校驗,如果手機格式錯誤會出現(xiàn)會提示用戶手機格式不正確和正確的格式。


 10 ·. 人性化幫助

幫助性提示最好的方法是:

1.無需提示:非常簡單易懂,用戶看界面就知道怎么操作,無需提示;

2.一次性提示:只需要一次提示用戶就懂如何使用;

示例:常見的新功能引導(dǎo)、引導(dǎo)?等,示例:


3.常駐提示: 較重要的提示,用于指導(dǎo)或幫助用戶;

示例:支付寶轉(zhuǎn)賬時,常駐在頂部的安全確認(rèn)提示,還有轉(zhuǎn)賬時的服務(wù)費提示,如圖:


4.幫助文檔:稍微復(fù)雜一點的軟件,雖然要讓他盡量簡單但幫助文檔都是必要的;

示例:微信設(shè)置界面里的「幫助與反饋」,還有支付寶轉(zhuǎn)賬時彈出來的「求助反饋」,點進去后的常見問題界面;


以上就是我對Jakob Nielsen(雅各布·尼爾森)的十大交互設(shè)計原則的理解和實例解讀,希望對大家有所幫助。如果大家同樣對這些方面有些興趣或者看了后有些什么想法,歡迎一起討論。

轉(zhuǎn)自:站酷-搞設(shè)計的月野兔



Vue源碼剖析(三)patch和Diff算法

seo達(dá)人

Patch和Diff算法

網(wǎng)上看了好多的博客和源碼教程,感覺很多仔細(xì)的地方?jīng)]有說清,而且在一些復(fù)雜的部分加了好多的描述,所以就想自己也寫下心得, 方便自己, 方便他人,有興趣的同學(xué)可以關(guān)注我的github里面有我之前一些博文 github/193Eric



我們知道的,在數(shù)據(jù)更改后,會觸發(fā)getter,然后通過dep.notify()來通知watcher觸發(fā)update進而更新視圖,最終是通過Diff算法來對比新老Vnode的差異,并把差異更新到Dom視圖上



Diff

我們知道的,Virtual DOM是一顆樹,而diff算法主要把兩顆樹進行對比,找出之間的差異,來渲染頁面



diff 算法是通過同層的樹節(jié)點進行比較而非對樹進行逐層搜索遍歷的方式,所以時間復(fù)雜度只有 O(n),是一種相當(dāng)?shù)乃惴?br />


1.調(diào)用patch函數(shù)比較Vnode和OldVnode,如果不一樣直接return Vnode即將Vnode真實化后替換掉DOM中的節(jié)點



2.如果OldVnode和Vnode值得進一步比較則調(diào)用patchVnode方法進行進一步比較,分為以下幾種情況:



Vnode有子節(jié)點,但是OldVnode沒有,則將Vnode的子節(jié)點真實化后添加到真實DOM上



Vnode沒有子節(jié)點,但是OldVnode上有,則將真實DOM上相應(yīng)位置的節(jié)點刪除掉



Vnode和OldVnode都有文本節(jié)點但是內(nèi)容不一樣,則將真實DOM上的文本節(jié)點替換為Vnode上的文本節(jié)點



Vnode和OldVnode上都有子節(jié)點,需要調(diào)用updateChildren函數(shù)進一步比較



updateChildren比較規(guī)則



提取出Vnode和OldVnode中的子節(jié)點分別為vCh和OldCh,并且提出各自的起始和結(jié)尾變量標(biāo)記為 oldS oldE newS newE



如果是oldS和newE匹配上了,那么真實dom中的第一個節(jié)點會移到最后



如果是oldE和newS匹配上了,那么真實dom中的最后一個節(jié)點會移到最前,匹配上的兩個指針向中間移動



如果都沒有,在沒有key的情況下直接在DOM的oldS位置的前面添加newS,同時newS+1。在有key的情況下會將newS和Oldch上的所有節(jié)點對比,如果有相同的則移動DOM并且將舊節(jié)點中這個位置置為null且newS+1。如果還沒有則直接在DOM的oldS位置的前面添加newS且newS+1

直到出現(xiàn)任意一方的start>end,則有一方遍歷結(jié)束,整個比較也結(jié)束



updateChildren例子:



假設(shè):



真實dom為 A、B、C

oldDom為 A1、B1、C1

newDom為 A2、D2、C2、B2



先確定oldS = A1 ; oldE = C1; newS = A2; newE = B2



先對比oldS和newS,oldE和newE,發(fā)現(xiàn)oldS = newS 所以真實dom的A固定不動。排序為 A、B、C

然后oldS = B1 ; oldE = C1; newS = D2; newE = B2



對比發(fā)現(xiàn) oldS = newE , 所以真實dom,B要插入到后面去



真實dom排序為:A、C、B



然后oldS = C1; oldE = C1; newS = D2; newE = B2



對比發(fā)現(xiàn)兩兩都不對等,所以走第三步。

假設(shè)有key存在,所以newS直接和oldDom里面的所有節(jié)點對比,發(fā)現(xiàn)沒有存在,然后插入到oldS前面,且newS+1

真實dom排序為:A、D、C、B

然后重新開始,oldS++ > oldE-- ,結(jié)束了。



這就是updateChildren,之后就是一直遍歷,運行updateChildren直到?jīng)]有


一文秒懂 ajax, fetch, axios

seo達(dá)人

1, JavaScript的Ajax

Ajax的全稱是Asynchronous JavaScript and XML,意思就是用JavaScript執(zhí)行異步網(wǎng)絡(luò)請求,而不需要重載(刷新)整個頁面。

Ajax使用XMLHttpRequest對象取得新數(shù)據(jù),然后再通過 DOM 將新數(shù)據(jù)插入到頁面中。另外,雖然名字中包含 XML 的成分,但 Ajax 通信與數(shù)據(jù)格式無關(guān); 這種技術(shù)就是無須刷新頁面即可從服務(wù)器取得數(shù)據(jù),但不一定是 XML 數(shù)據(jù)。

對于IE7+和其他瀏覽器,可以直接使用XMLHttpRequest對象,對于IE6及以前的瀏覽器,使用ActiveXObject對象。



使用方法如下:



var xhr;

if (window.XMLHttpRequest) {

    xhr = new XMLHttpRequest();

} else {

    xhr = new ActiveXObject('Microsoft.XMLHTTP');

}

1

2

3

4

5

6

啟動請求:



xhr.open(method, url, boolean);     

xhr.send();

1

2

注:

1,xhr.open參數(shù)含義:

method:請求方式,post、get等

url: 請求鏈接,只能向同源的url發(fā)送請求

boolean:是否異步請求,true:異步, false: 同步,默認(rèn)為true

2,調(diào)用 open()方法并不會真正發(fā)送請求, 而只是啟動一個請求以備發(fā)送。

3,send()方法接收一個參數(shù),即要作為請求主體發(fā)送的數(shù)據(jù)(post方法會使用,get方法直接傳null)。如果不需要通過請求主體發(fā)送數(shù)據(jù),則必須傳入 null,因為這個參數(shù)對有些瀏覽器來說是必需的。調(diào)用send()之后,請求就會被分派到服務(wù)器。



XMLHttpRequest對象的異步請求示例如下:



function success(text) {

    console.log(text);

}



function fail(code) {

   console.log(code);

}



var xhr = new XMLHttpRequest();     // 新建XMLHttpRequest對象

xhr.onreadystatechange = function () { 

    // 狀態(tài)發(fā)生變化時,函數(shù)被回調(diào)

    if (xhr.readyState === 4) { // 成功完成

        // 判斷響應(yīng)結(jié)果:

        if (xhr.status === 200) {

            // 成功,通過responseText拿到響應(yīng)的文本:

            return success(xhr.responseText);

        } else {

            // 失敗,根據(jù)響應(yīng)碼判斷失敗原因:

            return fail(xhr.status);

        }

    } else {

        // HTTP請求還在繼續(xù)...

    }

}



// 發(fā)送請求:

xhr.open('get', '/api/categories');

xhr.send(null);

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

xhr的屬性含義如下:

responseText: 作為響應(yīng)主體被返回的文本。

responseXML: 如果響應(yīng)的內(nèi)容類型是"text/xml"或"application/xml",這個屬性中將保存響應(yīng)數(shù)據(jù)的 XML DOM 文檔。

status: 響應(yīng)的 HTTP 狀態(tài)。

statusText: HTTP 狀態(tài)的說明。

readyState :表示請求/響應(yīng)過程的當(dāng)前活動階段??扇≈等缦隆?br />
0: 未初始化。尚未調(diào)用 open()方法。

1: 啟動。已經(jīng)調(diào)用 open()方法,但尚未調(diào)用 send()方法。

2: 發(fā)送。已經(jīng)調(diào)用 send()方法,但尚未接收到響應(yīng)。

3: 接收。已經(jīng)接收到部分響應(yīng)數(shù)據(jù)。

4: 完成。已經(jīng)接收到全部響應(yīng)數(shù)據(jù),而且已經(jīng)可以在客戶端使用了。

只要 readyState 屬性的值由一個值變成另一個值,都會觸發(fā)一次 readystatechange 事件。可以利用這個事件來檢測每次狀態(tài)變化后readyState 的值。通常,我們只對 readyState 值為 4 的階段感興趣,因為這時所有數(shù)據(jù)都已經(jīng)就緒。不過,必須在調(diào)用 open()之前指定 onreadystatechange事件處理程序才能確??鐬g覽器兼容性。



另外,在接收到響應(yīng)之前還可以調(diào)用 abort()方法來取消異步請求:



xhr.abort();

1

調(diào)用這個方法后,XHR 對象會停止觸發(fā)事件,而且也不再允許訪問任何與響應(yīng)有關(guān)的對象屬性。在終止請求之后,還應(yīng)該對 XHR 對象進行解引用操作。由于內(nèi)存原因,不建議重用 XHR 對象。



2, jQuery的Ajax

$.ajax({

        url:"",

        type:"GET",

        contentType: '',

        async:true,

        data:{},

        dataType:"",

        success: function(){

        }

});

1

2

3

4

5

6

7

8

9

10

url 必填項,規(guī)定把請求發(fā)送到哪個 URL。

type 以什么樣的方式獲取數(shù)據(jù),是get或post

contentType:發(fā)送POST請求的格式,默認(rèn)值為’application/x-www-form-urlencoded;

charset=UTF-8’,也可以指定為text/plain、application/json

async 是否異步執(zhí)行AJAX請求,默認(rèn)為true,千萬不要指定為false

data 發(fā)送的數(shù)據(jù),可以是字符串、數(shù)組或object。如果是GET請求,data將被轉(zhuǎn)換成query附加到URL上,如果是POST請求,根據(jù)contentType把data序列化成合適的格式;

dataType

接收的數(shù)據(jù)格式,可以指定為’html’、‘xml’、‘json’、'text’等,缺省情況下根據(jù)響應(yīng)的Content-Type猜測。

success 可選。執(zhí)行成功時返回的數(shù)據(jù)。

缺點:

是基于XHR原生開發(fā)的,目前已有的fetch可替代。本身是針對mvc的編程模式,不太適合目前mvvm的編程模式。jQuery本身比較大,如果單純的使用ajax可以自己封裝一個,不然會影響性能體驗。



3,Axios

Vue2.0之后,axios開始受到更多的歡迎。其實axios也是對原生XHR的一種封裝,不過是Promise實現(xiàn)版本。它是一個用于瀏覽器和 nodejs 的 HTTP 客戶端,符合的ES規(guī)范。



axios具有以下特征:



從瀏覽器中創(chuàng)建 XMLHttpRequest

支持 Promise API

客戶端支持防止CSRF

提供了一些并發(fā)請求的接口

從 node.js 創(chuàng)建 http 請求

攔截請求和響應(yīng)

轉(zhuǎn)換請求和響應(yīng)數(shù)據(jù)

取消請求

自動轉(zhuǎn)換JSON數(shù)據(jù)

PS:防止CSRF:就是讓你的每個請求都帶一個從cookie中拿到的key, 根據(jù)瀏覽器同源策略,假冒的網(wǎng)站是拿不到你cookie中得key的,這樣,后臺就可以輕松辨別出這個請求是否是用戶在假冒網(wǎng)站上的誤導(dǎo)輸入,從而采取正確的策略。



設(shè)置全局的 axios 默認(rèn)值



axios.defaults.baseURL = '
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

1

2

3

注:axios 的 headers的 content-type 默認(rèn)是 “application/json ”



默認(rèn)情況下,axios將JavaScript對象序列化為JSON,如果是get請求,對請求參數(shù)不用做任何處理,但是如果是post請求,并且Content-Type 為application/x-www-form-urlencoded,需要使用URLSearchParams API格式化請求參數(shù), 否則Content-Type依然是application/json



var params = new URLSearchParams();

params.append('param1', 'value1');

params.append('param2', 'value2');

1

2

3

get請求,以下3中寫法完全等價



axios.get('/user?id=12345&name=xiaoming')

.then(function (response) {

    console.log(response);

})

.catch(function (error) {

    console.log(error);

});

1

2

3

4

5

6

7

axios.get('/user', {

    params: {

      id: '12345',

      name: 'xiaoming'

    }

})

.then(function (response) {

    console.log(response);

})

.catch(function (error) {

    console.log(error);

});

1

2

3

4

5

6

7

8

9

10

11

12

axios({

    url: '/user',

    method: 'get',

    params: {

      id: '12345',

      name: 'xiaoming'

    }

})

.then(function (response) {

    console.log(response);

})

.catch(function (error) {

    console.log(error);

});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

post請求,以下2種寫法完全等價



axios({

    url: '/user',

    method: 'post',

    headers: {

        'Content-Type': 'application/json'

    },

    data: {

      id: '12345',

      name: 'xiaoming'

    }

})

.then(function (response) {

    console.log(response);

})

.catch(function (error) {

    console.log(error);

});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

var url = '/user';

var data = {

      id: '12345',

      name: 'xiaoming'

    };

axios.post(url, data, {

       headers: {

        'Content-Type': 'application/json'

    }

})

.then(function (response) {

    console.log(response);

})

.catch(function (error) {

    console.log(error);

});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

執(zhí)行多個并發(fā)請求



function getUserAccount() {

  return axios.get('/user/12345');

}

 

function getUserPermissions() {

  return axios.get('/user/12345/permissions');

}

 

axios.all([getUserAccount(), getUserPermissions()])

  .then(axios.spread(function (acct, perms) {

    // 兩個請求現(xiàn)在都執(zhí)行完成

}));

1

2

3

4

5

6

7

8

9

10

11

12

創(chuàng)建實例



可以使用自定義配置新建一個 axios 實例



axios.create([config])

var instance = axios.create({

  baseURL: '

  timeout: 1000,

  headers: {'X-Custom-Header': 'foobar'}

});

1

2

3

4

5

6

配置會以一個優(yōu)先順序進行合并,順序由低到高為

1,在 node_modules/axios/lib/defaults.js 找到的庫的默認(rèn)值

2,實例的 defaults 屬性

3,請求的 config 參數(shù)



// 使用由庫提供的配置的默認(rèn)值來創(chuàng)建實例

// 此時超時配置的默認(rèn)值是 0

var instance = axios.create();

 

// 覆寫庫的超時默認(rèn)值

// 現(xiàn)在,所有請求都會等待 2.5 秒

instance.defaults.timeout = 2500;

 

// 為已知需要花費很長時間的請求覆寫超時設(shè)置

instance.get('/longRequest', {

  timeout: 5000

});

1

2

3

4

5

6

7

8

9

10

11

12

攔截器



在請求發(fā)出之前或響應(yīng)被 then 或 catch 處理前攔截它們做預(yù)處理。



// 添加請求攔截器

axios.interceptors.request.use(function (config) {

    // 在發(fā)送請求之前做些什么

  }, function (error) {

    // 對請求錯誤做些什么

  });

 

// 添加響應(yīng)攔截器

axios.interceptors.response.use(function (response) {

    // 對響應(yīng)數(shù)據(jù)做點什么

  }, function (error) {

    // 對響應(yīng)錯誤做點什么

  });

1

2

3

4

5

6

7

8

9

10

11

12

13

可以在稍后移除攔截器:



var myInterceptor = axios.interceptors.request.use(function () {/.../});

axios.interceptors.request.eject(myInterceptor);

1

2

可以為自定義 axios 實例添加攔截器



var instance = axios.create();

instance.interceptors.request.use(function () {/.../});

1

2

4, fetch

window 自帶了 window.fetch 方法, 在版的 Firefox 和 Chrome 中已經(jīng)提供支持,其他瀏覽器還有兼容性問題,要做兼容性處理。fetch 是一個 基于promise設(shè)計的low-level API,不是ajax的進一步封裝,而是原生js,它注定不會像你習(xí)慣的 $.ajax 或是 axios 等庫幫你封裝各種各樣的功能或?qū)崿F(xiàn).



interface GlobalFetch {

    fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

}

1

2

3

fetch()是一個全局的函數(shù),返回一個promise對象。它有兩個參數(shù),第一個參數(shù)是請求的地址,第二個參數(shù)是可選,RequestInit是個對象格式如下:



interface RequestInit {

    body?: any;

    cache?: RequestCache;

    credentials?: RequestCredentials;

    headers?: HeadersInit;

    integrity?: string;

    keepalive?: boolean;

    method?: string;

    mode?: RequestMode;

    redirect?: RequestRedirect;

    referrer?: string;

    referrerPolicy?: ReferrerPolicy;

    window?: any;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

優(yōu)點:

符合關(guān)注分離,沒有將輸入、輸出和用事件來跟蹤的狀態(tài)混雜在一個對象里

更好更方便的寫法

更加底層,提供的API豐富

脫離了XHR,是ES規(guī)范里新的實現(xiàn)方式

fetch中可以設(shè)置mode為"no-cors"(不跨域)



缺點:

fetch不支持同步請求

fetch只對網(wǎng)絡(luò)請求報錯,對400,500都當(dāng)做成功的請求,需要封裝去處理

fetch默認(rèn)不會帶cookie,需要添加配置項

fetch不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實現(xiàn)的超時控制并不能阻止請求過程繼續(xù)在后臺運行,造成了流量的浪費

fetch沒有辦法原生監(jiān)測請求的進度,而XHR可以



fetch的使用示例:



window.fetch(url)

    .then(response => {

        if (response.ok) {

            //通過 response 原型上的 json 方法將 response.body 轉(zhuǎn)換為 JS 對象,再返回出去

            return response.json();

        }

    }

).then(result => {

    console.log(result);

}).catch(error => {

    console.log(error);

})

1

2

3

4

5

6

7

8

9

10

11

12

需要注意以下幾點:

1,用 response.ok判斷fetch請求是否成功

2,服務(wù)端只返回了response對象,而真正的請求結(jié)果,即 response.body,則是一個 ReadableStream。fetch 將 response.body 設(shè)計成 ReadableStream 在請求大體積文件時變得非常有用。然而,在我們的日常使用中,還是短小的 JSON 片段更加常見。而為了兼容不常見的設(shè)計,我們不得不多一次 response.json() 的調(diào)用。不僅是調(diào)用變得麻煩,如果你的服務(wù)端采用了嚴(yán)格的 REST 風(fēng)格,對于某些特殊情況并沒有返回 JSON 字符串,而是用了 HTTP 狀態(tài)碼(如:204 No Content),那么在調(diào)用 response.json() 時則會拋出異常。

3,Response 限制了響應(yīng)內(nèi)容的重復(fù)讀取和轉(zhuǎn)換,response .json / response.text 方法只能使用一個并且只能使用一次,同時使用兩個,或使用兩次都會報如下錯誤:



Uncaught (in promise) TypeError: Failed to execute 'json' on 'Response': body stream is locked

1

為什么不能使用兩次?

因為數(shù)據(jù)流只能讀取一次,一旦讀取,數(shù)據(jù)流變空,再次讀取會報錯。

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

版權(quán)聲明:本文為CSDN博主「Sherry慈」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:
https://blog.csdn.net/weixin_41480546/article/details/102805864

重磅發(fā)布!天貓雙十一品牌設(shè)計背后的故事

資深UI設(shè)計者

一年一度,天貓雙十一全球狂歡節(jié),如約而至!

從2015年開始,我們每年都會在雙十一期間,將雙十一品牌設(shè)計的完整思路分享給大家,這已經(jīng)成為雙十一設(shè)計團隊的傳統(tǒng)。不為別的,各位同仁辛苦一年,想跟大家就著新鮮出爐的設(shè)計嘮嘮嗑。

每逢雙十一logo出街,都會有熱心的朋友幫我們解讀,也有人問我們?yōu)樯恫桓銈€官方發(fā)布?各位朋友,您現(xiàn)在看到的就是官方發(fā)布的內(nèi)容,它不只有l(wèi)ogo,而是從頭到尾一個完整的故事。

△ 2019天貓雙十一主logo

△ 2019天貓雙十一主logo多語言版本

今年是雙十一的第十一年,當(dāng)我們接到這個任務(wù)的時候,就有機靈的同學(xué)提議:「我們用6個1吧,111111,61兒童節(jié)!」、「讓我們回歸購物的純真快樂!」。

「哈哈哈哈哈哈…」魔性的笑聲在整個會議室回蕩,看來往年撓破頭也解不開的難題,就這么解開了?故事當(dāng)然不會這么簡單,我們還沒有往這個方向嘗試就被否了。

  • 其一,雙十一是一個深入人心的認(rèn)知,這四個一已經(jīng)成為了超級符號,是我們寶貴的品牌資產(chǎn),而六個一不但不能幫我們強化認(rèn)知價值,反而會增加認(rèn)知成本。
  • 其二,六個一是一個純視覺的創(chuàng)意,他很難支撐起我們要傳達(dá)的消費者價值,也很難建立起情感連接。

我們應(yīng)該從哪兒入手?

回歸到設(shè)計的本質(zhì)來思考,我們認(rèn)為,設(shè)計的本質(zhì)是將一個想法或者觀點巧妙的表達(dá)給目標(biāo)對象,表達(dá)的過程中,形式只是手段,重點在于我們要表達(dá)什么。

我們集合了阿里各事業(yè)部的設(shè)計師代表,讓大家回歸到一個普通消費者的狀態(tài),一起聊一聊各自的雙十一故事,把這些故事提煉出來,就是消費者對于雙十一普遍真實的認(rèn)知。在全年最便宜的一天,無論湊熱鬧也好,跟風(fēng)也好,貪便宜也好,好像不買點什么總感覺錯過了什么。在這一天,「購物」毫無疑問成為頭等重要的事情。

△ 阿里巴巴經(jīng)濟體設(shè)計師共創(chuàng)

那么我們要對消費者表達(dá)「購物」嗎,講我們多么便宜,貨品多么豐富,多么物美價廉?這些是消費者早就形成的認(rèn)知,是我們不用表達(dá)大家都知道的事,它看起來并不是一個想法和觀點。

還是購物,但肯定不是教大家怎么購物,作為消費者,購物能給我們帶來什么?

有人說,購物能讓我們吃飽穿暖,讓我們出行方便,讓我們安居無憂。

如果這些你都有,你為什么還要購物?

因為每個人都向往更好的生活!

為了更好的生活,我們需要通過物品的改善帶來心理的滿足感。當(dāng)然也有人會會說,滿足感也可以通過其他的方式獲取,比如關(guān)愛他人、親近自然、學(xué)習(xí)、修行、冥想等等,我們非常認(rèn)同,更好的生活當(dāng)然不僅僅只有購物。但我們當(dāng)下探討的范疇僅僅只是「購物」以及「購物」能帶來的滿足感,對這種滿足感的期待,是每一個消費行為的動因。比如你想要買一件新衣服的時候,其實你已經(jīng)在期待穿上這件新衣服的樣子,你在挑選一件禮物的時候,已經(jīng)在期待他人收到這件禮物時的反應(yīng)……

雙十一,全年最便宜的一天,無疑讓你的期待,變得「更值得」期待,所以「更值得」讓大家買得更多。

但,這些洞察還只是幫我們理清了消費行為背后的共性規(guī)律,實際上,細(xì)分到每個消費者,因為身份角色生活方式的不同,動因各自不同,還不能簡單的用向往更好的生活來概括,因為它太抽象,聽上去對,但每個消費者更關(guān)心的是我的需求是不是被滿足,而對于雙十一來講,我們就是要打造屬于每一人的雙十一,而不僅僅只是購物,這樣它才具有節(jié)日的文化屬性。

所以,我們開始探尋真實的消費者故事,尋找那些通過物品讓生活變得更好的故事,這些真實的故事,給了我們很大的感觸。我們發(fā)現(xiàn),購物行為下,其實還隱藏了每一個消費者內(nèi)心更深層的需求,它是一個個藏在心底的愿望,正是這些不同人的愿望,成就了每一個平凡人鮮活的人生。我們想要幫助他們實現(xiàn)自己的愿望。在雙十一當(dāng)天,幫助每個消費者「愿望11實現(xiàn)」!這才是雙十一更應(yīng)該滿足的消費者需求,它不僅僅是購物,而是通過物品價值上升到情感價值,這樣的品牌,才真正能夠讓人感受到溫度。

在傾聽這些故事的時候,我們的阿里女神被感動了,她主動要求幫我們寫一首歌,她想把她的感動通過音樂的方式記錄下來,配合我們精選出來的11個故事,講給大家聽。

△ 雙十一品牌設(shè)計概念篇mv

「logo出來了?」低沉而沙啞的聲音,把我們從自我陶醉中喚醒,我們找到了想要表達(dá)什么,但和怎么表達(dá)之間還隔著上百個logo方案。

于是,我們開始了一輪又一輪的打磨,打磨的的重點放在了如何表達(dá)「愿望11實現(xiàn)」這一主題,這個過程中,有兩個大方向上的分歧:

一個大方向是表現(xiàn)「愿望」,因為它比較有畫面感,也比較容易表達(dá)。

另一個大方向是表現(xiàn)「實現(xiàn)」,因為它是對結(jié)果的描述,更符合消費者對結(jié)果的預(yù)期。

在糾結(jié)掙扎過后,我們選擇了把兩個方向融合,劇情貌似又回到了熟悉的設(shè)計故事,「把這兩個方案融合一下!」我相信做設(shè)計的朋友,一定反復(fù)聽過這句話,沒聽過的朋友,那說明你做設(shè)計還不久,我保證在你今后的職業(yè)生涯里,這句話一定會反復(fù)出現(xiàn)。(一個會心的微笑)

融合說起來容易,這么抽象的文字怎么轉(zhuǎn)換成圖形表達(dá),同時還要和貓頭+11.11融合,為什么要和貓頭+11.11融合呢,因為這是我們重要的品牌形象資產(chǎn),從2015年開始,貓頭+11.11的組合就固定下來了,這意味著logo的80%的主體已經(jīng)固定,我們的難點就在于在這20%的區(qū)域里,如何既要表達(dá)主題,還能做出和往年不一樣的感覺。我敢向你保證,雙十一的logo是所有l(wèi)ogo里最難的,沒有之一,至少是我十幾年職業(yè)生涯里最硬的茬。

「愿望、實現(xiàn)、貓頭、11.11」這幾個詞反復(fù)在腦海里縈繞,經(jīng)驗告訴我們,當(dāng)面對如此復(fù)雜的局面,我們應(yīng)該從里面跳出來,換個視角看問題,換什么視角?當(dāng)然還是再次回到消費者視角,消費者愿望實現(xiàn)時是一種什么樣的狀態(tài)?是愿望實現(xiàn)時的滿足?好像還差點意思,愿望平時也能實現(xiàn),和在雙十一實現(xiàn)愿望有什么不同?

我們認(rèn)為,它應(yīng)該是超越你期待的表達(dá),從愿望實現(xiàn)時的滿足,升級到愿望實現(xiàn)時的驚喜!這才是狂歡節(jié)該有的味道。當(dāng)然,驚喜也有很多種它還不夠有體感,如何找準(zhǔn)驚喜體感?

答案是感同身受。于是我們開始了場景模擬,模擬消費者逛雙十一的場景。

當(dāng)我們來到雙十一的時候:「咦!今年好像真的不一樣!」

繼續(xù)探索的時候:「呀!找了好久的idou同款原來在這里!」

準(zhǔn)備下單的時候:「喔!真的很便宜!」

收到快遞的時候:「哇?。。?!」

聽上去有點夸張,但這確實是我們想要營造給消費者的驚喜,當(dāng)人感到超越期待的驚喜時,會不自覺的放大瞳孔、張開嘴巴脫口而出。這是人類共通的體感,是不用解釋就有的共鳴。這讓我們瞬間被點亮了,「驚喜到脫口而出!」我們一下子找到了核心創(chuàng)意。

通過反復(fù)嘗試,我們發(fā)現(xiàn)氣泡形的表達(dá),不僅能成為承載所有消費者愿望的想法框,同時也能成為表達(dá)愿望實現(xiàn)時驚喜到脫口而出的對話框,把這個氣泡形和貓頭+11.11結(jié)合,這就是我們今年雙十一主logo的原由,這個logo和以往雙十一的logo最大的不同在于,它更像是一個容器,容納不同人不同的個性化表達(dá)。它一改之前一直端著的狀態(tài),以一種更加親民,更加個人化的方式呈現(xiàn)給大家。

△ 2019天貓雙十一品牌logo演繹視頻

當(dāng)然,作為容器,我們還要把核心創(chuàng)意延展到線上線下各個場景。

△ 雙十一定制禮盒

△ 走向全球的雙十一

過去幾年,我們向大家介紹過天貓雙11的主風(fēng)格的來龍去脈,一定會在創(chuàng)新的基礎(chǔ)上,保持一貫的傳承。所以今年波普藝術(shù)的主基調(diào)還是會延續(xù)下去,問題又回到了我們?nèi)绾卧诓ㄆ账囆g(shù)這個大的基調(diào)下面,通過老元素的新組合,創(chuàng)造出全新的視覺感受。相比符號,視覺風(fēng)格更容易表現(xiàn)「驚喜到脫口而出!」這個idea,它可以通過形色質(zhì)構(gòu)全方位的表達(dá)。

當(dāng)一個人「驚喜到脫口而出!」的時候,快樂的氣場圍繞在他周圍,這些無形的從中心向四周放散的表現(xiàn),看上去很像是圓形聲波,同時它還能根據(jù)不同人的狀態(tài)做動態(tài)變化,這就形成了一種設(shè)計語言,一種能用固定的形式做出千變?nèi)f化的效果的語言。

當(dāng)我們把它和波普藝術(shù)的主基調(diào)結(jié)合的時候,就形成了今年雙十一獨特的視覺語言,再通過形色質(zhì)構(gòu)的拆解,應(yīng)用到各個場景。

△ 裝置應(yīng)用

△ 天貓雙十一發(fā)布會現(xiàn)場應(yīng)用

△ 天貓雙十一開幕盛典現(xiàn)場應(yīng)用

文章來源:優(yōu)設(shè)

JS實現(xiàn)動態(tài)星空背景

seo達(dá)人



這里我截取的是一個圖片,實際上是會動的。廢話不多說,上代碼。

HTML:



<canvas id="canvas"></canvas>

1

CSS:



/css reset /

body,p,div,ol,ul,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,form,input,iframe,nav {

    margin: 0;

    padding: 0;

}

html,body {

    width: 100%;

    height: 100%;

}

body {

    font: 14px Microsoft YaHei;

    -webkit-text-size-adjust:100%;

    -moz-user-select: none;

    -webkit-user-select: none;

    user-select: none;

    position: relative;

    background: #000;

}


canvas {

    width: 100%;

    height: 100%;

    display: block;

    opacity: .8;

}





// 音量大小,0.01-1





//宇宙

var canvas = document.getElementById('canvas'),

ctx = canvas.getContext('2d'),

w = canvas.width = window.innerWidth,

h = canvas.height = window.innerHeight,



hue = 217,

stars = [],

count = 0,

maxStars = 1100;                //星星數(shù)量,默認(rèn)1300

var canvas2 = document.createElement('canvas'),

ctx2 = canvas2.getContext('2d');

canvas2.width = 100;

canvas2.height = 100;

var half = canvas2.width / 2,

gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);

gradient2.addColorStop(0.025, '#CCC');

gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');

gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');

gradient2.addColorStop(1, 'transparent');



ctx2.fillStyle = gradient2;

ctx2.beginPath();

ctx2.arc(half, half, half, 0, Math.PI 2);

ctx2.fill();



// End cache

function random(min, max) {

    if (arguments.length < 2) {

        max = min;

        min = 0;

    }



    if (min > max) {

        var hold = max;

        max = min;

        min = hold;

    }



    return Math.floor(Math.random()
(max - min + 1)) + min;

}



function maxOrbit(x, y) {

    var max = Math.max(x, y),

    diameter = Math.round(Math.sqrt(max max + max max));

    return diameter / 2;

    //星星移動范圍,值越大范圍越小,

}



var Star = function() {



    this.orbitRadius = random(maxOrbit(w, h));

    this.radius = random(60, this.orbitRadius) / 10;       //星星大小,值越大星星越小,默認(rèn)8

    

    this.orbitX = w / 2;

    this.orbitY = h / 2;

    this.timePassed = random(0, maxStars);

    this.speed = random(this.orbitRadius) / 80000;        //星星移動速度,值越大越慢,默認(rèn)5W

    

    this.alpha = random(2, 10) / 10;



    count++;

    stars[count] = this;

}



Star.prototype.draw = function() {

    var x = Math.sin(this.timePassed) this.orbitRadius + this.orbitX,

    y = Math.cos(this.timePassed)
this.orbitRadius + this.orbitY,

    twinkle = random(10);



    if (twinkle === 1 && this.alpha > 0) {

        this.alpha -= 0.05;

    } else if (twinkle === 2 && this.alpha < 1) {

        this.alpha += 0.05;

    }



    ctx.globalAlpha = this.alpha;

    ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);

    this.timePassed += this.speed;

}



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

    new Star();

}



function animation() {

    ctx.globalCompositeOperation = 'source-over';

    ctx.globalAlpha = 0.5;                                 //尾巴

    ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 2)';

    ctx.fillRect(0, 0, w, h)



    ctx.globalCompositeOperation = 'lighter';

    for (var i = 1,

    l = stars.length; i < l; i++) {

        stars[i].draw();

    };



    window.requestAnimationFrame(animation);

}



animation();

藍(lán)藍(lán)設(shè)計www.bouu.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計  圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)。

日歷

鏈接

個人資料

存檔