function _getValue(target, valuePath, defalutVal) {
let valueType = Object.prototype.toString.call(target)
console.log(valueType)
// if (valueType == "[object Array]") {
let paths = valuePath.replace(/\[(\d+)\]/, `.$1`).split('.')
let result = target
for(const path of paths){
result = Object(result)[path]
if(result == undefined){
return defalutVal
}
}
return result
}
測試:
let obj = {
a:{
b:[
{
c:2
}
]
}
}
console.log(_getValue(obj, 'a.b[0].c')) //2
function isEqual(res1, res2) {
let a = getTypeOf(res1)
let b = getTypeOf(res2)
if(a !== b){
return false
}else if(a === 'base'){
console.log('base',res1,res2)
return res1 === res2
} else if(a === 'array'){
if(res1.length !== res2.length){
console.log('array',res1,res2)
return false
}else{
//遍歷數組的值比較
for(let i =0;i<res1.length;i++){
if(!isEqual(res1[i],res2[i])){
console.log('array',res1[i],res2[i])
return false
}
}
return true
}
return true
}else if(a === 'object'){
let ak = Object.keys(a)
let bk = Object.keys(b)
if(ak.length !== bk.length){
return false
}else{
for(let o in res1){
console.log(res1[o])
if(!isEqual(res1[o],res2[o])){
console.log('object',res1[o],res2[o])
return false
}
}
return true
}
}else if(a === 'null' || a === 'undefined'){
console.log('null')
return true
}else if(a === 'function'){
console.log('function')
return a === b
}
}
function getTypeOf(res) {
let type = Object.prototype.toString.call(res)
switch (type) {
case "[object Array]":
return 'array'
case "[object Object]":
return 'object'
case "[object Null]":
return 'null'
case "[object Undefined]":
return 'undefined'
case "[object Number]"||"[object String]"||"[object Boolean]":
return 'base'
case "[object Function]":
return 'function'
default:
return 'typeError'
}
}
測試:
let a = {
a:20,
b:{
c:30,
d:[1,2,3]
}
}
let b = {
a:20,
b:{
c:30,
d:[1,2,3]
}
}
console.log(isEqual(a,b)) //true
function _flat(arr){
let result = []
for(let i = 0;i<arr.length;i++){
if(Array.isArray(arr[i])){
result = result.concat(_flat(arr[i]))
}else{
result.push(arr[i])
}
}
return result;
}
let arr = [1,2,[3,4,[5,6]]]
_flat(arr) //[1,2,3,4,5,6]
//es6
function _flat2(arr){
while(arr.some(item=>Array.isArray(item))){
arr = [].concat(...arr)
}
return arr
}
let arr = [1,2,[3,4,[5,6]]]
_flat2(arr) //[1,2,3,4,5,6]
簡單深克隆,不考慮內置對象和函數
function deepClone(obj){
if(typeof obj !== 'object') return
let newObj = obj instanceof Array?[]:{}
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === 'object'?deepClone(obj[key]):obj[key]
}
}
return newObj
}
復雜版深度克隆 考慮內置對象 比如date regexp 函數 以及對象的循環引用的問題
const isObject = (target) => typeof target === "object"&& target !== null;
function deepClone2(target, map = new WeakMap()) {
console.log(target)
if (map.get(target)) {
return target;
}
// 獲取當前值的構造函數:獲取它的類型
let constructor = target.constructor;
// 檢測當前對象target是否與正則、日期格式對象匹配
if (/^(RegExp|Date)$/i.test(constructor.name)) {
// 創建一個新的特殊對象(正則類/日期類)的實例
return new constructor(target);
}
if (isObject(target)) {
map.set(target, true); // 為循環引用的對象做標記
const cloneTarget = Array.isArray(target) ? [] : {};
for (let prop in target) {
if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = deepClone(target[prop], map);
}
}
return cloneTarget;
} else {
return target;
}
}
filter去重
function _unique(arr){
return arr.filter((item,index,array)=>{
return array.indexOf(item) === index
})
}
es6 Set
function _unique2(arr){
return [...new Set(arr)]
}
includes
function _unique3(arr){
let newArr = []
arr.forEach(item => {
if(!newArr.includes(item)){
newArr.push(item)
}
});
return newArr
}
雙層for循環
function _unique4(arr){
for(let i =0;i<arr.length;i++){
for(let j =i+1;j<arr.length;j++){
if(arr[i] === arr[j]){
arr.splice(j,1)
j--
}
}
}
return arr
}
indexof
function _unique5(arr){
let newArr = []
for(let i = 0;i<arr.length;i++){
if(newArr.indexOf(arr[i] === -1){
newArr.push(arr[i])
})
}
return newArr
}
function _typeOf(obj){
let res = Object.prototype.toString.call(obj).split(' ')[1]
let mold = res.substring(0,res.length-1).toLowerCase()
return mold
}
_typeOf(5) //number
_typeOf('5') //string
function getParamsObj(params){
let paramsStr = params.replace(/^.+\?(.+)/,"$1")
let paramsArr = paramsStr.split('&')
let paramsObj = {}
for(let [key,value] of paramsArr.entries()){
if(/=/.test(value)){
let valArr = value.split('=')
val = decodeURIComponent(valArr[1]) //解碼
val = /^\d+$/.test(val)?parseFloat(val):val //判斷是不是數字
if(paramsObj.hasOwnProperty(valArr[0])){
paramsObj[valArr[0]] = [].concat(paramsObj[valArr[0]],val)
}else{
paramsObj[valArr[0]] = val
}
}
}
return paramsObj
}
//從一次傳入多個參數 編程多次調用每次傳入一個參數
function add(a, b, c, d, e) {
return a + b + c + d + e
}
function curry(fn) {
let dFn = (...args)=>{
if(args.length == fn.length) return fn(...args)
return (...arg)=>{
return dFn(...args,...arg)
}
}
return dFn
}
let addCurry = curry(add)
addCurry(1,2,3)(2)(3)
//添加了兩個功能
// 圖片加載完成后 移除事件監聽
// 加載完的圖片從imgList中移除
let imgList = [...document.querySelectorAll('img')]
let length = imgList.length
const imgLazyLoad = function () {
let count = 0
let deleteIndexList = []
imgList.forEach((img, index) => {
let rect = img.getBoundingClientRect()
//獲取元素到視圖的距離 top元素上邊到視圖上邊的距離 left元素左邊到視圖左邊的距離 right... bottom...
if (rect.top < window.innerHeight) {
// img.src = img.dataset.src
img.src = img.getAttribute('data-src')
deleteIndexList.push(index)
count++
if (count === length) {
document.removeEventListener('scroll', imgLazyLoad)
}
}
})
imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
}
imgLazyLoad()
document.addEventListener('scroll', imgLazyLoad)
圖片懶加載:https://juejin.cn/post/6844903856489365518#heading-19
函數防抖 觸發高頻事件 事件在n后執行,如果n秒鐘重復執行了 則時間重置
//簡易版
function debounce(func,wait){
let timer;
return function(){
let context = this;
let args = arguments;
console.log(timer)
clearTimeout(timer)
timer = setTimeout(function(){
func.apply(context,args)
},wait)
}
}
let btn = document.querySelector('button');
function aa(){
console.log(111)
}
btn.onclick = debounce(aa,2000)
// 復雜版
// 1.取消防抖
// 2.立即執行功能(點擊之后立即執行函數 但是 wait時間之后在點擊才能在立即執行)
// 3.函數可能有返回值
function debounce(func,wait,immediate){
let timer,result;
const debounce = function () {
const context = this
const args = arguments
if(timer) clearTimeout(timer)
if(immediate){
console.log(timer)
var callNow = !timer
timer = setTimeout(function () {
timer =null
},wait)
if(callNow) result = func.apply(context,args)
}else{
timer = setTimeout(function (params) {
result = func.apply(context,args)
},wait)
}
return result
}
debounce.cance = function () {
clearTimeout(timer)
timer=null
}
return debounce
}
let btn = document.querySelector('button');
function aa(){
console.log(111)
}
btn.onclick = debounce(aa,2000,true)```
函數節流 觸發高頻事件 且n秒只執行一次
//使用時間戳
function throttle(func,wait) {
var context,args;
var previous = 0
return function () {
context = this;
args = arguments;
let nowDate = +new Date()
if(nowDate-previous>wait){
func.apply(context,arguments)
previous = nowDate
}
}
}
//定時器
function throttle(func,wait) {
var context,args;
var timer;
return function(){
context = this;
args = arguments;
if(!timer){
timer = setTimeout(function () {
timer = null;
func.apply(context,args)
},wait)
}
}
}
//組合版 options.leading 為true 立即執行一次 options.trailing為true 結束之后執行一次 默認為true function throttle(func, wait ,options = {}) { var context, args, timer,result; var previous = 0; var later = function () { previous = options.leading === false ? 0 : new Date().getTime(); timer = null; func.apply(context, args) if (!timer) context = args = null; } var throttle = function () { var now = new Date().getTime() if (!previous && options.leading === false) previous = now; context = this; args = arguments; //下次觸發 func 剩余的時間 var remaining = wait - (now - previous); if (remaining <= 0 || remaining > wait) { // if (timer) { // clearTimeout(timer); // timer = null; // } previous = now; func.apply(context, args); if (!timer) context = args = null; } else if (!timer&& options.trailing !== false) { timer = setTimeout(later, remaining); } } throttled.cancel = function() { clearTimeout(timer); previous = 0; timer = null; } return throttle } function aa(e) { console.log(111) console.log(e) } let btn = document.querySelector('button'); btn.onclick = throttle(aa, 2000,{ leading:false, trailing:true
})
轉自:csdn論壇 作者:Selfimpr歐
移動互聯網的迅速崛起,讓移動網頁,移動客戶端越來越重要,客戶端的頁面設計也是一門很大的學問??萍佳杆侔l展的今手機屏幕的尺寸越來越放大化,但卻始終 很有限,因此,在APP的界面設計中,精簡是一貫的準則。這里所說的精簡并不是內容上盡可能的少量,而是要注重重點的表達。在視覺上也要遵循用戶的視覺邏 輯,用戶看著順眼了,才會真正的喜歡。
接下來為大家分享精美的app UI設計案例:
icon的設計會貫穿全套設計稿,所以在設計的環節中必不可少,優質的icon設計會幫助品牌和企業更好的樹立形象,形成自己的設計語言。
接下來為大家分享一些經典案例:
--手機appUI設計--
--icon圖標賞析--
更多精彩文章:
據中國天氣網微博預報,大風和沙塵已經到達北京西北部邊界,即將開始影響北京。
此前報道:
大風攜裹沙塵已到河北張家口,傍晚前抵京
北京市氣象臺剛剛預報,目前,大風攜裹著沙塵,已經影響到河北西北部張家口地區,未來繼續向東南推進,下午自北向南影響本市,預計傍晚前影響北京大部。
根據預報,今天下午至前半夜本市有沙塵天氣,最低能見度6公里左右。隨著中午前南風增大,下班前轉北風,沙塵下午就影響北京了。明天接著還有大風天氣,但沙塵影響不會持續。
氣象部門表示,由于上游土壤濕度較3月份增加,加之降水的抑制作用,此次沙塵強度明顯弱于3月15日和28日的沙塵暴過程。
根據北京市生態環境監測中心的實況,目前全市空氣質量已經達到輕度污染水平。
針對此次天氣過程,北京市氣象臺已于14日10時30分發布大風黃色預警信號、16時30分發布沙塵藍色預警信號。市森防辦與市氣象臺已聯合發布森林火險橙色預警。(來源:北京日報客戶端記者 駱倩雯)
注意!沙塵已到內蒙古中部 可能影響北京晚高峰
今天(4月15日)上午9點半左右,今年第三次蒙古氣旋東移帶來的沙塵天氣已經抵達內蒙古中部,并正在向東南移動。今天傍晚前后可能影響到京津冀一帶,或對北京晚高峰造成影響。
據氣象北京微博消息,今天上午9點30分前后,沙塵天氣已經抵達內蒙古中部,并正在逐漸向東南方向移動,內蒙古、甘肅、寧夏等地風沙漸起。
↑內蒙古鄂爾多斯市今天上午已經出現明顯沙塵天氣。(攝/趙建軍)
據中國天氣網首席分析師胡嘯介紹,預計今天下午,這股沙塵將會逐漸自西向東影響京津冀一帶,北京平原地區午后也會逐漸加大,風力普遍可達4~5級,陣風8~9級,伴有揚沙天氣,晚高峰可能是核心影響時段,公眾出行需關注臨近預報,做好防風防沙準備。
此外,據北京日報客戶端消息,北京市教委已建議停止全市大中小學校、幼兒園、中等職業學校及校外教育機構停止體育課、升旗、早操、課間操、運動會、體育考試、外出社會實踐等室外活動。提醒學生注意安全,減少不必要的外出活動。各單位要加強巡視巡查力度,及時消除各類安全隱患。(來源:中國天氣網)
今天還是一篇非常干貨的原創文章。
內容分為兩點:
圖標的基礎特征
動手設計之前,咱們先對完整的圖標集進行分析。
弄明白在畫整體的系統圖標集合時,各個圖標得具備哪些特征,有哪些切入點,可以作為我們在實際繪制時候的依據。
先來看幾組 iconfont 的案例,看不太清的同學可以戳圖片放大。
圍繞上面這些案例,咱們可以歸納出圖標的幾點設計原則。比如:
1. 設計圖標需要考慮延續性,圖標之間互相牽連影響
圖標幾乎不會以單個的形式出現,大多數都是以組歸類。符號整體性與統一性,都是依靠單個 icon 的共性特征建立起來的。
比如 iconfont 中的這組icon,圖標圓形的外輪廓,就保持了一致。其次用戶頭像的代表符號,也很好保持了延續性。
正是這種小特征,共同組成了圖標庫的整體特征。
2. 設計手法趨同、圖形內容差異
第二點好理解,設計風格、手法要素需要統一,但是內容傳達的差異必須要拉開,避免圖形趨同導致功能混淆。
比如下面兩個案例,由于過于相近,導致用戶很難理解圖標含義,是天氣,還是設置按鈕,這種情況我們在設計時需要極力避免。
總結來說,就是圖標的共性往往體現在設計手法上,比如顏色、形狀粗細、細節的一致性,這些都是設計風格的統一。
而圖標的特性,往往體現在形狀內容差異,形狀會決定圖標的信息傳遞含義。所以共性要趨同,特性要拉開,這個是設計圖標集的基本原則。
3. 功能大于形式,圖形能理解的情況下樣式越簡潔越好
不知道大家是否關注,曾經在設計圈風靡一時的MEB圖標風格,產品圈卻非常冷門,幾乎沒有產品在繼續用這種風格作為功能性質圖標。
△ 該作品來自于網絡圖片,僅作交流使用
因為雖然圖標增加了小裝飾后,顯得有趣精致,但其實也增加了圖標的識別難度以及識別效率,反而背離了圖標的設計初衷。
所以對于系統功能圖標而言,必要的簡潔性,高效的識別率,才是關鍵。
圖標的設計約束性
聊完了設計主張及基本的特征。接下來咱們開始剖析圖標的設計細節,包括分析制定圖標的系統設計規范,應該從哪些方面入手。
規范的第一點,就是圖標的基礎形狀比例。這個比例,主要是約束長與寬,共包含了四個關系,分別為「正方形 : 橫矩形 :豎矩形 :圓形」
這四個關系的約束,會讓圖標集里的所有圖標大小,看起來是一致的、統一的。橫矩形、豎矩形這兩個比例,會決定整套圖標的飽滿程度,橫豎比例越一致,圖標整體越飽滿。
這點大家可以自己斟酌,如果是泛娛樂型的產品,icon可以更飽滿一些。如果是偏工具化產品,那么還是可以優先保障圖標的識別度,飽滿程度倒是其次。
圓潤飽滿型:
剛正工具型:
定了比例后,接下里就是對圖標的細節刻畫。對于線性圖標而言,最重要的細節就是線條粗細;對于面性圖標而言,最重要的就是正負形之間的間距。
所以這些核心元素,在圖標的核心線條、核心區域部分,間距樣式都應當保持統一。
通常在移動端@2x內,主流icon的粗細為3px,而4px大多數都是為功能性導航icon,細一點的圖標通常看起來會更精致一些。
當然也有部分產品使用的是2px,比如新版的YouTube,其次還有些較為復雜的icon,單根粗細的線段不一定能滿足其需求,所以還需要制定一條副線的粗細。
細節可以根據產品的調性來定,統一即可。
大比例跟基本元素確定后,也可以制定一些圖標的個性化元素規范,比如圖標的圓角大小、角度位置,等一些特殊的樣式。
像這些個性化的規范,顆粒度可以Case By Case來定義,圓潤還是方正,可以根據產品的視覺風格來定義就好。
這些規范樣式定好,就可以充分的讓圖標集內的圖標,從設計上是保持一致的,且具有特色感。
上面講了關于圖標的分析及規范。為了方便大家掌握,接下來咱們就來講講,具體動手做,流程是什么樣的。這里我給個我的步驟作為參考:
第一步:繪制好圖標基本網格
第一步,當然是確定好圖標icon的大小,以及上面我提到的基本尺寸比例,四個關系「正方形 : 橫矩形 :豎矩形 :圓形」的約束,構建好基本骨骼。
我這里以圖標容器大小為 56×56,預留8px安全間距,圖標最大大小為 48×48。
由于視差關系,圓形在圖標里面的尺寸是最大的,所以圓形的大小為48×48。因為我想圖標飽滿一些,所以正方形的大小我兩邊各減去2,為42×42。
然后再繪制出橫矩形(48×36)與豎矩形(36×48),各線段之間的間距保持一致。
然后各個形狀居中對齊,這樣四個關系「正方形 : 橫矩形 :豎矩形 :圓形」定好后,基本的容器就制定好啦。
第二步:設定圖標基本規范
接著制定好圖標的基本規范,為了方便大家看得清,我這里設定圖標的線條粗細為3px,圓角為6px,干凈簡潔一些,讓它看起來更飽滿。
角度、斷點啥的,我這里就不定義了,因為只是示例給大家看,講一下流程,所以盡可能簡單一些。大家在做練習的時候,也可以嘗試自己去定義一下。
第三步:繪制圖標
好了后就可以開始繪制圖標啦。我這里分別繪制十五個,作為示例
然后就是使用路徑工具,根據創意去繪制完善圖標了。繪制的過程中,也可以不斷調整,讓圖標看起來更協調,更飽滿,更容易識別。
花了十五分鐘左右,簡單的十五個圖標草稿就畫好了,接下來咱們開始調整細節。
第四步:整體性調整
所有的圖標繪制好了后,咱們就可以整體性的開始打磨細節,把圖標形狀的一些折角處、大小樣式調整一致,讓圖標的節奏更清晰,整體樣式更統一。
這樣一組精致的系統icon就繪制好啦。
接著咱們也可以加點特色風格進行嘗試,比如填充一個顏色。
當然細看的話,圖標部分細節還是有點糙,其實還可以再調調,但這個主要做示例用,大家自己在做練習的時候,可別像我一樣偷懶嗷
上面講了很多方法經驗,文末給大家來點實際的。
我珍藏了很多較為不錯的大廠圖標集合庫,日常在畫圖標沒靈感的時候,就會打開看看這些,參考一下。
文件都是矢量格式的,編輯方便,還很全面。今天拿出來送大家白嫖了
文章來源:優設網 作者:UX小學
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
“色彩是我們感知世界的重要媒介,對于信息傳達有著重要的作用,能使人們能夠更有效的感知設計的意圖和內涵,使傳達更高效。且人對色彩的視覺感知與想象能力,能夠指導人做出預測、理解和決策。”
— lyft kevyn arnott
隨著世界的數字化轉型進程大爆發,科技把每一張有形的辦公桌移到了云端,用戶沉浸在數字構建的世界中。騰訊文檔作為先進的生產力工具,產品生態越來越多元豐富,多品類多終端的復雜環境展現在我們面前,開始真正的朝復雜龐大的大規模設計邁進。我們希望能以更加專業、高效的設計姿態迎接騰訊文檔的未來挑戰。
色彩是體現品牌與基因的關鍵因素,構建科學高效的色彩系統,建立產品的品牌形象,對產品設計極具指導意義。
騰訊文檔在色彩上也進行了一些深入的挖掘和沉淀,一方面希望帶給用戶全新的品牌印象和認知,另一方面構建科學有效的色彩系統,為產品的發展提供優質高效的設計系統基礎。本文將聚焦于色彩系統的構建。
騰訊文檔代表著效率協作的先進生產力,從云端創作到云端協作,打破了辦公空間的實體界限。我們希望,新的品牌色,能夠為騰訊文檔塑造更加有未來科技感及智慧感的視覺感受和認知。
我們將標準色由平靜的天藍色,升級為更加生動、進取、科技、可靠的明亮清澈的鈷藍色。這種藍色具有更多的電子意味,蘊含了更多的活力和想象力,承載了騰訊文檔對未來數字世界新挑戰的態度和形象的進化。
同時我們認為灰色在騰訊文檔的色彩系統中起著至關重要的作用,為產品界面創造結構、表達邊界、建立信息層次。我們將灰色賦予了統一的品牌認知感受,將藍色加入到中性灰色里,生成了騰訊文檔特有的藍灰色。
至此,騰訊文檔標準色進化升級,它體現了騰訊文檔對可靠穩定的技術、產品體驗的追求,以及對未來智能的數字世界的不斷創新和進取,蘊藏著無限的可能性。
在一個科學有效的色彩系統里,往往包含至少兩種色彩:主色+輔助色,兩者互相搭配組合成產品體系的整體色彩感受,減少用戶在產品體驗中對反復出現的主色的視覺疲勞。
騰訊文檔的產品生態愈來愈豐富多元。我們擁有多品類的產品,為用戶提供了豐富的產品功能,其中云端協作、文檔資產的沉淀管理是騰訊文檔的非常重要的能力,在線文檔、在線表格、在線幻燈片、在線收集表、在線思維導圖、在線流程圖以及文件夾等的品類圖標,又是用戶在對文檔進行協作分享及沉淀時,識別不同類型文件的關鍵因素?;诖耍v訊文檔相較于其他產品需要更多的輔助色。
于是,如何有效的選擇既符合品牌調性又有區別度的輔助色是構建騰訊文檔色彩系統的關鍵。在輔助色選擇上,我們以鄰近色、互補色、對比色為主要方法構建了輔助色彩體系。
1. 創建色相色板,保持相同明度、相同飽和度
我們以騰訊文檔標準色#1E6FFF(H 218 S 88 B 100) 為起始點,S(飽和度)、B(明度)保持不變,H(色相)以 218°為起點,以 15°為增量或減量標準,生成 24 色色板。這個色板是我們選取輔助色的重要依據。
2. 以鄰近色、互補色、對比色為原則選擇豐富的輔助色彩
為了保持騰訊文檔的基礎品牌調性,并保證其具有極清晰的識別度,我們以品牌藍色為起點,選擇了相對較多的鄰近色,以保證在色溫上保持騰訊文檔整體色調的清爽感。并利用對比色及互補色,選擇更加豐富多元的色相,以保證能夠滿足各種使用場景下對色彩的需求。
總的原則是利用鄰近色構建有質感、品牌感的色彩家族,利用對比色及互補色擴展色相,以制造更強烈的色彩對比,滿足一些沖突性場景。
3. 校正輔助色
雖然我們保持相同的飽和度和明度,使用科學的方法得到了較為合適的色相,但由于色彩本身自帶感官明度屬性,導致在視覺感受上的感官體驗并不同頻。
黃色、綠色的明度即發光度較高,藍色就稍微偏暗一些,導致色板看起來不一致。為了讓不同色相看起來更加協調,需要調整色板的明度和飽和度,以保證視覺感官體驗同頻且更加和諧舒適。
校正原則:
校正后我們得到了清澈明亮、清晰易分辨的騰訊文檔的主色+輔助色。并且針對視障群體進行了色彩測試。
灰色是產品體驗設計中至關重要的一節,工具型產品大部分是由各種各樣的容器、面板、列表組成?;疑珵楫a品界面創造結構、表達邊界、建立信息層次,保持舒適的對比度是提高可讀性和吸引用戶注意力的關鍵。
前面我們已經定義了騰訊文檔的藍灰色,在界面的設計中,我們將其與中性的灰色結合,共同構建灰色的色彩體系 。
騰訊文檔藍灰色相擴展:
中性灰色色相擴展:
為構建一個高效易用的灰色調色板,我們將藍灰色彩作為 Y 軸,有透明度的中性灰色作為 X 軸,兩者透明度保持一致,建立起騰訊文檔有梯度的、豐富的灰色調色板。
對比度是否合理是閱讀體驗是否舒適的重要評價維度,過高或者過低的對比度都會影響閱讀體驗及識別度。下圖是對比度的鐘型曲線圖,隨著對比度的增加,舒適度和識別度都在上升,但一旦超過一個界點,對比度越增加,識別度和友好度亦會逐步下降。
為保證視障用戶的使用,保證足夠的對比度,遵守 WCAG 2.0 的標準,我們對調色板灰色的對比度進行了可用性測試,以指導騰訊文檔體驗設計中灰色調色板的使用。
是:對比度在 AA 標準以上,符合 W3C 標準,可以使用。
中:僅可用于 disable 狀態。
否:對比度在 AA 標準以下,不符合 W3C 標準,不可使用。
定義好文檔的主色、輔助色以及中性色后,我們需建立完整的調色板來滿足不同場景下顏色的使用。以傳達品牌精神,建立色彩層級,或傳達信息,或強化界面層級。
在色彩系統中,很多產品使用 Tints and shades 系統,通過在顏色上面增加白色,或者增加黑色,來改變它的明度和飽和度,形成同色系的調色板。但這種方法得到的調色板往往比較刻板僵硬,故騰訊文檔采用了另一種方式,將已生成的灰色色板與色相疊加,在符合無障標準的區域,選擇不同明度飽和度的色彩,形成有梯度、有層級的彩色調色板。
Tencentdocs_blue:
生成主色-藍色色階:
用同樣的方法將輔助色生成色階:
現在,我們有一個梯度豐富,能夠支持騰訊文檔設計系統的調色板了~
實際案例
實踐才是硬道理,我們嘗試以這個調色板為指導來調整優化騰訊文檔鏈接色的優化調整。
為保證用戶閱讀體驗的舒適度,鏈接之類的彩色文本,要求顏色在背景下可以達到 4.5:1 對比度以上,以使它能夠清晰的從灰色文本、背景中脫穎而出。于是,我們放棄了品牌藍_1E6FFF,選擇了品牌藍 70_175CEB 作為鏈接色。
以后,選擇顏色,so easy~
這個長長的制作調色板的故事就要結束了,我在這項工作中,重新審視過去設計中的設計決策方法,在其中學到了很多東西,希望本文對您也有所幫助。
我們經??焖俚膭邮?,依靠主觀情感去選擇顏色,在剛開始可能沒遇到什么特別的問題,但隨著產品的壯大和發展,往往會越來越凌亂。抽絲剝繭的搭建色彩系統,真正讓色彩為設計服務,簡化團隊的工作,相信您會有更愉快的工作體驗~
文章來源:優設 作者:騰訊ISUX
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
“搜索”是產品中一個非常必要的功能模塊,搜索就像為用戶提供了一條便捷的綠色通道,方便用戶快速檢索內容。
搜索動作在 App 中依靠搜索框來完成,好用的搜索框很大程度上決定了產品的搜索體驗如何。大多數搜索框存在相似性,但真正好的搜索框會在細節上為用戶帶來差異化的反饋,帶來很暖很貼心的感覺。
從體驗層面上看,一個良好的用戶體驗需要具備完整的流程。搜索框的使用流程可以簡單劃分為:
其中使用中會涉及到跳轉和輸入兩種不同的狀態,在下面的文章里我會展開來分析。
回想常用 App 的搜索框,好像它們的樣式看起來差別并不是很大,但其實每個搜索框的細節都是經過精心設計的,下面總結了幾種常見的搜索框類型。
1. 搜索圖標
頁面上只提供一個放大鏡圖標,通常需要用戶點擊圖標后才能跳轉到搜索頁面,例如小紅書就將搜索圖標放置在頁面右上角。
2. 基本搜索框
基本的搜索框組成包括放大鏡圖標、文字提示、輸入框三部分。微信主頁的搜索框采用了這種基本形式,文字提示為搜索,簡潔清晰。
3. 文字提示類搜索框
和基本搜索框的唯一不同的地方在于,這類搜索框中的文字提示部分不再是搜索兩個字,而是根據產品需求支持預置多組文字提示并在搜索框內循環展示。
△ 在大眾點評的頂部搜索框中,文字提示部分循環展示了三組不同的內容,引導用戶快速檢索到好吃的和好玩的。
4. 功能類搜索框
之所以叫做功能類搜索框,是在文字提示類搜索框的基礎上根據產品功能的需要額外添加了常用的功能性圖標,如掃碼圖標、拍照圖標、語音圖標等,賦予搜索框更多的功能屬性。
△ 經常使用豆瓣看書評的同學可能會注意到豆瓣主頁的搜索框中有一個掃碼圖標,點擊之后可以快速掃描圖書條碼或二維碼,快速識別書的內容,省去檢索的麻煩。
△ 淘寶搜索框的組成更復雜,除了支持掃碼外還有相機圖標,方便用戶拍照識別商品。
使用搜索框搜索的過程總體可以分為四部分:搜索前、點擊搜索框、輸入中、搜索后。設計分析過程中我們要先理清整體的搜索流程,再考慮每個狀態對應的交互細節及反饋,這樣才能保持邏輯清晰。
位置
大多數搜索框出現在頁面頂部,作為一個大的觸摸目標更符合用戶的認知習慣,更容易被用戶發現和使用。
△ 在蘋果自帶的地圖應用中,搜索框放在頁面中部偏下的位置,相比于頂部搜索框,這樣的位置分布更方便用戶單手操作。
樣式
搜索前的狀態除了前面講的幾種常見的搜索框樣式外,有些產品會直接在搜索框增加“搜索”按鈕。
△ 阿里系產品包括淘寶、支付寶、閑魚等主頁搜索框都額外添加了“搜索”按鈕,相比于點擊搜索框再點擊鍵盤搜索內容推薦,直接點擊按鈕簡化了搜索流程。
搜索框
點擊搜索框后,框內的放大鏡圖標會消失,出現閃爍的光標引導用戶輸入,搜索框右側會出現“取消”按鈕。
△ 點擊大眾點評的搜索框后,搜索頁會出現三個選項,點擊每一個選項,搜索框內的文字提示都會改變,有效幫助用戶提升搜索準確度,雖然是很小的點但做的很用心。
鍵盤
點擊搜索框后會彈起鍵盤,在不輸入內容的情況下,點擊鍵盤自帶的“搜索”按鈕能查詢搜索框中推薦的內容。
搜索頁
搜索頁的內容通常包括歷史搜索、搜索發現、熱門推薦等版塊,記錄用戶的搜索行為,推薦目標商品或服務,提高轉化率。
△ 豆瓣將最熱門的內容都展現在搜索頁中,包括實時更新的熱門書影音榜單、熱門小組、熱門話題等,為用戶提供有效的引導。
關于歷史搜索我們還可以繼續深入分析,思考這些記錄怎么排序、最多顯示幾條記錄……
△ 網易云音樂的歷史搜索最多可以保留10條,采用橫向滑動的手勢交互可以節省屏幕空間。根據內容長短一屏一次可以顯示2-3條記錄,這會導致排在后面的歷史記錄不容易被用戶快速發現。
△ 淘寶的歷史搜索可以容納更多的數量,當搜索記錄超過兩行時會有一個小的展開按鈕,點擊按鈕可以查看早期的記錄,這樣既能節省屏幕空間也能最大化容納歷史記錄。
刪除/取消
當開始輸入內容時,在搜索框的右側會出現刪除圖標,方便用戶一鍵刪除輸入的內容,這里要注意區分刪除和取消的區別。
△ 在淘寶中點擊“刪除”圖標,頁面會返回到上一級也就是搜索頁;
△ 點擊“取消”按鈕,頁面會直接返回到主頁也就是搜索前的狀態。
搜索提示
在用戶輸入內容時,產品會根據用戶輸入的內容提供相對應的搜索推薦,這是搜索框的必備的交互反饋。
通過合理的詞條推薦能極大降低用戶的思考時間,提高搜索效率,同時省去再次點擊搜索按鈕的流程,降低用戶的操作步驟。
字數限制
目前我所知道的大多數 App 在搜索時都沒有字數限制問題。
回顧一下搜索使用場景會發現用戶在搜索框內輸入任何內容都是有可能的,盡量不要約束用戶的輸入內容。無論用戶輸入多少內容,點擊都可以完成基本的搜索操作,這樣整個流程才完整。
△ 在百度中輸入過多字符時,會提示查詢限制在38個漢字以內,多的字符會被忽略,雖然給出了提示但并未打斷用戶的操作流程,可以讓用戶繼續完成搜索。
符合預期
搜索的理想狀態是搜索到的結果符合用戶的預期,滿足用戶的搜索需求,并把最吻合的搜索結果排在前面,為用戶帶來清晰的結果展示。
智能提示
智能提示是對用戶輸入內容上的一種提示或糾正,如果用戶輸入的內容有問題或不夠標準,在搜索結果中會能給最貼切的搜索結果。
△ 在淘寶中輸入“shouji”或“souji”,淘寶會根據拼音給出“手機”的搜索結果,但仍保留原標簽,方便用戶再次點擊搜索;輸入“手ji”時,會直接給出“手機”標簽,這種差異化的反饋能更好的為用戶服務。
無結果提示
△ 相比于直接顯示搜索無結果的狀態,拼多多的搜索結果首先會標明相關商品較少,然后將搜索內容拆分成不同的標簽進一步引導用戶來發現內容。
這里介紹了關于搜索框設計的一些基本體驗,學會從整體到局部再到具體細節一步步分析,大家會挖掘到更多更細的設計要點。
文章來源:優設 作者:Clip設計夾
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
當公司的發展規模到一定程度時,考慮到信息安全、持續采購成本與相關風險,企業會采取自研的方式來實現部分協同工作軟件的自產與自用,本文將以內部目標管理系統為例,闡述我們是如何系統化的做企業系統設計改版?
什么是OKR?
OKR,是Objectives 和Key Results 的縮寫,即目標和關鍵結果,它是企業進行目標制定和過程管理的重要手段??峒覙吠瑯硬扇KR的管理方法,將公司目標層層分解到團隊,部門再到個人,在各個層面貫穿和統一起來,以幫助實現目標達成。
理清業務目標,制定設計策略,是系統性改版產品的前提,在實際工作中設計師很容易被產品的原型、對產品的描述蒙蔽,只有非常清楚的理清業務的目標,才能制定系統性、合理的設計策略來支撐業務,通過專業的設計方法來助力業務結果的達成,在這個項目中我們是如何做的呢?
OKR系統的改版項目最開始是高層的訴求,提的業務要求很簡單“ 讓大家用起來,目標管理起來”,那么如何讓大家用起來、利用系統將目標管理起來是當前需要解決的的問題。
以一個普通員工【小何】為例,在OKR系統中進行OKR制定時,通常需要與多個角色產生關聯:
③結束回顧,包含查看、追溯、復盤
(1) 清晰的頁面結構:
讓用戶能明確的感知到系統的整體結構是有規律的,可以簡單被理解的,即左邊全局控制,右邊內容展示
我們把消息類型通過兩個維度定義消息的優先級:“重要性”和“緊急度”,通過四象限法則,我們拆出來了:
通過此模型和產品確定了每一個消息類型的所在位置,且清晰表達的了每個消息應當的位置
在設計的過程中,為了進一步的驗證設計合理性和易用性,針對角色代表進行了8組可用性測試,最終普遍反饋新版的操作體驗更好。
你是否有在聽別人說某某原理法則時一臉懵B的時候?明明知道這個原理卻說不出它的名字?不要緊,本文就來介紹與人機交互設計相關的15個常見的設計心理學原理,約13000字,幫助你了解產品的定位,需求目的和交互邏輯,洞悉用戶的各種行為,也為自己的設計予以理論支撐。
1956年美國科學家米勒對人類短時間記憶能力進行了研究,他注意到年輕人的記憶廣度為5-9個單位,就是7±2法則。與席克定律類似,神奇數字 7±2 法則也經常被應用在移動應用交互設計上。
因為人腦處理信息的能力有限,所以它通過把信息分成塊和單元來處理復雜問題。7±2法則應用很廣泛,例如iPhone通訊錄中的手機號碼被分割成”xxx-xxxx-xxxx“的形式,還有銀行卡號、身份證號,我們總是喜歡把一長串數字拆分開來讀寫,目的就是降低記憶成本,提高信息的易讀性,從而達到視覺防錯的作用。
Web導航欄選項卡數量不超過9個
在設計網頁導航時,如果希望用戶記住導航區域的內容或者一個路徑的順序,那么數量應該控制在7個左右(不超過9個),如蘋果、Dribbble、behance等網站的導航分類。
Web導航欄選項卡數量過多時
如果導航或選項卡內容很多,可以用一個樹狀層級結構來展示各級別關系,但要注意其廣度和深度的平衡。例如人人都是產品經理和Dribbble,把更多子類別收在二級目錄里。
移動端選項卡導航
在移動端應用設計中,常見的電商app例如奈雪和樂凱撒分類模塊,兩個產品的商品分類布局形式很相似,都是用了選項卡的方式來分類商品,層級明確,相應的提升了用戶找尋單品的效率。
Tabbar區標簽最多不超過5個
在移動應用設計中,底部Tabbar最少3個,最多為5個(幾乎沒幾個超過5個),這樣做除了減輕用戶記憶負擔,超過5個會降低視覺和操作上的體驗。事實上就算只有4個,我們也經常想不起微信底部的4個Tab分別是啥。
頂部導航欄頁簽
我們看到的大部分app頂部導航欄的頁簽數量都嚴格遵循了7±2法則,雖然在橫軸可無限滑動,
但在顯示區域只保持7±2法則的顯示數量,例如馬蜂窩、飛豬旅行等。
金剛區圖標不超過8個
我們常說的“八大金剛”就是一屏顯示8個圖標,超過的則放在第二屏。如果兩行10個,往往第十個是“更多”入口,總的來說也沒超過9個。
banner文案不超過9個字
產品運營banner主文案字數通??刂圃?個字以內,在設計時也通常把長標題一分為二排兩行,便于用戶快速閱讀,提升點擊率。
在交互設計中,7±2法則是減少用戶認知負荷,提升用戶體驗的重要環節。同時還強調了在設計過程中對產品的預見性,避免在不斷為產品添加功能時,破壞原有的視覺基礎。
0無需說明書
喬布斯曾說過:“蘋果應該創造所有人都可以使用的產品,即使沒有用戶指南”。
1 一看就會
簡單易懂,看一眼就明白你想說什么,不用教學就知道怎么用。
2秒法則
所謂“2秒法則”,是指用戶在使用某類系統時的等待時長不超過2秒。在極短的時間內展示重要信息,給用戶留下深刻的第一印象。這里的2秒只是一個象征意義上的表達,也許有一點隨意,但是這卻是一個合理的數量級。我們熟知的“F”瀏覽模式其實就是間接縮短用戶看到重要信息的時長,達到快速瀏覽的目的。
進入App的首頁加載時間如果過長就會導致用戶產生厭煩情緒,很容易退出甚至卸載App的行為。因此我們看到許多應用將首頁加載時的空白頁進行占位圖設計。
下拉刷新也是一個設計點,為避免刷新時間過長,設計師通常會在加載動畫上做文章。充滿趣味性的動效能安撫用戶焦躁不安的心情,無形中降低了用戶對等待時間的感知。
APP里面的banner設計要有視覺沖擊力,如果兩秒之內沒有抓住用戶的眼球,可能就被用戶忽略了。
因此,在設計互聯網產品的頁面時,用戶等待的時間越短,用戶體驗越佳。反之,就會讓用戶產生焦慮的情緒。
3次點擊法則
用戶在3次點擊之內如果還沒有找到他們想要的信息或了解網站特色,他們就會離開該網站。這條原則突出了清晰的導航,符合邏輯的結構和易于理解的網站層級的重要性。(來自《眾妙之門》P133)
其實在交互體驗中,點擊的次數往往是無關緊要的。只要每次點擊都是無需思考的,毫不費力地順勢進行,那么用戶的挫敗感就會大大降低。如果你的網站能夠讓用戶知道他在哪里,從哪里來,要到哪里去,并且能夠讓用戶了解如何完成目標,這樣的點擊即使有10次也是沒有問題的。例如,在京東購買一件商品需要經過“立即購買>確定>提交訂單>選擇支付方式”4次點擊才能到訂單支付頁面完成購買,這過程中可能還穿插其他的點擊行為(比如選擇地址、優惠券),用戶并沒有感受到不方便,使用過程流暢而自然。
在可用性測試領域,“三次點擊”定律一直是一個很具爭議內容。體現在以下幾點:
·研究表明,用戶在超過3次點擊還沒到達想去的頁面時,往往并沒有退出網站,而是會繼續多點幾次;
·當把一個3次點擊就能到達的流程改為4次點擊的時候,用戶發現目標頁面的能力反而提升了600%;
·合理的導航系統比點擊次數更重要;
·比起“3次點擊”,有人提出了“1次點擊”定律,即用戶的每一次點擊都應該讓他們更接近目標,同時盡量減少能干擾實現這一目標的因素;
·用戶抱怨要花很長時間才能找到某個產品,實際上他們是在抱怨無法找到想要的東西,如果用戶找到了想要的東西,他們就不會抱怨點擊的次數了;
英國心理學家William Edmund Hick認為,在簡單的判斷場景中:一個人所面臨的選擇越多,做出決定所花的時間就越長。有時候在選擇中花費太長時間從而導致決策失敗。
生活中我們也經常會面臨選擇困難癥,比如早上起床就糾結今天穿什么?中午去食堂就會糾結吃什么?造成我們如此糾結的原因就是因為選擇太多了(遠古人就沒這些煩惱,尋找食物時逮著什么就吃什么)。
在設計中的應用
應用到界面設計中也是如此,選項越多,意味著用戶做出決策的時間越長。
例如APP Store首頁,改版前的首頁把眾多app平鋪出來,對目的不明確的用戶來說選擇有點多。改版后的首頁大幅減少了App的數量,卡片的設計方式簡潔且目標清晰。
不得不面對較多選項時, 對主要和次要的選項做視覺權重區分,做好設計上的歸類,提升用戶做決定的效率。例如美團外賣金剛區第一行5個入口的圖標在尺寸和表現手法上都比下面的入口圖標要大更醒目?!拔业摹表撁姘岩恍┑皖l率功能或不太重要的功能收納到“設置”里,此外還可以通過置灰、鎖定等方法間接減少選項,降低干擾。
對于多流程的任務進行分步操作,讓用戶專注眼前任務。 例如Clubhouse注冊時,把需要用戶選擇的選項分步引導完成,讓用戶能專注當前行為。
對于多種類別的選項應當做二次分類的區分,我們都知道電商平臺的品類繁多,僅通過單一分類是不夠的,比如數碼頻道下面還分相機、影音娛樂、數碼配件、智能設備、電子教育等大的分類。商品詳情頁的篩選功能也是貼合使用場景來設計的,所以分類不怕多,就怕混亂。
適用邊界
雖然選擇越少,用戶做決策的時間越短,但這并不是提高用戶體驗的唯一標準,過度的減少選項,可能導致負面效果。
如上圖右,如果在刪除App的彈窗中只有一個“刪除”選項,沒有明顯的取消之類的途徑,那么用戶會覺得特別難受,感覺被強迫去刪除。如果當下有急需使用手機處理一些事情,那么這樣會把這種負面情緒給無限放大,讓用戶抓狂。
??硕芍饕苡绊懹谶x項的多少,但是它不適用于需要高難度閱讀的任務。例如考試試題每道題只給你A、B兩個選項(學渣竊喜),那也太容易蒙了,這就是??硕稍诖鸢冈囶}中的局限性。
希克定律是一個可以適用于設計的指南,記住要盡量減少用戶在一次決策中要做的選項,因為決策效率是一個產品導致用戶流失的重要原因之一。引導用戶在明確的選項之間進行選擇,以便快速將他們送到某個地方(例如賬單支付),這將大大提升用戶體驗并達到你的目標。
費茨定律由心理學家Paul Fitts提出,用來預測從任意一點到目標中心位置所需時間與該點到目標的距離和大小有關,距離越大時間越長,目標越大時間越短。舉例來說,你伸手去拿桌子上的咖啡杯,開始你的手臂迅速地往杯子位置移動,接著你會放慢速度直至找到杯子把手,這個杯子把手的大小與你“抓住”它有著一定的關系。
如上圖所示,如果光標現在在任易地點想要去點擊目標target,最短路徑一定是D,最短路徑上容錯的最長路徑是D+W,只要水平上移動超過了D+W你就點不到了,而這個點擊動作所耗的時間是一個常數加上一個以D為正比W為反比的函數的和。
詳細解釋如下,圖中紅色方塊代表點擊目標,虛線代表移動路徑,此時因為紅色方塊目標較大,所以用戶從任何一處點擊都很容易(可以用鼠標在屏幕任意點移至紅色方塊試試)。
相反,紅色方塊目標變小,快速點擊就會困難很多,很難一次到位。
但如果紅色方塊目標很小距離很近的話,因為移動范圍小,也能準確的點擊到。
按鈕越大越容易點擊
在頁面中,大而近的目標區域意味著用戶不需要做太精細的調整就可以輕易的觸達目標。比如頁面中的大按鈕。
將按鈕放置在離開始點較近的地方
夸克瀏覽器的搜索欄就放在離手最近的屏幕底部區域,相比常見頂部搜索欄更方便操作,效率更高。
相關按鈕之間距離近點更易于點擊
注冊登錄界面,通常將「注冊」和「登錄」放到一起,不僅可以在視覺上增強用戶對他們相關性的認知,還可以減少在他們之間的距離 。
適用邊界
費茨定律鼓勵減少距離,增加目標大小以提升用戶效率,但反過來亦適用。比如iPhone關機按鈕,沒有使用點擊關閉,而采用滑動操作,還把按鈕放在屏幕頂部,這樣明顯增加了操作難度,進而避免了用戶誤操作。
App彈窗經常把“關閉”按鈕放在卡片的右上角離手遠的地方,希望用戶先完成彈窗提示的任務。還有啟動頁廣告,喜歡把“跳過”按鈕放在難以點擊的右上角(恰飯重要),以提高用戶的誤觸機率提高轉化。
思考小結
按鈕越大越容易點擊,因此在程序開發中,會增加按鈕點擊的熱區范圍,減輕用戶精準點擊的壓力。但也不能過分的大,容易引起誤觸;
讓相關聯的內容更靠近彼此,用視覺手法增強用戶對它們相關性的認知。距離產生美,注意不要靠的太近,會出事;
將按鈕放置在離出發點較近的地方,比如頁面主按鈕一般會放在屏幕底部易操作區域;
屏幕的邊角很適合放置像菜單欄和按鈕這樣的元素,因為在屏幕邊緣和角落位置有“無限可選中”的屬性,可以大膽操作而無需“微調”,參見macOS底部dock欄;
定律的反向使用可以適用一些特殊場景,比如想達到某種目的而降低按鈕被點擊的可能;
“任何事物都具有其固有的復雜性,無法簡化”。
泰斯勒定律(Tesler’s Law)由Larry Tesler于1984年提出,也稱「復雜度守恒定律」。
該定律認為:每一個過程都有其固有的復雜性,存在一個臨界點,超過了這個點過程就不能再簡化了,你只能將固有的復雜性從一個地方移動到另外一個地方。
生活中很多我們習以為常,感覺便捷方便的生活方式,是無數卓越的數學家、工程師、設計師等無數的時間投入,才實現的某個小功能,是他們把這些復雜性轉移到自己身上替我們簡化了。
說回移動端,每個應用中都有其無法簡化的復雜度,也不能按照我們個人意愿去除這些功能。這就是為什么飛機稿都簡潔好看,而一搬到線上就面目全非。常見的復雜性轉移有:“查看更多”、“查看全部”、“查看詳情”、“展開和收起”之類的文字做轉移跳轉,比如:頂部導航欄的更多圖標,就是將常用的功能整合并隱藏在首頁設計的更多功能模塊中,把用戶的操作范圍轉移到另一個地方。
除此之外,還有一些降低操作復雜度的方法:
刪除、組織、隱藏
視覺層面的“降噪”方法,刪除會干擾用戶操作的選項;功能分類明確,圍繞用戶行為組織信息內容;隱藏那些不常用而又不能少的功能,延遲及階段性展示??偟膩碚f就是將復雜的信息收起來,展示重要且簡潔的界面。
簡化交互設計
可以用代碼節省用戶操作時間的地方,是互聯網人一致的追求。例如,B站的一鍵三連,用戶長按點贊按鈕,會同時觸發點贊、投幣和收藏,省時省力。
算法解放“生產力”
個性化算法就是通過技術手段,將用戶復雜度降低,而轉移到開發者身上。抖音為什么會讓人上癮?是算法知道了你的喜好,專推給你喜歡的內容而不用自己去找,誰都喜歡私人定制。這對用戶來說是一件好事,但就像魯迅說的:“你覺得好,一定是有人在負重前行”,這里的簡化復雜的難度就轉移到設計和開發身上了,還逼得機器去學習。例如抖音、淘寶、知乎首頁推薦的內容都是基于你的喜好定制化推薦給你的。
我們常說以用戶為中心去設計,就需要從用戶角度出發,在交互設計中盡量簡化操作的復雜度,降低學習成本。但如“復制粘貼之父” Larry Tesler (1945-2020) 所說:“任何事物都具有其固有的復雜性,無法簡化”。因此,如何取得復雜度的“平衡點”就是重要的部分,是讓工程師及設計師花費大量時間去降低產品的使用難度,還是在設計中保留一定的復雜度是我們需要思考的事。
該原理是由麥肯錫國際管理咨詢公司顧問Barbara Minto提出的理論,她強調結論先行,論點自上而下。
你是否遇到過這樣的場景,部門開會時有人口若懸河的講了半天,到最后你都不知道他想說什么。所以如果開會時你會走神,這不怪你,只怪講演者說話沒有邏輯,沒有重點。
金字塔原理指示結構化表達遵循結論先行的原則,即任何問題都能歸納出一個中心點,讓受眾能夠第一時間清楚你想談論的主題。然后由數個論據作支撐,而這些一級論據可以繼續由數個二級論據支撐,如此延伸,狀如金字塔。自上而下,上層影響下層。
應用到交互設計上,即將信息展示的重點與交互行為的主任務優先展示,再根據用戶在這個界面上所愿意停留時間逐級給予更多細節補充。以京東的商品詳情頁為例,首先金字塔的最上層是用戶目標明確直接進行“立即購買”的底部全局按鈕,其次是商品的頭圖和用戶評價這些,讓用戶了解更多信息,進一步促成購買,最后一層是提供商品相關的全部信息、參數、評分等,確保交易的最終完成。在這個過程中,用戶在每一層花的時間也在逐級增加,呈金字塔狀。
映射到設計師身上也是如此,從設計新人到設計總監,中間差的就是一個完整的設計技能金字塔。就像升級打怪,每完成一項任務獲得相應的經驗值,累積的經驗值幫助我們更快的升到下一級。當把工作中的需要攻克的難題一一解決之后,你的設計水平會在不知不覺中更加精進,形成一套自己的設計風格,成為一名優秀的設計師。
有趣的是,把金字塔模型倒過來就成了“用戶漏斗模型”。自上而下,激勵用戶成長。它告訴我們:
用戶的需求是永遠滿足不完的,所以什么值得做,什么是可分階段去實現的是決策人需要明白的。如喬布斯所說:“消費者并不知道自己需要什么,直到我們拿出自己的產品,他們就發現,這是我要的東西”;
不斷完善主要功能,以滿足金字塔頂的核心用戶群。決策者常常添加一些自己想要的而不是用戶想要的需求,比如在信息流中添加一個廣告位;
如何優化完善產品架構,檢驗產品策略的合理性和完整性;
防錯原則由世界著名的品質管理專家新鄉重夫提出,即在過程失誤發生之前加以防止,是一種在作業過程中采用自動作用、報警、標識等手段。使操作人員不用特別注意也不會失誤的方法。
防錯原則認為大部分的意外都是由于設計的疏忽,而不是人為操作失誤,可以通過優化設計把過失降到最低。該原則最初用于工業管理,后來應用于界面交互設計中,當使用條件沒有滿足時,常常通過功能失效來表示。
自動檢測提示
bilibili在登錄時輸入框沒有內容或沒有輸密碼時,登錄按鈕處于禁用的置灰狀態,只有兩者都滿足了才可以正常點擊。此外登錄功能就可能會有用戶名錯誤、密碼錯誤、網絡超時、郵箱錯誤等不同的錯誤。通常必須賬號和密碼同時滿足且匹配才能成功。
Twitter發帖時只允許用戶輸入140個字,為了提醒用戶,其解決辦法是在鍵盤上方的工具欄上顯示還能輸入幾個字符,超過會以負數警示。知乎發布文章標題過長時也會提示錯誤預警。
消除可能的失誤
防錯法則認為大部分的出錯都是產品設計的不夠優秀,而不該責怪用戶操作疏忽,通過設計手法可以把出錯率降到最低。防錯法則的核心觀點是,如何有效的在用戶出錯之前就盡量避免錯誤的發生。比如,美團外賣在接受短信驗證碼時,系統會自動提取驗證碼在鍵盤上方顯示,用戶點一下就可以自動填寫,省去了跳出應用——打開短信——記住驗證碼——再輸入的繁瑣過程,有效預防了出錯的機率。還有微信在綁定銀行卡時也是通過掃描銀行卡自動提取賬號,避免手動輸入的出錯率。
將失誤降至最低
二次確認,在一些比較重要的場景讓用戶二次確認,通常以彈窗的形式告知用戶再次讓用戶考慮自己的行為結果,進一步降低出錯率。例如,最近大家都在用的報稅App,會在提交信息前再次確認。
視覺暗示
可在視覺(置灰或隱藏)上屏蔽那些不能選的選項,避免用戶點擊后才報錯或點擊沒反應。
其次,一些不可恢復的操作,視覺上通常會給強標識。例如,刪除短信時的文字顏色“變紅”。
為用戶犯的錯買單
當用戶輸入錯誤信息時,比如打錯字,系統應該給予用戶想要的信息,而不是無動于衷,冷漠視之。
范圍限制
其實限制用戶的選擇并不是一個好主意,但是如果有明確的規則來定義可接受的選項,那么限制用戶可以輸入的類型是一個很好的策略。例如,Airbnb訂房可選日期和設置鬧鐘時的時間范圍。
研究得出,使用產品時有77.7%的錯誤都是人為的,防錯法則可以幫助設計師站在用戶體驗的角度考慮設計方案,做到操作前、中、后都有及時的反饋,預測到他們有可能發生的誤操作狀態,讓用戶更快完成目標,幫助用戶減少出錯率。
每次拿起U盤插入電腦時,我就呆住了,到底朝那個方向才是對的?
防呆(Fool-proofing)是一種預防矯正的行為約束手段,運用避免產生錯誤的限制方法,使出錯的機會降至最低,進而達到“第一次就把工作做對”之境界。
設計師應謹記:不要認為用戶是專家。比如,我們都知道“漢堡”圖標就是菜單,點擊這個按鈕就會調出某些功能。但是設計師忘記了普通用戶可能并不理解什么是漢堡包圖標、什么是面包屑、什么是抽屜式導航、什么是3Dtouch、怎樣雙指滑動。更何況普通用戶并不會研究App,在他們眼中產品只是眾多工具中的一個。因此,一定要把交互和設計做的簡單,通用的圖標、功能和交互方式最好保持用戶熟悉的樣子,減輕用戶重復學習的負擔。每個頁面應強調一個重要的功能而不應該讓用戶做選擇題,這些都是有效防呆的好方法。
△頁面的中主按鈕更突出
防呆設計是預防錯誤發生的方法,讓非專業、無經驗的用戶可以高效完成正確操作,不要讓用戶去思考,而是我們時時為用戶思考。
又被稱作“簡單有效原理”:“如無必要,勿增實體?!?
通俗點去理解“如無必要,勿增實體”可以理解為“不要浪費較多東西去做用較少的東西同樣可以做好的事情?!被蛘弑硎鰹椤霸谄渌麠l件相同的情況下,要求得越少的那個就越好,越有價值”。
應用到設計學領域,該法則認為做產品時功能上不可過于繁瑣,應該保證簡潔和工具化。例如,產品中為用戶提供了收藏功能是否就不再需要喜歡?提供了喜歡是不是不再需要收藏?一定要保證功能上的克制。不必要的設計元素會導致使用效率降低,還會增加不可預知的后果。建議在不損及功能的前提下,干掉多余的元素,當兩個設計方案都能達到設計目的時,選擇較為簡單的那一個有利于更好地傳達內容更好地用戶體驗。
總的來說,我們可以結合《簡約至上》一書中提到的刪除、組織、隱藏、轉移四個策略來將復雜的設計和體驗變得更加簡單。
刪除:關注核心,讓用戶注意力集中在自己要完成的目標上,刪除不必要的功能、流程和造成視覺混亂的元素等;
組織:繁瑣的功能通過分塊,被組織成清晰的層次結構。還記得我們前面說到的“7±2法則”嗎,把項組織到7加減2個塊中;分塊越少,選擇越少,用戶負擔約輕;
隱藏:隱藏那些主流用戶很少使用,但自身更新需要但功能。通過漸進展示和適時出現的方法減少干擾;
轉移:把合適的功能轉移到合適的設備上去。讓用戶感覺簡單的一個重要前提,就是先搞清楚把什么工作交給計算機,把什么工作留給用戶。
小測試,下列飲料中哪一種給你印象最深刻呢?文末揭曉。
可口可樂、雪碧、芬達、嶗山可樂、7喜、美年達
雷斯托夫效應又稱隔離效應(isolation effect),以及新奇效應(novelty effect),前蘇聯心理學家馮·雷斯托夫認為,某個元素越是違反常理,就越引人注意,收到更多的關注。
一樣東西與以往經歷明顯不同就產生了經歷差異。比如人生中的很多第一次,第一次高考、大學的第一天、初戀、第一份工作等等。該差異也會出現在新奇面孔、電話號碼記憶中。奇特的面孔和特殊的電話號碼更能被人記住。
該理論以多種不同的方式應用到設計中,最明顯的就是如果想要突出某個重點內容,就要使它特殊化,通過色彩、尺寸、留白、字體粗細等設計手段。利用對比來凸顯想要表達的重要信息。例如金剛區、tab欄的運營活動廣告,特殊化的設計讓它們在背景中脫穎而出。
個人中心的會員卡為了吸引用戶注意,增加開通率,都成了重點設計對象。
與以往不同的界面設計可以更加的吸引用戶,加深用戶的記憶,同時擴大了活動對用戶的影響力。例如每年淘寶的雙11首頁設計都與往常不同。
Google doodle 會在一些比較特殊的日子改變 logo 的設計,把logo設計成與這個日子相關的插畫或涂鴉,與平時的 logo 形成差異化,幫助人們更好地記住這個日子。
因此我們在界面設計中,若想讓用戶對哪個模塊或者是元素引起注意或點擊,就可以打破常規對該元素進行強調設計,使他在背景中脫穎而出。但是不要任何元素都強調,因為什么都強調就等于什么都沒強調,就沒有重點,所以要謹慎使用這個方法。
回到開篇的題目,答案是「嶗山可樂」。相比其他飲料,嶗山可樂遇到的少,反而成了最特別的一個了。你的答案是什么?歡迎在下方留言探討。
食之無味,棄之可惜
損失厭惡是指人們面對同樣數量的收益和損失時,認為損失更加令他們難以忍受。 同量的損失帶來的負效用為同量收益的正效用的2.5倍。比如,丟100塊錢的痛苦感要遠高于你撿到100塊錢帶來的幸福感,也就是說要至少撿到300塊才能平復之前的心情。
生活中類似的栗子還有很多,比如旅游時,雖然這個景點很爛,人們依然覺得來都來了,還是要看完再走才“不虧”;吃自助餐時,明明吃不下那么多,可想到花了那么多錢,就要盡可能的多吃才算“回本”,真是應了那句話:“食之無味,棄之可惜”;花了50塊買了張電影票,過了10分鐘發現是部爛片,就算在電影院睡覺也不愿提前走,覺得這50塊錢不能白花...
那么,該如何將“損失厭惡”賦能給產品設計呢?
最典型的莫過于電商App中的各類券滿天飛,比如:買二送一、3件7折、倒計時xx小時后恢復原價等等。商家就是為了營造現在不買就會錯過的套路,用戶也會覺得失之可惜。一年一度的天貓雙11,京東618,還有情人節、中秋節等各種有的沒的節日都是商家利用“損失厭惡”心理為基礎刺激消費。
我們App的用戶粘性不太理想,增加一個“簽到”功能吧,產品經理如是說。如是我們看到各種簽到得禮品,贏紅包等活動。中間還不能中斷,要連續簽到多少天才能得到獎勵,用戶也擔心中斷的損失。
某網盤下載文件時,會給你一個10秒VIP高速下載的體驗,計時過后又恢復到龜速,讓你恨的牙癢癢。雖然這招有點損,但用戶體驗到了VIP的快感,很多人還是會乖乖成為付費會員。
產品運營中會經常發一些優惠券,雖然知道自己不會用,也要先領了再說。這些券也都有時間限制,快過期的提醒也會加快用戶決策。還有0元開通會員,套路是第一個月免費,次月開始按正常價自動續費,典型的“騙”進來養肥了再“殺”。
人天生會對危險的,不好的東西避而遠之。如是我們就看到保險行業,他們會用一些負面信息(空難、車禍)刺激你,用戶就會產生焦慮,自然就想規避掉這些概率小的風險。例如購買機票時的意外險,QQ退出登錄時的提示。
還有就是有用戶自己的內容的東西,一般不會輕易舍去。拿我個人來說,飛書一直是我的寫作工具,后來看到幾個更好用的軟件,但要想到把原來的這么多東西全部轉移過去也是件很心累的事,太麻煩,還是繼續用飛書好了。QQ這個“古老”的軟件,估計很多人好久都沒打開過了吧,但是讓你刪了它,你還是不愿意的,因為那上面有很多青春的回憶。
用戶會將大部分時間花在其它網站上,因此他們會希望你的網站也能像他們已經掌握的其它網站一樣,擁有相同的使用模式和習慣。
Jakob定律是由Jakob Nielsen提出的,他認為用戶在其他網站所積累的經驗教會了他們如何使用網站,所以他們會希望你的網站可以與那些熟悉的網站一樣,相似的使用方式,在使用你的產品、服務、內容和信息的時候,他們不會感到恐慌,而是輕車熟路。該原則鼓勵設計師遵循常見的設計模式,以避免混淆用戶或導致更高的認知成本。
例如YouTube2017年改版前后的對比,在新版中,網站框架和功能上幾乎沒動,只是在UI上做了順應新的設計準則,比如調整字體大小、顏色、欄目間距等。整體上和舊版沒太大區別,而且還給用戶提供了舊版的選擇。
在移動端App中也應如此,在具有相同功能的頁面,盡量保持一致。大到頁面底層框架(比如電商應用中的購物流程),小到UI設計中的一個按鈕,一個圖標,甚至一句微文案。
在設計產品時,要先延續大眾早已習慣的概念模型。然后再從自己的產品出發,對其進行改善。而不是從零開始制定自以為是的流程。
日常使用的各類修圖軟件,版式都高度相似,中間是圖片,各種濾鏡、貼紙、調整等功能都放在底部操作區域,很多相同功能的名稱都一樣。這是用戶最熟悉的布局,可降低用戶在同類軟件使用的學習成本提升使用效率。
也許你會質疑當所有產品都遵循相同都設計模式,會讓產品同質化嚴重,答案是必然的。此時需要深入了解用戶的目標和心智模型(用戶訪談、用戶畫像、用戶體驗地圖等),并將其應用到我們的產品設計中去,縮小我們與用戶心智模型之間的差距,從而獲得良好的用戶體驗。上文YouTube例子中,就是通過簡單的用戶授權(新舊版本選擇),避免了心智模型的不一致會帶來的問題,當用戶準備好隨時可以切換到新的版本。相反的案例Snapchat在18年設計改版時,因為新的布局未能確保改版前后用戶心智模型的一致性,導致大量用戶流向競爭對手Instagram那里了。
但是也要注意設備之間的差異,比如在移動端“漢堡包”式菜單是個不錯的方案,可是放到桌面端可能并不太友好,因為大屏幕可視范圍更大,小小的漢堡包圖標很容易被忽略,這時候平鋪出來可能會更好。
思考總結
1、用戶會把在其他產品使用中已熟悉的操作習慣轉移到另一個看起來相似的產品上;
2、利用現有的思維模型,使用戶可以專注于自己的目標上,而不是學習新的操作方式;
3、在進行必要的改版時,請給用戶過渡到新版本的機會,即可以選擇短時間內繼續使用舊版本;
看名稱挺拗口,另一種翻譯叫做“對角線平衡的和諧狀態”。它告訴我們瀏覽頁面是由左上至右下的視線流,左上角是視覺第一落點區,右下角是視覺最終落點區,因此右上角和左下角都是一個強烈的視覺盲點區,大多數時容易被忽略。
在進行信息排布時,將最重要的信息放在左上角,右上角和左下角添加輔助元素,右下角作為整個視覺落點可以展示重要操作。運用視覺元素來創建一條虛擬的“線”,讓用戶的視線跟隨左上到右下這條對角線移動,符合用戶習慣性的眼動規律。
古騰堡圖表應用最典型的例子就是商品詳情頁,在界面的頂部展示商品圖片、名稱、價格、快遞和優惠等用戶主要關心的信息;右上和左下通常是分享、客服和收藏等次要信息;右下角則放置最終促成用戶交易的購買按鈕。
我們都知道一般頁面按鈕都在界面底部是因為離手近,方便操作,但不僅僅如此。還因為瀏覽是用戶的第一行為,他們的視線會根據頁面元素進行移動,最終停留在底部結尾的地方。
看各種社交產品評論、點贊的位置,就知道產品希望用戶先干什么的想法。
彈窗的按鈕擺放一般都是左「取消」右「確認」,目的是讓用戶最快地看到主要操作內容。
余額寶的「轉出」在左,「轉入」在右,畢竟誰也不想財往外流是吧。
既然如此,為什么“發布”頁面的按鈕都在右上角呢?因為發布頁是屬于“編輯頁面”,需要用戶謹慎操作,這里關注的核心應該是可編輯內容區域,而不是按鈕本身。
類似的例子還有很多,設計中與此視覺流與節奏規律相似的還有F型布局和Z型布局,合理運用這些節奏模式,使用者會跟隨你“設計”的視覺流和運動規律來瀏覽頁面,有效提高用戶閱讀的節奏和理解能力。
美國心理學家亞伯拉罕·馬斯洛(Maslow.A.H.)從人類動機的角度提出需求層次理論,該理論強調人的動機是由人的需求決定的。他將人類需求分成生理需求、安全需求、社交需求、尊重需求和自我實現需求,依此由低層次到高層次的過程。馬斯洛需求層次理論最大意義就在于,它告訴了我們,人在滿足了基本的需求之后,就要去實現更高的需求和目標。
馬斯洛需求層次理論有兩個基本出發點,一是人人都有需求,某層需求滿足后,另一層需求才出現;二是在上層需求未獲滿足前,首先滿足迫切需求,該需求滿足后,后面的需要才顯示出其激勵作用。例如,在能感受到愛之前,他們的生理和安全需求一定要得到滿足。
回歸到產品,一款產品,最核心的是解決用戶的需求。馬斯洛需求層次理論,為產品的需求分析指明了方向。
生理需求:滿足人的最基本需求,如衣、食、住、行、生理方面的需求。諸如美團外賣、淘寶、馬蜂窩等為日常生活提供方便的應用;
安全需求:人生安全、財產保險,也是強需求。如是各類投資理財軟件層出不窮。
社交需求:包括友情、親情、愛情多個層次,滿足人類社會關系,讓每個人不再是孤單的個體。如是微信、微博、Soul、探探、陌陌等不同類型的社交軟件多如牛毛;
尊重需求:每個人都有被尊重的需求,都希望展現自己,獲得人們認可。此需求可以深度結合在社交需求中。
自我實現:最高層級的需求,完成與自己的能力相稱的一切事情,實現自己理想的需要。結合到產品可以理解為能滿足自己外在展示(炫耀)的需求,如各類美顏軟件,美化后的照片曬到朋友圈,給人看到最好的一面。
由此規律可以看出,越靠近底層需求越是剛需,越往上,就變得越來越不必要,如自我實現,變得可有可無,不再是所有人的剛需。一個優秀的產品,深諳人性滿足用戶核心需求,才能形成持續穩定高用戶粘性的產品。
序列效應法則又叫系列位置效應,是指一種記憶現象: 在列舉項目時,排在最前面與最后面的元素,要比排在中間的更容易讓人記住。
因為人們對排在頭、尾的項目,要比排在中間的更容易記起來。比如我們都知道第一位登上月球的宇航員是阿姆斯特朗,卻很少人知道第二位奧爾德林;班級里我們一般都知道成績最好的第一名和倒數第一名,至于排在中間的很難記住。因此對排在開頭的項目產生加強的回想效果,稱為“首位效應”( primacy effect)。對排在結尾的項目產生加強的回想效果,稱為“近因效應”( recency effect )。
分類頁簽中,我們通常都會記得“精選”、“熱門”這類標簽,是希望給用戶進入App后看到的主要內容。這就是“首位效應”,把重要性高的內容放在首要位置。
我們都知道界面中“返回”按鈕放在左上角,除了操作習慣和防誤觸外,還因為它出現在頁面左上角最開始的地方,更長久地儲存在長期記憶之中,需要“返回”時能夠快速回憶出來。
tabbar數量不管是3個還是5個,用戶通常都會記得第一個“首頁”和最后一個“我的”,對排在中間的都會選擇性的忽略掉。
有時候新上一個功能,產品想提高它的位置引起用戶注意,會和“我的”互換位置。例如網易云音樂,新版本中把“我的”放在第三個tab,為了提升“云村”重要性,把它放置最后一個tab,正是利用了“近因效應”。
近因效應常用于及時進行反饋的設計界面中,比如點贊、評論、分享等功能置于底部不僅可加深印象,同時用戶在看到有趣的內容,想要評論或分享時,不用等到文章看完即可操作。從而增強內容粘性,提高互動率。
用戶的記憶具有系列位置效應,而且人的短期記憶非常有限,通過序列效應法則的應用,我們可以幫助用戶減輕記憶負擔。在排列項目時,把重要的放在首位或末尾,以達到最好的記憶效果。
文章來源:站酷 作者:Fyin印跡
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
1.Object.defineProperty(obj,prop,descriptor)這個語法內有三個參數,分別是obj(要定義其上屬性的對象) prop (要定義或修改的屬性)descriptor (具體的改變方法)
2.簡單的說 就是用這個方法來定義一個值。當調用時我們使用了它里面的get方法,當我們給這個屬性賦值的時候,又用到了它里面的set方法
var obj = {}; Object.defineProperty(obj,'hello',{ get: function(){ console.log('調用了get方法') }, set: function(newValue){ console.log('調用了set方法,方法的值是' + newValue); } }); obj.hello; // => '調用了get方法' obj.hello = 'hi'; // => '調用了set方法,方法的值是hi'
原文來自于這里,我說一下我自己的理解,其實發布-訂閱模式和觀察者模式很像,但是不同的是,觀察者模式只有兩個角色,而且Obsever是知道Subject的,但是在發布-訂閱模式中,他們兩卻彼此不了解,他們是在一種類似于中間件的幫助下進行通信的,換句話說,還有第三個組件,稱為代理或消息代理或事件總線,Observer和Subject都知道該組件,該組件過濾所有傳入消息并相應的分發他們。
<input type="text"> <p></p>
我們要對上面兩個DOM元素實現雙向數據綁定,就是當輸入inputValue時下面的p可以及時更新inputValue內容
<script> let input = document.querySelector('input') let p = document.querySelector('p') let obj = {} let value = '' Object.defineProperty(obj, 'inputvalue', { get() { return value }, set(newValue) { input.value = newValue
p.innerHTML = newValue } }) // 訂閱者 DOM元素 input.value = obj.inputvalue
p.innerHTML = obj.inputvalue // 監聽輸入的事件 input.addEventListener('keyup', function (e) { // 修改inputvalue 達到修改input.value 以及input.innerHTML // 發布者 obj.inputvalue = e.target.value // 觸發了set }) </script>
所以在我們的代碼中,訂閱者就是頁面中的DOM元素,因為他會訂閱我們的inputvalue,而發布者就是監聽事件中的數據,一旦監聽到了數據有修改,就要發布給我們的訂閱者,也就是說輸入的數據一旦發生了變化,我們的頁面DOM元素的數據也會發生變化,所以這個中間件就是Object.defineProperty中的set方法
轉自:csdn 論壇 作者:Y shǔ shǔ
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
藍藍設計的小編 http://www.syprn.cn