<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>

          首頁

          vue 前端解決跨域問題 —代理

          前端達人

          前言
          跨域問題來源于JavaScript的同源策略,即只有 協議+主機名+端口號(如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源,主要是安全問題。

          在很多時候跨域問題我都是讓后端解決,嘿嘿。但也有需要自己解決的項目!

          1. 首先在項目的根目錄下建一個vue.config.js

          2. 如下:

          3. //改變webpack的設置
            
             const { default: Axios } = require("axios")
            
             module.exports = {
                 publicPath :"./",
                 devServer: {
                     // 設置主機地址
                     // host: 'xxx.1xx.1xx.xxx',
                     // // 設置默認端口
                     // port: 8051,
                     // 設置代理
                     proxy: {
                         '/api': {
                             // 目標 API 地址
                             target: 'http://xxx.xxx.xxx.xxx:8051',//服務器地址
                             // 如果要代理 websockets
                             ws: true,
                             // 將主機標頭的原點更改為目標URL
                             changeOrigin: false
                         }
                     }
                },
                chainWebpack: config => {//沒有用到scss的這里就不需要啦!
                   const oneOfsMap = config.module.rule('scss').oneOfs.store
                    oneOfsMap.forEach(item => {
                      item
                         .use('sass-resources-loader')
                         .loader('sass-resources-loader')
                         .options({
                             // 要公用的scss的路徑
                             resources: './src/assets/base.scss'
                         })
                         .end()
                       })
                   }
               }



          轉自:csdn 論壇 作者:可 樂 伢


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


          IDEA2021 tomcat10 servlet 較新版本 踩坑記錄

          前端達人

          因為學習的時候用的版本比較新,而網上的教程又全是老版本,所以出現了很多問題,總結以下,幫同樣初學的師傅們踩坑了。
          廢話不多說:

          1:
          file->new->project新建一個普通java項目:
          工程名可以隨意命名

          2:
          工程名上右鍵->Add Framework Support:

          在Web Application上打勾,點擊OK

          3:
          展開工程名->web->WEB-INF,在WEB-INF下新建兩個文件夾,分別是classes、lib:

          4:
          按下ctrl+alt+shift+S,調出Project Structure,
          選到Modules->Paths,單選框選到use module xxxxx,將兩個路徑改為剛才創建的classes。
          然后選到Dependencies,點擊下面的+號,選擇jars or dirxxxxxxxx,選擇剛創建的lib目錄,讓選擇目錄用處的話,選擇jar direxxxxxxx,打上勾,點擊apply,OK

          5:
          將tomcat/lib目錄下的servlet-api.jar復制到我們創建的lib目錄里。

          6:
          點擊右上角小錘子旁邊的Add Configuration,點擊加號,選擇tomcat server->local。這里注意不要選成tomEE的,兩者圖標一樣,但是不是一個東西。其他配置不變,點擊aplly上面的fix,application context可以隨意命名,建議一個/就可以。然后aplly,OK。

          7:
          改一改index.jsp中帶的title和end,運行一下,如果類似以下,那基本就OK了。

          8:
          在src里面新建一個java class,嘗試寫一個servlet:
          這里也是與其他版本不同的地方,老版本都是import javax.servlet.xxxxx,這里是import jakarta.servlet.xxxxx,具體應該import的包,可以展開servlet-api.jar看到。
          在這里插入圖片描述

          import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "login") public class Login extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML>"); out.println("<HTML>"); out.println("  <HEAD><TITLE>login</TITLE></HEAD>"); out.println("  <BODY>"); out.print("    this is login page"); out.print(this.getClass()); out.println("  </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML>"); out.println("<HTML>"); out.println("  <HEAD><TITLE>login</TITLE></HEAD>"); out.println("  <BODY>"); out.print("    this is login page"); out.print(this.getClass()); out.println("  </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45

          然后修改web.xml文件,如下:
          servlet-name可以任意命名,只要上下兩個一致就可以,servlet-class應該與類名相同,url-pattern是與java class中的@WebServlet(name=“xxxx”)的xxxx相同,這里的xxxx就是路徑。
          此時編譯并運行,在地址欄輸入我們寫的url,就可以訪問到動態資源了:

          全篇結束,只是記錄踩坑,希望能對大家有幫助。


          轉自:csdn 論壇 作者:Hausa_


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

          [收錄量]史上最全的百度索引量下降原因分析及解決方案

          seo達人

           

              索引量是流量的基礎,索引量數據的每一個變動都撥動著站長敏感的神經,“索引量下降之后該如何著手分析”一直是各位討論的熱門話題。這次快排科技(vx:seokuaipai)孔宇又拔刀相助了,看看史上最全的百度索引量下降原因分析及解決方案吧。
              一、百度索引下降分析簡圖
          百度索引下降分析簡圖
              二、導致百度索引量下降的常見原因--網站方原因
              1、內容數據所在的網址url未規范統一:
              1.1:自己站點url規范統一:多域名都可以200狀態正常訪問網頁內容;一域名下出現多種url形式可以訪問相同內容,如大小寫url、url規則變更等。
              解決方案:選擇主域名(或主url),其他域名下的所有url都301重定向到主域名(或主url),并站長工具提交域名改版(或目錄url改版)
              1.2:外部平臺使用己站數據::
              Ⅰ、市場合作,站點數據調用到其他平臺上;內容主動外發,推廣人員完整轉發自有內容到高質量平臺--這兩個原因都有可能導致搜索引擎收錄了外部平臺的內容而拒絕了原網站內容;
              解決方案:使用站長平臺鏈接提交工具的主動推送功能,及時提交網站新出現的鏈接,延遲將內容調用到其他平臺的時間;
              Ⅱ、被鏡像,用戶通過其他舉辦主體的域名或url直接可訪問己方內容。
              解決方案:關注域名解析安全和服務器安全;綁定唯一可解析的域名或唯一可訪問的url;頁面內容中鏈接使用絕對地址;
              2、站點受青睞度下降:
              2.1:網頁內容相關
              Ⅰ、內容質量度下降
              解決方案:提高內容質量度,詳見百度站長學院相關內容;杜絕簡單拷貝,多做整合信息。
              Ⅱ、更新量及頻率下降
              解決方案:穩定的更新頻率,視內容發展情況,擴充編輯團隊,生產更多新內容,讓網站索引避免下降,持續增加。(當更新量及頻率下降明顯,那么配額就會下降,首先表現抓取頻次下降,導致索引量下降)
              Ⅲ、時效性信息消失
              解決方案:時效性的信息,大部分一般在數據庫不會長期保留,所以需要持續挖掘新的時效信息點,整合相關內容。
              Ⅳ、部分區域出現不良信息
              解決方案:杜絕大量外鏈軟文、惡劣彈窗廣告、非法敏感類信息、專門針對搜索引擎作弊的內容等
              Ⅴ、觸犯懲罰算法
              解決方案:關注站長工具消息和百度網頁搜索動態。按官方公告說明來整改站點,并進行反饋,然后等待算法更新。
              Ⅵ、特型url不被信任
              解決方案:定制各類url的索引查詢規則;定位索引量下降的特型url;排查該類url當日、前一日、本周、歷史索引情況;找出未被入庫的數據可能存在的問題;處理完后,增強該類url與百度數據溝通(途徑有sitemap、批量提交url、數據推送等)。
              2.2:站點被搜索引擎信任度下降
          鏡像
              Ⅰ、非法投票嫌疑(鏈接工廠等)
              解決方案:珍惜自己頁面的投票權,對于劣質網頁堅決不投票,盡量減少站點的導出鏈接。
              Ⅱ、主題變動(如從教育領域跨入醫療領域)
              解決方案:將舊領域的網頁進行死鏈處理后向百度進行提交,封禁相關舊url的被訪問權,然后再上線新主題相關內容,加強對百度的數據提交
              Ⅲ、受牽連
              相同ip下非法站點偏多,同一域名所有人舉辦的網站大都被懲罰且情況惡劣等
              解決方案:離開惡鄰,獲取搜索引擎的各產品的相關反饋方式,請求給予解禁,等待恢復正常索引。
              Ⅳ、政策性原因
              如香港主機、國外主機站點由于各種你懂的原因,穩定性可能較差
              解決方案:國內主機備案,合法符合政策經營
              3、網頁模板相關
              3.1:主體內容區域對蜘蛛的限制:
              解決方案:取消登陸查看信息等限制,讓蜘蛛便捷暢快的“采集”到己站數據
              3.2:啟用了對蜘蛛不友好的技術:
              解決方案:對需要蜘蛛識別的內容,不要啟用對蜘蛛不友好的技術來調用。
              3.3:響應式模板干擾蜘蛛識別頁面類型(pc、移動):
              解決方案:提交特定的url對應關系(盡量parrten級);meta標記移動版本url及適合瀏覽的設備;自主適配;增強pc、移動不同模板源碼標簽的區分度,幫助百度識別頁面類型
              4、源碼相關
              源碼錯誤較嚴重,如編碼錯誤、標簽使用錯誤等;源碼改動嚴重,蜘蛛“采集”數據后重新觀察分析;某類url下的TD(網頁title、description)變化,如變化比例大、變化頁面量大,頁面進行更改后會重走建索引庫流程,如果頁面質量達不到建索引庫標準會從線上消失
              解決方案:校驗源碼,準確的源碼是蜘蛛“采集”數據進行分析的基礎;link內鏈結構、url地址形式、頁面主題、頁面各區域html標記等盡量維持改動前的情況;逐步、分期更換TD(網頁title、description),結合頁面主題、用戶實際需求來制定合理的TD,不欺騙不誤導用戶。
              5、已入庫的url對蜘蛛狀態有變化
              5.1:robots聲明,禁止蜘蛛抓取
              解決方案:查看百度站長工具robots及抓取情況。
              5.2:url規則變化,原有url無法訪問:
              解決方案:特別是linux和win服務器之間的數據遷移,可能會出現大小寫url支持變化,確保各類url規則不變化。url必須重構的時候,做好舊新url301重定向,站長工具提交改版需求。
              5.3:提示錯誤頁面:
              解決:由于誤刪,則可以數據恢復,并維持url對應網頁內容的更新變化,提高抓取頻次。如果確定要刪除,那么提交死鏈,刪除死鏈后,再robots禁止,這種情況的索引下降無需擔憂。?
              5.4:被入侵:
              解決方案:防止url對蜘蛛進行非法跳轉操作;防止url對應的網頁內容對蜘蛛出現內容大變化,特別是一些違法亂紀的內容
              6、DNS、服務器問題
              6.1:DNS問題:dns不穩定;dns不安全
              解決方案:選擇可靠的dns服務;溝通強調對蜘蛛的穩定性;防止dns解析到非正常ip;防止解析的網站ip頻繁變動。防止dns管理漏洞,導致被惡意解析;防止dns解析掛靠在小代理等技術能力、管理規范、道德法律約束都欠缺的平臺上。
              6.2:服務器問題
              Ⅰ、可訪問性差
              解決方案:盡量讓目標地區所有運營商來路的用戶都能在3秒內打開網站,最佳1秒內;監控網站運行狀態,合理設置目標地區的所有運營商監控節點及監控項目、監控頻率
              Ⅱ、屏蔽百度ua或ip
              解決方案:多利用百度站長工具,查看百度抓取網頁的情況,可見
              Ⅲ、bbs.zhanzhang.baidu.com/thread-15392-1-3.html
              Ⅳ、防刷壓力值設定
              解決方案:將蜘蛛解析到專用空間;如出現訪問陡增的ip,查看是否為蜘蛛再確定是否禁止訪問。
              三、導致百度索引量下降的常見原因--百度方原因
              1、配額再分配
              同類數據量接近索引分配總額,配額量再分配,有升的就會有降的
              解決:超過競品,爭取高額分配。
              2、數據異常錯誤
              Ⅰ、錯誤懲罰:應對某類作惡行為而新算法上線,但由于蝴蝶效應,導致部分站點被錯誤懲罰而清除大量索引。
              解決方案:反饋百度方,請求解除懲罰。
              Ⅱ、地區性數據異常:部分地區數據抓取或查詢異常,導致誤判站點情況而清除相應索引數據或輸出錯誤索引量,如百度dns系統升級事件。
              解決方案:反饋百度方,由百度檢查各地蜘蛛執行情況。
              Ⅳ、接口調用數據錯誤、數據丟失、數據備份衍生異常
              解決方案:反饋百度方,由百度檢查相關數據情況。
          文章來源:快排科技

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

           

          GDP“報復性”增長!豬肉價格“報復性”下降!

          seo達人

           

          中新網客戶端北京4月16日電(記者 李金磊)16日,中國一季度經濟數據出爐,中國經濟取得開門紅,GDP、消費、投資、出口等主要指標呈現兩位數的增長。同時,就業物價等民生指標總體穩定,豬肉價格出現“報復性”下降。

          4月16日,國新辦召開一季度經濟數據發布會。<a target='_blank'  >中新網</a>記者 李金磊 攝
          4月16日,國新辦召開一季度經濟數據發布會。中新網記者 李金磊 攝

          一季度GDP同比大增18.3%

          國家統計局數據顯示,初步核算,一季度國內生產總值249310億元,按可比價格計算,同比增長18.3%。

          18.3%,兩位數增速,這個數字非常漂亮,在外界看來,這可謂是“報復性”增長。

          不過要看到,增速的大幅反彈,主要是受到上年較低基數、員工就地過年工作日有所增加等不可比因素影響。

          受到疫情的影響,2020年一季度GDP出現了負增長,同比下降6.8%。此后,中國經濟在全球主要經濟體中率先恢復正增長,2020年全年增長2.3%。

          數據顯示,2021年一季度GDP比2020年四季度環比增長0.6%;比2019年一季度增長10.3%,兩年平均增長5.0%,這表明我國經濟穩定恢復。

          資料圖。張艦元 制圖
          資料圖。張艦元 制圖

          主要經濟指標取得兩位數增速

          從消費、投資、出口等主要經濟指標來看,同比均取得了兩位數的增幅。

          具體數據顯示,一季度,社會消費品零售總額105221億元,同比增長33.9%;全國固定資產投資(不含農戶)95994億元,同比增長25.6%;貨物進出口總額84687億元,同比增長29.2%。出口46140億元,同比增長38.7%;進口38547億元,同比增長19.3%。

          從季度環比看,主要指標繼續保持增長,一季度規模以上工業增加值比上年四季度環比增長2.01%,社會消費品零售總額環比增長1.86%,固定資產投資環比增長2.06%。

          從兩年平均的增速看,一季度國內生產總值兩年平均增長5%,規模以上工業增加值兩年平均增長6.8%,社會消費品零售總額兩年平均增長4.2%,固定資產投資兩年平均增長2.9%,貨物進出口總額兩年平均增速也接近10%。

          “所以,綜合這些指標來判斷,可以說,總體經濟處于穩定恢復的狀態中?!眹医y計局新聞發言人劉愛華16日在新聞發布會上說。

          再來看收入、就業、物價等民生指標,總體上是收入漲、失業率降、物價持平的態勢。

          ——居民收入繼續增加

          數據顯示,一季度,全國居民人均可支配收入9730元,同比名義增長13.7%,兩年平均名義增長7.0%;扣除價格因素同比實際增長13.7%,兩年平均增長4.5%。

          按常住地分,城鎮居民人均可支配收入13120元,同比名義增長12.2%,實際增長12.3%;農村居民人均可支配收入5398元,同比名義增長16.3%,實際增長16.3%。全國居民人均可支配收入中位數8014元,增長12.7%。

          企業效益的改善為居民收入增加奠定了基礎。在企業利潤方面,1-2月份,規模以上工業企業利潤總額同比增長1.79倍,兩年平均增長31.2%;規模以上服務業企業扭虧為盈,實現利潤總額達到了1690億元,上年同期是虧損的。

          招聘會資料圖。<a target='_blank' >中新社</a>記者 武俊杰 攝
          招聘會資料圖。中新社記者 武俊杰 攝

          ——城鎮調查失業率下降

          就業是民生之本。一季度,全國城鎮新增就業297萬人,完成了全年預定目標任務的27%。

          3月份,全國城鎮調查失業率為5.3%,比2月份下降0.2個百分點,比上年同期下降0.6個百分點。

          不過,劉愛華提醒,3月份16-24歲年輕人的調查失業率是13.6%,比上年同期上升,說明年輕人就業還面臨一定的困難。這可能和春節節后大量年輕人進入勞動力市場,帶來摩擦性的失業有關系,一定程度上可能也反映了就業市場在趨于活躍。但年輕人就業問題的解決還需要一段時間的消化,這方面總量的壓力確實是存在的。

          圖為4月9日,山西太原一超市,消費者在選購豬肉。<a target='_blank' >中新社</a>記者 張云 攝
          圖為4月9日,山西太原一超市,消費者在選購豬肉。中新社記者 張云 攝

          ——豬肉價格大幅下降

          從物價看,一季度居民消費價格同比持平,其中3月份由上月的下降0.2%轉為上漲0.4%,漲勢比較溫和。

          近日多地豬肉價格重新回到了十幾元的時代。劉愛華稱,在一系列保供穩價的措施作用下,生豬產能得到了顯著恢復。今年一季度,生豬存欄同比增長了29.5%,連續六個季度環比增加。在生豬產能恢復的作用下,個別地區豬肉價格回落比較多,從全國居民消費價格來看,3月份當月豬肉價格同比下降18.4%,環比也是下降的。綜合生產、供應改善的情況來看,豬肉價格進一步回落是有基礎的。

          劉愛華稱,另外一方面,糧食價格最近也比較穩定。今年以來糧食生產形勢比較好,冬小麥苗情是略好于往年水平的,從這方面來講,糧食安全也是有保障的。所以,不管是從豬肉價格還是從糧食價格來看,CPI上漲的壓力不大。(完)

          來源:中國新聞網 

           

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

           

          學會這 7 個技巧,畫出完美圖標

          周周

          圖標是 UI 設計中最基礎也是很重要的部分,輔助人們更好的理解功能內容。隨著扁平化設計風格的普及,圖標的風格越來越簡約,看似簡單的圖形,實際要準確的表達含義,也是需要注意一些方法的。以下是圖標設計技巧的分享內容:

          設計圖標是一個藝術創作的過程,里面也有很多需要被關注而不可忽視技巧。要知道如何設計好圖標,是對于 UI 設計師來說是不可或缺的重要技能。

          在我設計圖標的時候,我個人認為有以下7個規則:

          簡單

          一個圖標一個非寫實的表現。不需要擔心圖標不夠真實,消除不必要的細節,用基本的形狀只保留最基礎的部分,讓這個圖標更容易被理解。

          學會這 7 個技巧,畫出完美圖標

          有時候圖標會因為有更多細節而傳達了更復雜的意思,這反而是樣式問題!

          一致性

          在整個圖標系統中,你的圖標要保持同一種樣式來確保圖標完美協調。比如同樣的形狀,填充,描邊粗細,尺寸等。要制定好可以被復用的柵格,規范和樣式。

          學會這 7 個技巧,畫出完美圖標

          如果可以的話,盡可能重新設計這些圖標,而不要混入其他不同風格的圖標來使用。

          清晰

          設計「完美像素」的圖標,特別是在圖標非常小的時候。這樣圖標的描邊就可以保持銳利,不會有模糊。注意半像素的情況出現,盡量避免小數點參數。

          學會這 7 個技巧,畫出完美圖標

          這也可以幫你保持圖標的辨識度,在你等比縮放他們的時候保持清晰。

          空間

          確保你的圖標的所有形狀有足夠的空間。筆畫和空間過于狹小會使圖標更難被理解。

          學會這 7 個技巧,畫出完美圖標

          最少給2px的負空間

          視覺調整

          確保你的圖標看起來是正確的,適當的調整元素的對齊來達到視覺上的平衡。

          學會這 7 個技巧,畫出完美圖標

          不要只關注參數,如果有需要就用上你的眼睛來衡量,輕微移動這些元素。

          布局規格

          所有圖標保持同樣的尺寸,在圖標周圍定義一個可調整的內邊距范圍,盡量讓元素設計在這個范圍內。不要擠滿所有元素。

          學會這 7 個技巧,畫出完美圖標

          當圖標需要額外控件時可以超出這個內邊距范圍。

          測試驗證

          在設計階段,你的圖標可能看起來是完美的,但還是需要將圖標放到實際的界面環境中,測試他們是不是完美,有沒有可以調整的細節問題。

          學會這 7 個技巧,畫出完美圖標

          確保每個新增的圖標和其他圖標顯示一致。

          你在設計圖標過程中,有用到以上的這些技巧嗎?可以在評論區告訴我,你是怎么怎么設計圖標的。


          文章來源:優設網    作者:布萊恩臣



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



          深度解析B端導航設計-交互篇

          資深UI設計者

          一起深度用案例解析B端導航設計中的交互





          hello各位在B端奮斗的小伙伴們,你是否會時常因為面對導航多種多樣的形式從而面對需求時無從下手,你又是否因為雖然見過了很多的案例仍然不得導航設計的要領和精髓,沒關系,今天我們就一起來解決這個在B端設計中困擾我們多時的難題,從交互的角度結合案例對導航進行一個立體的剖析


          如果你準備好了那么就請系上安全帶現在就發車


          要探討一個概念那么首先需要知道的是其精準的定義,才能展開研究,而所謂的導航(Navigation)的精準定義可以闡述為:是一種對信息的分類,幫助用戶找到想要的信息、完成預期的任務



          如果你覺得這個定義很抽象,那么不妨從這個角度去理解,如果說任何界面上的功能都能夠找到在我們物理世界的隱喻的話,那么導航映射的就是我們物理世界中的路牌、導覽、線路示意圖等,因為立足于其功能而言,導航的作用用一種大白話的說法就是:告訴用戶你從哪里來,你在哪里,你可以去哪里



          由此我們對導航有了一個較為準確的把控,那么請在座的各位快速回答我一個問題,你能夠告訴我以上6個內容那些不是導航嗎?


          3

          2

          1


          OK公布答案,如果你的答案是2和6那么恭喜你,你對導航的理解是較為優秀的,2和6的名稱大家想必也不陌生那就是:菜單,但是不夸張的說日常的工作中仍舊有不小數目的一波同學搞不清楚這二者的區別,那么如何對二者進行一個有效的區分呢


          同樣是從定義來入手,參照前面我們給導航進行的定義方式,菜單就是:是一種對動作的分類和集合,

          幫助用戶快速達到某個功能,也就是說當你對菜單的某一個欄目進行點擊時會立馬生成一個具體的動作,而導航則是對信息的分類與合集






          那么明白了這點我們就可以對導航進行分類了,提到導航的分類大家一定會脫口而出一堆詞匯如:頂部導航、底部導航、左側導航、舵式導航、標簽導航、菜單導航……沒錯這的確是一種分類,但他只是導航在外觀這個維度的分類,并不是我們今天從交互、結構層去討論的重點



          而立足于結構來對導航進行分類又將是如何呢?較為科學的來說是以下幾類:

          全局導航

          局部導航

          輔助導航

          內嵌導航

          友好導航

          遠程導航

          下面我們來對這6類導航進行一步一步的具體分析


          1.1 全局導航



          所謂全局導航是指他可以覆蓋整個產品的通路,往往表現為產品的一級分類(而且大部分情況都是一級分類),他不一定包含全局信息,但是一定可以讓用戶可以去到其目標的關鍵節點


          1.2 局部導航



          所謂局部導航是指在同一個框架中,可以到這個節點上的上下級通路,他一定存在于嚴格的父子級關系中


          1.3 輔助導航



          所謂輔助導航就是提供用戶在全局/局部導航不可達到相關內容的快捷途徑(這個快捷途徑在本產品內)


          1.4 內嵌導航



          所謂內嵌導航也叫上下文導航,是指嵌入頁面自身內容的導航,通常同在上下文超鏈接、引導搜索等


          1.5 友好導航



          所謂友好導航是指它可以為用戶提供一個便利的前進途徑,在需要的時候能夠找到入口信息,通常在不需要的時候成隱藏狀態


          1.6 遠程導航



          所謂遠程導航是指不包含在產品結構中,以獨立的方式存在產品內,通常表現為網站地圖、索引表(地址選擇、品牌選擇)等


          1.7 導航的常用UI表現形式


          在從結構的層面了解了導航的基本類型之后,順便給大家提一提導航的外觀,這里并不展開說,大家需要知道的是導航的外觀使用遵循的是“同構異型”的準則,什么意思呢?同樣的結構(比如同一組數據集:商品、商品名稱、商品價格)可以嵌套進入不同的外觀如:卡片式、列表、詳情……這個視具體的業務情況、使用場景而定



          常用的導航外觀基本分為以上七種外觀即:菜單欄、樹狀表、頂欄、選項卡、面包屑、文字鏈接、步驟





          知道了導航的結構分類和使用場景,那么不妨來給大家一些關于導航本身的小貼士作為原則參考解決大家在實戰中的一些問題


          2.1 導航盡量扁平、保持穩定就算要多一次點擊



          對于B端產品來說穩定相當重要!因為B端產品對于用戶來說使用和學習成本、門檻較大,如果你很頻繁地對其路徑進行修改調整,用戶就會因為產品不符合操作的習慣、心智模型對產品很容易滋生負面情緒,對于產品本身來說這樣的傷害是需要盡量避免的


          2.2 最好便于拓展



          還是從穩定的方面來說,我們需要保證的是導航的變化不會因為產品的變化而發生很大的變化,舉個很簡單的例子就是當我們的產品的功能增多時,尤其是二級導航的項目增多,導致原來如果是橫向布局的導航不得不改成縱向布局的導航,這就所謂的因為產品的變化發生很大的變化,所以在選擇導航布局的時候就需要打下一個很好的基礎便于日后的拓展


          2.3 清晰可見,操作易懂



          這是站在一個外觀和交互共同的層面去看,導航的大小一定要足夠,而且其位置一定要是用戶認為足夠清晰的,確保在視覺反饋的的層面對于用戶來說是友好的,其次就是所有的可交互區域需要有積極的響應,與內容區要有對比,可以將其稱為界面的熱情度,這也是一個優秀界面的自我修養


          2.4 導航項可以重復



          一個頁面中允許出現兩個主導航,同一個界面中允許出現兩個同樣的導航項,并不是說一個項在導航中只能夠出現一次,并沒有那么死板


          2.5 不要讓用戶有驚喜



          這對于To B 的設計來說十分重要,不同于To C的產品,B端產品的一個重點就是要符合用戶的預期,所以我們一定要避免“因為有趣所以這設計”這個思路


          2.6 導航的反饋需要保持一致



          界面上面所有的界面編排,所有的組件,所有的控件,所有的模式都是可以找到隱喻的,比如文字鏈和帶“跳轉”的文字鏈,它代表的隱喻是不一樣的,所以我們就需要賦予其不同的外觀和交互響應對應戶進行反饋


          2.7 導航不一定是有層級關系的



          回到最初導航的定義,它的本質是對信息進行分類,讓用戶快速完成任務,這也是導航的本職工作,很多時候不一定要拘泥于這個項目它應該嚴格存在于哪個層級之中這樣的思路進行設計,而是根據用戶的需求,如何將這個項目合理的分類于最適合的集合之中


          2.8 按權重布局的三種導航樣式



          這是一個立足于外觀的點,根據大量的案例分析和眼動測試,目前市面上最為常見的按照信息權重布局的導航可分為:橫向式、縱向式、縱橫式,由于這部分我們不展開說,所以直接在上圖整理了每種布局的特征、優劣勢和應用場景






          知道了上面的分類和注意事項之后,下面我們用一個具體案例來對導航的交互層面設計進行一個深度體驗(因為此內容十分精彩也涉及到機密,所以不在這里做具體展示,以示意的方式來敘述),總共分為六步,看看這是否也是你工作場景中比較頭疼的呢


          3.1 搞清楚每一個導航項的定義


          需要搞清楚導航項的定義是因為導航項的定義決定了你的目標界面是什么,所謂的目標界面就是導航所引導你到的哪一個分類的信息處



          所以我們首先先來整理一下導航中每個導航項的界面定義,這也是我們日常工作中對導航梳理十分重要的一步



          當問題被羅列出來之后我們就會自然而然的產生各種各樣的疑問,比如導航分類之間存在有的存在流程上的關系,但是有的分類卻并不屬于流程,這是為什么呢?再比如有的導航分類和導航項之間名字一樣但內容卻不一樣這又是為什么呢……(想一想這是不是我們工作中也經常遇到的疑問呢)這都是后面我們需要去優化的地方


          3.2.搞明白用戶的使用路徑


          保留住上面的問題,我們來做第二步,這一步我們需要搞明白用戶的使用路徑,因為這樣我們可以很好的給任務類產品做一級分類



          通過基于不同角色的用戶體驗地圖我們可以得出不同的用戶操作路徑,于是便可以很順暢的得出這一套操作流程的大框架



          基于業務中的任務鏈路推導出每一步的操作路徑,于是我們就可以將用戶的操作路徑就可以提煉為一級導航


          3.3.區分一下權限


          得出了一級導航,下面我需要角色的權限進行一下區分,這也是B端產品的必備屬性



          于是我們為每一個導航項進行了角色權限的梳理對應,那么一級導航中每個導航分類所對應的角色也瞬間一目了然,這里面多說一句,當用戶用不同權限的賬號登錄產品時,能看到不同的內容這才是一個優秀的擁有權限設計的導航


          3.4.區分一下界面數據性質


          到了這一部分對于一些完全沒有接觸過數據的同學來說理解起來可能會一些難度,我們首先需要知道的是:“相同的數據來源,可以幫我們區分界面性質,而且相同的數據來源,往往會有一組相同的界面來圍繞


          在此需要記住三個概念:

          1.元數據:數據屬性的信息,用來支持如指示存儲位置、歷史數據、資源查找、文件記錄等功能,例如一件商品、一個客戶

          2.記錄集:指定數據庫中檢索到的數據集合,例如訂單列表、發貨列表

          3.關系列表:對來描述對象和對象的關系,比如你和我是好友,你和我在同一個企業微信群



          于是我們為導航項進行數據性質的區分歸類,也就是說相同數據類型的實體往往圍繞著某個元數據并且包含系列的界面,當我們這里整理完后發現,相同數據性質的實體(這里可以理解為導航項)貌似可以歸類在一起,這是我們作為分類的一個依據



          根據相同的數據性質將導航項歸入應該歸入的二級導航中,此時不妨和最初的版本進行對比,我們的一級二級導航相對而言已經通過改版清晰了很多


          3.5.搞明白用戶的使用頻次


          這一步其實是比較好理解的,很簡單的法則:“高頻次高優展示,低頻次降低權重甚至隱藏”這是針對于二級導航中每個導航項的排布進行的設計。這里不妨把頻次由高到低量化成為:實時關注、每天關注、每月關注、很少使用、極少使用這個幾個概念,分別用五角星、三角形、矩形、圓形、菱形進行代表


          而關于使用頻次的高低甄別一般我們可以通過用戶調研和數據埋點的兩種常用方式來進行,這里并不展開講



          于是我們可以將使用頻次作為一列新的參考放入導航項的表格中,瞬間清晰明了



          根據使用頻次調整每個導航項的順序


          3.6.設計合適的導航布局



          這一步涉及的就是外觀了,不妨回顧一下2.8中對于導航的三種常見布局,根據產品的操作復雜程度等綜合需求,我們選擇了第二種形式成為最終形式




          文章來源:站酷  作者:核糖bro


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





          用左導航還是頂導航?

          資深UI設計者

          做中后臺產品的設計,基本都逃不開導航布局這個大框架。

          基于用戶的 Z 字形掃描行為,重要的導航應當選擇左側導航或頂部導航。

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          可是橫著豎著有那么大差別嗎?被人問道為什么這么選擇,該如何回答?

          今天給大家些靈感,從以下四個角度分析一下:

          • 科學角度
          • 布局角度
          • 尺寸適配角度
          • 統一性角度

          科學角度

          JR Kingsburg 曾經做過一次實驗(A comparison of three-level menu navigation structures for web design),研究 3 層導航中,哪種組合使用效率更高。

          這三層中,每一層都有橫向和縱向兩種可能性,所以實驗總共有 2×2×2=8 種對照組:

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          他為這 8 種導航布局做了不同電商原型,讓用戶來買東西,并記錄各種數據,結果發現了很多有意思的數據:

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          綜合這些數據,看起來整體表現較好都是「左上上」、「左左上」、「左左左」。

          科學雖然很嚴謹,卻缺乏靈活度,例如本次試驗的場景單一(電商購物),而且用來測試的界面未免也太簡陋了吧!

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          所以我們再從其他角度思考看看。

          布局角度

          從占據面積的角度來看,橫向導航比縱向導航省地方,因為只要細細一條就好了。

          然而,選項數量不多時橫向是可以;選項多起來,橫向導航就很擁擠了。

          畢竟縱向導航方便滾動,橫向導航很少有用戶會嘗試滾動查看的,「…」也不是什么方便的操作。

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          所以,如果確定選項少可以選橫向,不確定或者數量多建議保險起見選縱向。

          尺寸適配角度

          任何導航,都要占據屏幕不少空間,這對尺寸適配都是一件麻煩事。哪怕產品并不需要為移動端做響應式布局,只要是網頁端,就得考慮窗口尺寸的變化問題。因為設計師的 Mac 和大量用戶的 PC 甚至平板電腦之間,展示上的差異真的不小。

          橫向導航占據空間最小,同時也是最難做尺寸適配的。尤其是如果上面除了導航之外,還放有各種 logo、頭像、圖標、搜索…各種東西時。橫向導航一般都有三種狀態:展開、折疊和收起。但是縱向導航就簡單了,只需要兩個狀態:展開和收起。頂多再讓展開狀態的寬度能夠自適應變化或手動拉伸就差不多了。

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          這么看來,如果產品需要考慮很多不同尺寸適配的問題,縱向導航是最簡單的選擇,除非橫向導航的內容不多維護起來不麻煩。

          統一性角度

          我之前為了研究確定按鈕放在左邊還是放在右邊好,做了一系列實驗分析,結果得出超出我預期的結論…放哪都沒多大問題,統一就好。于是,我想這個問題也可以類比一下。

          大部分網站都是橫向導航,所以說如果產品是以網頁版為主,且用戶會經常穿插跳轉使用其它網頁,那么也使用橫向導航比較符合習慣。

          而無論 PC 還是 Mac,系統頁面的導航在左側的情況比較多,所以說如果產品是系統軟件的話,縱向導航比較符合習慣。

          用左導航還是頂導航?我從這4個角度做了一個完整分析!

          然而,更更更更更重要的是,千萬不要同一個產品不同端或不同子系統的導航不一樣!用戶很可能一會兒用這個,一會兒用那個,結果操作習慣換來換去,人都弄暈啦!還有,就是改版換導航肯定要讓老用戶不滿,好不容易養成習慣改起來容易嗎?所以說,決定導航布局時還是要謹慎才好哦。



          文章來源:優設  作者:
          體驗進階


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



          情境分析法(SCQA)讓你用問卷發現更本質的商業問題

          ui設計分享達人

          前言

           

          在企業工作中,每一個問卷調研都始于一個商業問題,問卷的質量也決定了最終結果是否能對業務起到幫助。本文將從定義問題-問卷設計-數據清洗與分析-報告撰寫這四個基本步驟相對完整地闡述企業問卷調研,希望可以給大家提供一些研究方法上的思路。



          定義問題:情境分析法(SCQA)


          在商業問題解決的過程中,既有公司內部的因素,也有外部行業的因素,影響因素錯綜復雜;周圍的環境也比較容易發生變化,具有很大的不確定性;同時又要保證解決方法的可落地性,產生實際的價值。相對來說,會比較復雜。在進行問卷設計之前,更有必要的是將問題梳理清楚,再決定是否采用問卷這種方式。

           

          1.1 結構化思考:使用SCQA描述項目


          SCQA是將不確定性考慮在內,一種結構化的問題分析方法,可以比較好地系統思考、查漏補缺。它包含四個環節:

          • 情境(Situation):由大家都熟悉的現狀或事實作為起點,包含對象、所處階段等

          • 沖突(Complication):實際情況往往和我們的目標有沖突,顛覆了穩定的狀態。說出行動的原因,包含威脅、機會和等著我們去克服的困難點

          • 問題(Question):基于沖突提出問題,要怎么解決這個困難點

          • 回答(Answer):我們的解決方案是什么,定位出需求點

           

          undefined

           

          1.2 如何洞悉情境和沖突:搞清楚為什么做調研


          假設我們拿到上述案例作為調研項目,可以有兩種方式去進行洞悉情境和沖突

          一是思考為什么要做這個研究;二是跟相關利益者訪談盡可能多地獲取信息。


          1)思考為什么要做這個研究:

          - 需要回答什么問題?

          - 為什么回答這些問題很重要?

          - 打算如何使用最終的調研結果?


          2)跟相關利益者訪談:

          - 核心業務方是誰?其他業務方是?

          - 每個業務方的關注點是什么?難點是什么?

          - 各個相關方的目標之間是否沖突,是什么沖突?

          undefined

          根據上述方法,可以得到對應的情境和沖突:


          情境:目前有三種產品方案A/B/C,分別對應的價格為100元/1000元/10000元。通過上述思考和信息了解,會知道這個事情和誰有關,在這個事件中承擔什么角色。


          沖突:B的銷量不佳,跟其他方案差異不明顯,瞄準客群很有可能有重疊,未成交客戶難轉化,希望可以方案B進行調整。在用戶層,可能其他方案中的功能能滿足需求,不需要購買方案B;在公司層,整體收入結構可以更優化、健康;在業務層,系統和流程可能不太合理,有些可能需要重構。


           

          1.3 問題拆解其實是建立一個假說/邏輯樹的過程


          我們可以將問題進行拆解,拆解應遵循MECE原則(相互獨立且完全窮盡),這么做的好處是可以把問題進行逐層分解,逐級分析,最大可能保證需要考慮的因素全面不遺漏。

           

          undefined

           

          案例中的問題,可以從用戶方面、競品方面、成本/利潤方面進行拆解,針對每一個層面的問題又可以進行拆分。 

          undefined

          對問題進行細致拆分之后,針對每個問題有不同的解決方案,有一些問題可以用問卷來解決,有一些問題需要使用其他方式進行解答。

          問卷并不能解答所有問題~~

           

          undefined



          問卷設計


          2.1 問卷的用途:定量為主


          一般通過問卷來進行大樣本的數據收集,主要以用戶的基礎數據、行為數據和態度數據為主,既可以作為獨立的調研項目,可以跟其他方式進行結合,比如說結合訪談、結合企業內部的數據,本文比較推薦的方式是多種方式結合進行交叉驗證,提升調研結果的可靠性。


          undefined

           

           

          2.2 問卷設計的原則

          undefined

          基于第一部分的定義問題階段,已經對問題進行了分析,在此基礎之上,我們需要確定哪些問題可以由問卷進行解答,并明確問卷的研究目標與參與對象。特別地:利益相關方(項目組成員間)在項目前期應該達成統一,避免后續產生分歧,付出額外的溝通成本不說,還有可能相互甩鍋。


          undefined


          2.3 問卷的基本結構


          一份問卷的基本結構包含標題、招募語、甄別題、主問卷、用戶基本特征、結束語。


          undefined


           

           

          2.4有邏輯的設計問題


          一份有效的問卷需要從如何提問、如何措辭、如何設置答題邏輯、如何設置題目選項這些方面去考慮,設置有效的問題。以下是問卷設計中的一些基本原則:

          undefined

           

          2.5 提升回復率的tips


          undefined

           

          • 個性化:在說明信件/郵件或郵件開頭注明回復者的名字、研究活動的目的、所需時間。向回復者強調他們反饋信息的重要性。需要注意的是,這里出現信息錯誤,會降低回復率。

          • 控制篇幅:問卷完成時間不要超過10分鐘,注意控制問題數量,避免出現需要大量思考、較難回復的題型。

          • 用戶激勵:獎勵參與者油卡/現金紅包/優惠券等,昂貴的激勵物沒有特別顯著提高回復率,所以小的激勵就可以。


           

          數據清洗與分析


          3.1 數據清洗原則

          undefined


          • 剔除有效范圍外的數據:排除異常作答時間值(比如作答時間為10秒),判斷為作答不認真??梢愿鶕}項來確定,一般10道題設置篩選出60秒之內的問卷。

          • 剔除連續重復值:在時間范圍內,再核查問卷是否出現連續重復值,出現的問卷予以刪除。如果問卷數量較大,可以使用STATA軟件編碼或Excel條件函數判斷進行處理。

          • 剔除違背邏輯一致性的數據:在時間范圍內,核查問卷是否存在前后邏輯不一致的題,比如總體滿意度打分為非常滿意,但后續題目都選擇了非常不滿意。

          • 剔除有缺失值的數據:嚴格來說應該將有缺失值的用戶予以刪除,但有時候回收樣本量沒有那么大,則可保留。


           

          3.2 數據分析方法


          數據分析方法有非常多,要在眾多的分析方法中選擇一種也是比較難的事,無論選擇什么樣高大上的方法都是其次,最重要的是選擇的分析方法能說明問題,能體現數據的價值。

          比較分析是一個簡單的、比較通用的、易于理解的數據分析方法,可以分成趨勢分析、特征重要性、分組分析三種。

           

          undefined


          報告撰寫


          最后,條理清晰地展現數據信息,表達你的觀點。報告寫作的過程是一個相對費勁的過程,特別是數據量多的情況下,總是覺得還有一些數據價值沒有被挖掘出來,但此時不要拘泥細節,細節可以回頭再補,會大大提升效率。


          4.1 問卷的報告框架


          • 報告主要發現:將總結放在最前面,閱讀者可以通過簡短的總結大致了解報告觀點,方便他們決定是否需要繼續了解詳細內容

          • 目錄和分目錄:報告包含的內容組成部分,讓閱讀者對報告內容有初步概覽

          • 調研背景和目的:陳述整個報告的背景和目的,對調研的范圍進行必要說明

          • 單頁-詳細內容描述:有邏輯的描述項目的發現,總結數據表現,挖掘價值

           

          單頁-詳細內容描述示例:

          undefined


          問卷調研不止是問卷本身,還包括前期項目組溝通、項目成員分工與配合、后續結果推廣、結果推動落地等,前期做好項目組溝通、明確項目分工,建立一個清晰的運行機制,有利于項目組成員對結果的認同,后續也有清晰的路徑去分工解決問題。所以,每一個環節都體現工作的價值,都同樣重要。希望大家在關注研究方法提升的同時,也可以更多關注更多工作方法提升。

          文章來源:站酷  作者:酷家樂UED

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


          死磕javascript的手寫面試題

          前端達人

          1.實現lodash的_.get方法

          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
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          測試:
          let obj = {
            a:{
              b:[
                {
                  c:2
                }
              ]
            }
          }
          
          console.log(_getValue(obj, 'a.b[0].c')) //2 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          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'
            }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          測試:
          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 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          3.數組扁平化的方法

          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;
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          let arr = [1,2,[3,4,[5,6]]]
          _flat(arr) //[1,2,3,4,5,6] 
          
          • 1
          • 2
          //es6
          function _flat2(arr){
            while(arr.some(item=>Array.isArray(item))){
              arr = [].concat(...arr)
            }
            return arr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          let arr = [1,2,[3,4,[5,6]]]
          _flat2(arr) //[1,2,3,4,5,6] 
          
          • 1
          • 2

          4.深克隆

          簡單深克隆,不考慮內置對象和函數

          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
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          復雜版深度克隆 考慮內置對象 比如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;
              }
          } 
          
          • 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

          5.數組去重

          filter去重

          function _unique(arr){
            return arr.filter((item,index,array)=>{
              return array.indexOf(item) === index
            })
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          es6 Set

          function _unique2(arr){
            return [...new Set(arr)]
          } 
          
          • 1
          • 2
          • 3

          includes

          function _unique3(arr){
            let newArr = []
            arr.forEach(item => {
                if(!newArr.includes(item)){
                  newArr.push(item)
                }
            });
            return newArr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          雙層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
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11

          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
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          6.判斷數據的類型

          function _typeOf(obj){
            let res = Object.prototype.toString.call(obj).split(' ')[1]
            let mold = res.substring(0,res.length-1).toLowerCase()
            return mold
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          _typeOf(5) //number
          _typeOf('5') //string 
          
          • 1
          • 2

          7.解析url參數為對象

          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
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20

          8.函數柯里化

          //從一次傳入多個參數  編程多次調用每次傳入一個參數
          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) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17

          9.圖片懶加載

          //添加了兩個功能
          // 圖片加載完成后 移除事件監聽
          // 加載完的圖片從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) 
          
          • 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

          圖片懶加載:https://juejin.cn/post/6844903856489365518#heading-19

          10節流防抖

          函數防抖 觸發高頻事件 事件在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
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          // 復雜版
          // 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)``` 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41

          函數節流 觸發高頻事件 且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
              }
            }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          //定時器
          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)
              }
            }
          
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          //組合版 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歐

          app界面賞析 + icon 圖標分享 ——— 北京藍藍設計 移動端UI設計資源分享(十八)

          前端達人

          移動互聯網的迅速崛起,讓移動網頁,移動客戶端越來越重要,客戶端的頁面設計也是一門很大的學問。科技迅速發展的今手機屏幕的尺寸越來越放大化,但卻始終 很有限,因此,在APP的界面設計中,精簡是一貫的準則。這里所說的精簡并不是內容上盡可能的少量,而是要注重重點的表達。在視覺上也要遵循用戶的視覺邏 輯,用戶看著順眼了,才會真正的喜歡。


          接下來為大家分享精美的app UI設計案例:

          jhk-1618475928898.jpgjhk-1618475937124.jpgjhk-1618475946821.jpgjhk-1618475964960.jpgjhk-1618475993734.jpg



          icon的設計會貫穿全套設計稿,所以在設計的環節中必不可少,優質的icon設計會幫助品牌和企業更好的樹立形象,形成自己的設計語言。

          接下來為大家分享一些經典案例:

          WechatIMG1677.jpegWechatIMG1678.jpegWechatIMG1679.jpegWechatIMG1680.jpegWechatIMG1681.jpeg




          --手機appUI設計--

          --icon圖標賞析--

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



            更多精彩文章:

                 手機appUI界面設計賞析(一)

                 手機appUI界面設計賞析(二)

                 手機appUI界面設計賞析(三)

                 手機appUI界面設計賞析(四)

                 手機appUI界面設計賞析(五)

                 手機appUI界面設計賞析(六)

                 手機appUI界面設計賞析(七)

                 手機appUI界面設計賞析(八)

                 手機appUI界面設計賞析(九)

                  手機appUI界面設計賞析(十)

                 手機appUI界面設計賞析(十一)

                 手機appUI界面設計賞析(十二)

                  手機appUI界面設計賞析(十三)

                 手機appUI界面設計賞析(十四)

                 手機appUI界面設計賞析(十五)

                 手機appUI界面設計賞析(十六)

                 手機appUI界面設計賞析(十七)


          日歷

          鏈接

          個人資料

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

          存檔

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