整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HttpClient+Jsoup模擬登陸賀州學院教務

          HttpClient+Jsoup模擬登陸賀州學院教務系統,獲取學生個人信息

            注:可能學校的教務系統已經做了升級,當前的程序不知道還能不能成功獲取信息,加上已經畢業,我的賬戶已經被注銷,試不了,在這里做下思路跟過程的記錄。

            在我的畢業設計中”基于SSM框架賀州學院校園二手交易平臺設計與實現”我有這樣一個設想:使用學校教務系統賬號進行賀州學院學生身份認證(通過HttpClient模擬登陸),發布者身份信息真實、平臺由學生(可以跟計算機協會合作,由他們進行維護)維護,平臺安全可靠,校園身份認證時本校園二手交易平臺的一大特色。為了實現這個功能,我對我們學校的教務系統進行了模擬登陸。

            我通過HttpClients模擬登陸教務系統,獲取學生信息,使用jsoup俗稱“大殺器”進行解析響應回來的html 匹配個人信息a標簽地址并做攜帶參數頁Referer進行第二次請求,使用jsoup來解析響應回來的htm匹配所有學生信息獲取我們想要的學生信息。在存儲過程中要進行唯一性認證,一個賬號只能認證一次,一個學生教務教務系統賬號只能綁定一個平臺賬號。

            目前頭像的上傳我是這樣做的,先把圖片下載的用戶電腦本地作為臨時文件,再調用FtpUtil.upload()方法讀取文件上傳到我們nginx圖片服務器,成功上傳后刪除用戶電腦中的臨時文件。(因為上傳需要傳入一個InputStream但是在寫代碼過程中發現從響應回來的HttpResponse獲取到的數據轉為InputStream時文件出現損失導致上傳后圖片無法正常打開的情況)。而一個重要的技術點就是驗證碼的問題,在編寫代碼時發現想使用Tesseract-OCR開源工具,然而,實現起來沒那么簡單,所以我的做法是把教務系統的驗證碼直接writeTo到用戶的HttpServletResponse獲取圖片驗證碼,直接響應回瀏覽器,讓用戶自己手動輸入再傳到后臺。

          代碼編寫

          引入jar:(如果想在控制臺打印更多連接時的信息,可以使用log4j),或者使用maven引入也行

          public class AuthenticationUtil {
              private static HttpClient client=HttpClients.createDefault();//實例化httpclient  
              //static HttpResponse response=null;  
              private static String rawHtml; //響應回來的數據
              
          /*    public static void main(String[] args) throws Exception {
                  //模擬登陸教務系統,獲取學生信息
                  System.out.println("======模擬登陸教務系統,獲取學生信息======");
                  //獲取驗證碼  
                  int i=getVerifyingCode();  
                  if(i==1){
                      //提醒用戶并輸入驗證碼  
                      System.out.println("驗證碼圖片下載成功! D:/verifyCode.gif,請輸入圖片驗證碼:");  
                      String code;  
                      Scanner in=new Scanner(System.in);  
                      code=in.nextLine();  
                      in.close();  
                      Map map=login("xxx","***",code);
                      if("200".equals(map.get("code"))){
                          String xm=(String) map.get("xm");//姓名
                          String xh=(String) map.get("xh");//學號
                          String lbl_xb=(String) map.get("lbl_xb");//性別
                          String lbl_csrq=(String) map.get("lbl_csrq");//出生日期
                          String lbl_sfzh=(String) map.get("lbl_sfzh");//身份證號
                          String lbl_xy=(String) map.get("lbl_xy");//學院
                          String lbl_zymc=(String) map.get("lbl_zymc");//專業
                          String lbl_xzb=(String) map.get("lbl_xzb");//班級
                          System.out.println(xm);
                      }else{
                          System.out.println(map.get("msg"));
                      }
                  }else{
                      System.out.println("驗證碼圖片下載失敗...");
                  }
              }*/
              /**
               * 模擬登陸
               * @param login_xh
               * @param login_mm
               * @param code
               * @throws IOException 
               * @throws ParseException 
               */
              public static Map<String,String> login(String login_xh,String login_mm,String code) throws Exception {  
                      Map<String,String> map=new HashMap<String,String>();
                      String __VIEWSTATE="";
                      HttpGet getVerifyCode=new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");  
                      HttpResponse response=client.execute(getVerifyCode);//獲取驗證碼  
                      rawHtml=EntityUtils.toString(response.getEntity(), "utf-8");
                      Document doc=Jsoup.parse(rawHtml);
                      Elements select_input=doc.select("input");
                      for (Element a : select_input) {
                          String name=a.attr("name");
                          if("__VIEWSTATE".equals(name)){
                              __VIEWSTATE=a.attr("value");
                              break;
                          }
                      }
                      
                      //設定post參數
                      ArrayList<NameValuePair> postData=new ArrayList<NameValuePair>();  
                      postData.add(new BasicNameValuePair("Button1", ""));  
                      postData.add(new BasicNameValuePair("RadioButtonList1", "學生"));//登陸賬號類型  
                      postData.add(new BasicNameValuePair("TextBox2", login_mm));//密碼    
                      postData.add(new BasicNameValuePair("Textbox1", ""));  
                      postData.add(new BasicNameValuePair("__VIEWSTATE", __VIEWSTATE));  
                      postData.add(new BasicNameValuePair("hidPdrs", ""));  
                      postData.add(new BasicNameValuePair("hidsc", ""));
                      postData.add(new BasicNameValuePair("lbLanguage", ""));
                      postData.add(new BasicNameValuePair("txtSecretCode", code));//驗證碼  
                      postData.add(new BasicNameValuePair("txtUserName", login_xh));//學號    
                      //登錄 post請求  
                      HttpPost post=new HttpPost("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//構建post對象  
                      post.setEntity(new UrlEncodedFormEntity(postData));//捆綁參數 
                      post.setHeader("Accept", "text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8");//帶上參數頁
                      post.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
                      post.setHeader("Connection", "keep-alive");//帶上參數頁
                      post.setHeader("Content-Type", "application/x-www-form-urlencoded");//帶上參數頁
                      post.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
                      post.setHeader("Origin", "http://jwxt.hzu.gx.cn");//帶上參數頁
                      post.setHeader("Upgrade-Insecure-Requests", "1");//帶上參數頁
                      post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36");//帶上參數頁
                      post.setHeader("Referer", "http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//帶上referer 參數頁
                      response=client.execute(post);//執行登陸行為  
                      //登錄成功,發生302重定向
                      if(302==response.getStatusLine().getStatusCode()){
                          //把響應結果打印出來
                          System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
                          Header header=response.getFirstHeader("location"); // 跳轉的目標地址是在 HTTP-HEAD 中的
                          String newuri=header.getValue(); // 這就是跳轉后的地址,再向這個地址發出新申請,以便得到跳轉后的信息是啥。
                          newuri="http://jwxt.hzu.gx.cn/"+newuri;
          //                System.out.println(newuri);
                          //登錄成功  get請求
                          HttpGet get=new HttpGet(newuri);
                          get.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
                          get.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
                          get.setHeader("Referer", "http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//帶上referer 參數頁
          //                client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);
          //                client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
                          // 超時設置
                          RequestConfig requestConfig=RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();//設置請求和傳輸超時時間
                          get.setConfig(requestConfig);
                          /*
                           * 第二次身份認證時,程序會卡在這里
                           * 
                           */
                          response=(CloseableHttpResponse) client.execute(get);//執行重定向 
                          //打印輸出
          //                rawHtml=EntityUtils.toString(response.getEntity(), "utf-8");  
          //                System.out.println(rawHtml);
                          String xsgrxxUrl="http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/";//個人信息a標簽地址
                          if(200==response.getStatusLine().getStatusCode()){
                              //使用jsoup來解析響應回來的html  匹配個人信息a標簽地址
                              rawHtml=EntityUtils.toString(response.getEntity(), "utf-8");
                              Document document=Jsoup.parse(rawHtml);
                              Elements select_a=document.select("a");
                              for (Element a : select_a) {
                                  String href=a.attr("href");
                                  if(href.indexOf("xsgrxx.aspx")!=-1){
                                      xsgrxxUrl=xsgrxxUrl+href;
                                      break;
                                  }
                              }
                              //查看個人信息   get請求
                              get=new HttpGet(xsgrxxUrl);
                              post.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
                              post.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
                              get.setHeader("Referer", newuri);//帶上referer 參數頁
                              response=(CloseableHttpResponse) client.execute(get);//執行
                          }
                          rawHtml=EntityUtils.toString(response.getEntity(), "utf-8");  
                          //打印輸出
          //                System.out.println(rawHtml);
                          //使用jsoup來解析響應回來的html    匹配所有學生信息
                          Document document=Jsoup.parse(rawHtml);
                          Elements select_span=document.select("span");
                          for (Element span : select_span) {
                              String id=span.attr("id");
                              if("xh".equals(id)){//學號
                                  String xh=span.text();
                                  map.put("xh", xh);
          //                        System.out.println("學號:"+xh);
                              }
                              if("xm".equals(id)){//姓名
                                  String xm=span.text();
                                  map.put("xm", xm);
          //                        System.out.println("姓名:"+xm);
                              }
          //                    if("lbl_TELNUMBER".equals(id)){//手機號碼
          //                        String lbl_TELNUMBER=span.text();
          //                        System.out.println("手機號碼:"+lbl_TELNUMBER);
          //                    }
                              if("lbl_xb".equals(id)){//性別
                                  String lbl_xb=span.text();
                                  map.put("lbl_xb", lbl_xb);
          //                        System.out.println("性別:"+lbl_xb);
                              }
                              if("lbl_csrq".equals(id)){//出生日期
                                  String lbl_csrq=span.text();
                                  map.put("lbl_csrq", lbl_csrq);
          //                        System.out.println("出生日期:"+lbl_csrq);
                              }
                              if("lbl_byzx".equals(id)){//畢業中學
                                  String lbl_byzx=span.text();
                                  map.put("lbl_byzx", lbl_byzx);
          //                        System.out.println("畢業中學:"+lbl_byzx);
                              }
                              if("lbl_mz".equals(id)){//民族
                                  String lbl_mz=span.text();
                                  map.put("lbl_mz", lbl_mz);
          //                        System.out.println("民族:"+lbl_mz);
                              }
                              if("lbl_sfzh".equals(id)){//身份證號
                                  String lbl_sfzh=span.text();
                                  map.put("lbl_sfzh", lbl_sfzh);
          //                        System.out.println("身份證號:"+lbl_sfzh);
                              }
                              if("lbl_xy".equals(id)){//學院
                                  String lbl_xy=span.text();
                                  map.put("lbl_xy", lbl_xy);
          //                        System.out.println("學院:"+lbl_xy);
                              }
                              if("lbl_zymc".equals(id)){//專業
                                  String lbl_zymc=span.text();
                                  map.put("lbl_zymc", lbl_zymc);
          //                        System.out.println("專業:"+lbl_zymc);
                              }
                              if("lbl_xzb".equals(id)){//班級
                                  String lbl_xzb=span.text();
                                  map.put("lbl_xzb", lbl_xzb);
          //                        System.out.println("班級:"+lbl_xzb);
                              }
                              if("lbl_lys".equals(id)){//所在省份
                                  String lbl_lys=span.text();
                                  map.put("lbl_lys", lbl_lys);
          //                        System.out.println("所在省份:"+lbl_lys);
                              }
                              if("jtdz".equals(id)){//家庭住址
                                  String jtdz=span.text();
                                  map.put("jtdz", jtdz);
          //                        System.out.println("家庭住址:"+jtdz);
                              }
                          }
                          //上傳頭像到圖片服務器上
                          Elements select_img=document.select("img");
                          String imagUrl=select_img.attr("src");
                          
                          getPortrait((String)map.get("xh"),"http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/"+imagUrl, xsgrxxUrl);
                          //ftp上傳到圖片服務器
                          FileInputStream fileInputStream=new FileInputStream(new File("D:/portrait.jpg"));
                          CpshResult result=FtpUtil.upload((String)map.get("xh")+"_portrait.jpg", fileInputStream);
                          if(result.getStatus()==200){
                              map.put("tx", result.getData()+"");
                              //把文件刪掉
                              File file=new File("D:/portrait.jpg");
                              file.delete();
                          }else{
                              System.out.println("頭像上傳失敗!");
                          }
                          //成功
                          map.put("code", "200");
                          map.put("msg", "驗證成功");
                      }else if(200==response.getStatusLine().getStatusCode()){//響應狀態200,登錄失敗
                          //使用jsoup來解析響應回來的html   解析彈窗提示信息
                          rawHtml=EntityUtils.toString(response.getEntity(), "utf-8");
                          Document document=Jsoup.parse(rawHtml);
                          Elements select_script=document.select("script");
                          String msg="";
                          for (Element script : select_script) {
                              String html=script.html();
                              if(html.indexOf("alert")!=-1){
                                  //只保留中文漢字
                                  msg=html.replaceAll("[^\u4E00-\u9FA5]", "");
                                  break;
                              }
                          }
                          //成功
                          map.put("code", "400");
                          map.put("msg", msg);
          //                System.out.println(msg);
                      }else if(500==response.getStatusLine().getStatusCode()){//
                          map.put("code", "500");
                          map.put("msg", "教務系統響應500...");
                          
                      }
          //            client.getConnectionManager().shutdown();
          //            response.close();
                      return map;
              }
              /**
               * 獲取圖片驗證碼,直接響應回瀏覽器
               * @param client
               * @return
               */
              public static void getVerifyingCode(HttpServletResponse response1){
                  try {  
                      HttpGet getVerifyCode=new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/CheckCode.aspx");//驗證碼get  
                      HttpResponse response=client.execute(getVerifyCode);//獲取驗證碼  
                      if(200==response.getStatusLine().getStatusCode()){//200響應碼
                          //將響應回來的圖片信息writeTo 到 fileOutputStream
                          response.getEntity().writeTo(response1.getOutputStream());
                      }
                  } catch (Exception e) {  
                      e.printStackTrace();  
          //            return 0;
                  }finally {  
                  }
              }
              /**
               * 獲取圖片驗證碼,下載到本地
               * @param client
               * @return
               */
              public static int getVerifyingCode(){
                  FileOutputStream fileOutputStream=null;  
                  try {  
          //            HttpClient client=HttpClients.createDefault();//實例化httpclient  
                      HttpGet getVerifyCode=new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/CheckCode.aspx");//驗證碼get  
                      HttpResponse response;  
                      response=client.execute(getVerifyCode);//獲取驗證碼  
                      if(200==response.getStatusLine().getStatusCode()){//200響應碼
                          /*驗證碼寫入文件,保存為verifyCode.jped*/  
                          fileOutputStream=new FileOutputStream(new File("D:/verifyCode.gif"));  
                          //將響應回來的圖片信息writeTo 到 fileOutputStream
                          response.getEntity().writeTo(fileOutputStream);
                          return 1;
                      }else{
                          return 0;
                      }
                  } catch (Exception e) {  
                      e.printStackTrace();  
                      return 0;
                  }finally {  
                      try {  
                          fileOutputStream.close();  
                      } catch (IOException e) {  
                          e.printStackTrace();  
                      }  
                  }
              }
              /**
               * 下載頭像圖片
               * @param cilent
               * @param imagUrl
               * @param referer
               * @return
               */
              public static void getPortrait(String xh,String imagUrl,String referer){
          //        HttpClient client=HttpClients.createDefault();//實例化httpclient  
                  FileOutputStream fileOutputStream=null;
                  try {  
          //            HttpClient client=HttpClients.createDefault();//實例化httpclient  
                      HttpGet portrait=new HttpGet(imagUrl);//get請求  頭像照片
                      //portrait.setHeader("Referer",referer);
                      HttpResponse response=client.execute(portrait);//  執行
                      if(200==response.getStatusLine().getStatusCode()){//200響應碼
          //                /*圖片寫入文件,保存為portrait.jpg*/  
                          File file=new File("D:/portrait.jpg");
                          file.createNewFile();
                          fileOutputStream=new FileOutputStream(file);  
                          response.getEntity().writeTo(fileOutputStream);
                          
                      }
                  } catch (Exception e) {  
                      e.printStackTrace();  
                  }finally {  
                      try {
                          fileOutputStream.flush();
                          fileOutputStream.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }

          效果

          可以再控制臺打印出來,我這里是作為layer彈窗:

          版權聲明

          作者:huanzi-qch

          出處:https://www.cnblogs.com/huanzi-qch

          若標題中有“轉載”字樣,則本文版權歸原作者所有。若無轉載字樣,本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利.

          輯導語:B端產品的展現形式包含了很多類型,標簽頁、彈窗、懸浮層等等。本篇文章中作者分享了如何正確的呈現B端產品,讓產品的交互體驗更加絲滑。感興趣的小伙伴們快來一起看看吧,希望對你有所幫助。

          在B端產品操作中,需要高頻率地打開各類鏈接和按鈕,如果點擊后需要展示新的內容,那么展現形式就包含了很多種類型,標簽頁、新頁面、懸浮層、彈窗、抽屜等等。

          在面對數量龐大的B端頁面、組件、交互場景下,應該選擇哪種展示形式就變成了一個棘手的問題。

          本篇分享就將集中在解決如何選擇正確的呈現形式上,讓產品的交互體驗更順滑。

          一、內容的載體形式

          網頁是一種可視化的UI界面,也是一種內容載體,它是瀏覽器訪問網站后顯示的主要對象,也是瀏覽器展示內容中層級最高的單位。

          在同一個網站中,如果我們想要訪問其它網頁,就需要點擊按鈕或鏈接觸發,這時候,打開新網頁的方式就有兩種,在新窗口/標簽中打開(_blank)或者在本窗口/標簽中打開(_self)。

          不管是哪種,本質上都需要瀏覽器重新加載新的頁面。對于一般的企業官網、新聞網站來說,這種加載的模式沒有太大的問題,因為操作頻次相對適中,用戶中間會有比較長的時間停頓下來查看頁面的內容信息。

          而B端項目則不同,雖然也有不少查看頁面信息的需求,但是包含了更多需要短平快完成操作目標的使用場景,比如修改個標題,更改商品價格,添加分類字段等。

          如果所有高頻操作的場景,都要重新加載頁面,使用起來的 “頓挫感” 是非常強的,降低使用體驗。

          早期的網站加載內容必須刷新頁面,所以頓挫感是難以解決的,只能想辦法減少跳轉流程來提升用戶體驗。

          隨著網頁技術的發展,異步處理(AJAX數據交換方式)技術的應用,讓網頁的內容可以通過不刷新或加載新網頁的形式加載和顯示。

          簡單解釋,就是早期的網頁加載完成以后就是 “靜止” 的,里面所有內容是固定的(不是HTML的靜態)。而異步處理,就是讓頁面中的指定模塊處于 “運動” 的狀態,客戶端可以在不重載網頁的情況下只加載和更新這個模塊的內容。

          比如下面的案例,設置不同的條件選項,在過去的網頁中只能重載頁面更新,而使用異步處理就可以直接和服務器請求數據刷新這個圖表模塊,而不用重載整個頁面。

          所以,在B端項目中,我們不再是只有重載網頁一個選項,而有了其它的選擇,如下圖所示。

          其中,網頁展示作為一個基礎展示對象,我就不多做介紹了。我會通過分別介紹其它幾個內容的載體,幫助大家區分它們和重載頁面有何不同,以及如何正確選擇內容加載形式。

          二、浮層的使用解析

          首先介紹浮層,它是我對通過懸浮在頁面基礎內容之上的內容層的統稱。例如各類氣泡、提示框、下拉菜單,都是浮層的表現形式。

          浮層是比較底層的形式,其展示內的容完全不需要使用一個新的頁面,且和觸發的元素有較強的視覺聯系(對比彈窗)。

          浮層并不是由內容的多和少決定的,復雜的浮層可以包含非常多的交互選項和內容信息,導致我們很容易和下方解釋的彈窗搞混。

          比如客戶端軟件常見的隱藏式側邊欄,搜索欄中展開的復雜面板,都是浮層的一種而不是彈窗。

          浮層最大的特點,源自它的位置定義邏輯,它會和觸發它的元素具有非常緊密的位置關系,而不是像彈窗一樣無差別顯示在界面或瀏覽器視圖的固定區域。

          如果我們想要顯示內容,完全沒到用一個新頁面展示的地步(如搜索建議面板),且和觸發它的控件有較強的聯系,就可以考慮使用浮層來展示。

          三、彈窗的使用解析

          彈窗,也是一種懸浮在基礎內容之上的內容層,它和浮層的不同之處,就在于彈窗通常是居中固定的顯示區域,和觸發它的元素沒有什么位置聯系。并且,彈窗可以包含的內容量級也是高于浮層的。基礎的彈窗包含強提示彈窗,或類似注冊登錄這種表單彈窗。

          而高級的彈窗,則類似下方案例,約等于打開一個獨立的網頁。

          之所以使用這些高級彈窗作為頁面載體,原因就是對原觸發頁面的使用和關注并沒有結束,需要支持快速關閉當前的窗口并返回原來的頁面中去。

          比如在一個非常長的列表中,你下滑了幾十頁的高度,肯定不想放棄掉當前的頁面位置,所以Behance或者花瓣等應用,都采用窗口模式加載新頁面。

          或者類似一個列表頁面中需要大量創建新的數據,這些數據又不復雜。于是就通過彈窗表單的形式,快速完成創建并在原頁面中再次點擊 “新增” 按鈕。

          高級的彈窗使用除了保持原頁面位置、高頻操作等防止加載的原因之外,還有個更重要的特征,就是強制吸引用戶的注意力到窗口上

          因為彈窗主要以模態 (Modal,后方有黑色遮罩)居中顯示,通過深色蒙版進行前后隔斷,凸顯彈窗區域,意味著我們強制讓用戶關注眼前的信息和任務

          如果我們想要顯示的內容,需要保留原頁面狀態,減少頁面跳轉數量,又需求用戶強行關注,就可以使用這種模式展示。

          四、抽屜的使用解析

          最后,就是最難選擇,也最容易和其它組件搞混的抽屜了。

          抽屜本身的特征包含懸浮屬性,覆蓋在原頁面之上。而我們常見的側邊欄、側邊菜單并不能和抽屜畫上等號,因為他們會占用畫布的實際顯示區域,和原有內容同層。

          比如下方案例中,Jira左側導航(不分左右)可以隱藏收入,頁面內容變大,這是側邊欄。而點擊列表選項,右側彈窗的窗口覆蓋原有頁面,才是抽屜。

          和高級的彈窗類似,抽屜也可以當成一個獨立的頁面展示信息。但它和彈窗不同的是,抽屜通常是從頁面的右側展開,沒有遮擋左側的空間。它的主要特征是還需要在原頁面進行交互。

          比如Teambition案例中的列表,我們每開一個抽屜都還可以直接點擊原列表的其它選項切換下一個抽屜,省掉關閉步驟或者原頁面被遮擋的情況。

          它比較適合應用在表格/列表環境中,作為表格/列表內容的詳情頁形式展開,這樣用戶可以在一個頁面中快速查看不同列表的具體信息或編輯。并且,表格/列表本身的特征會將標題放在最左側,也方便抽屜的切換。

          也因為這種特性,抽屜不太需要使用模態和遮罩將左側內容遮擋掉。如果需要通過遮擋來吸引用戶注意力,那么這種情況往往更適合使用彈窗。

          所以,如果不想通過新頁面打開的列表詳情內容,且不是強制要求用戶聚焦的任務,就可以使用抽屜的形式展現。

          五、結尾

          以上就是幾種基本的內容展現形式說明,時間關系還有后半部分關于如何站在系統框架級的角度使用內容載體的分享,我會留在下次分享。

          如果有關于這部分的實際項目疑問,也可以在下方留言。

          我們下篇再見~

          作者:酸梅干超人;公眾號:超人的電話亭

          本文由 @超人的電話亭 原創發布于人人都是產品經理。未經許可,禁止轉載。

          題圖來自 Unsplash,基于CC0協議。

          一直都很信賴WPS,也很支持WPS,就是因為wps對之前word個版本之前的兼容很好。

          前幾天wps強制我更新了版本現在的版本:10.1.0.5850,以為是正常更新,一運行,就跳出登錄窗口。因為本人的不喜歡彈窗關掉,但是提示要是不登錄就要關掉整個程序。為什么關掉登錄窗口,還不給未登錄的用戶的入口,就強制把WPS也關閉?!你們難道要徹底放棄不能上網的用戶,不上網就不能用WPS?因為不能看你們的廣告,不能看到你們推送的東西??!!!來看看最近我們公司客服同事對這的感受。

          wps強制登陸用戶體驗感受

          真的是很無語,今天突然有種被嫌棄、被拋棄的感覺……這讓我整個聯想到最近百度出來的一個算法,打擊用戶體驗不好的網站:

          強行彈窗app下載、用戶登錄、大面積廣告等影響用戶正常瀏覽體驗的頁面,尤其以必須下載app才能正常使用的站點為代表。從整個移動互聯網生態環境看,越來越多的網站進行此類強推,這已經嚴重影響了正常用戶的瀏覽體驗。

          要是百度對這種通過百度搜索進來的軟件有這樣的懲罰到是能夠平息我現在的心情。一萬個草泥馬從眼前奔騰而過,其實雖然不爽,但是我現在寫下這邊文章的額時候還是用的第三方登陸了wps文字word編輯的。期待在一定時間里金山測試好用戶登陸這個后,會不會撤銷這個很讓人煩的登陸功能。畢竟這個在每個應用到一定時期會需要用戶注冊的強制首段。PS:但是這個彈出就算了,關掉還不讓用,這個小編給差評!

          用戶不想注冊,越引導越反感。

          把內容做好,注冊醒目一點,不要喧賓奪主。

          看到特別優秀的網站,我瀏覽后會主動找注冊入口,為了獲得更全面的體驗。

          大家來說說!!

          分享來源: 任偉SEO博客 轉載請注明出處!(QQ交流:547701130/微信:renweiseo/微信公眾號:renwei_seo)

          原文地址:http://www.renweiseo.com/blog/view/4330.html


          主站蜘蛛池模板: 精品国产一区二区麻豆| 无码午夜人妻一区二区三区不卡视频| 国产品无码一区二区三区在线| 精品一区二区三区在线视频观看 | 天堂资源中文最新版在线一区| 夜精品a一区二区三区| 日韩精品无码一区二区三区 | 国产色综合一区二区三区| 日韩精品一区二区午夜成人版 | 一区二区三区国产精品 | 精品一区高潮喷吹在线播放| 中文字幕日本一区| 精品综合一区二区三区| 欧美日韩国产免费一区二区三区| 无码毛片视频一区二区本码| 97精品国产福利一区二区三区| 天码av无码一区二区三区四区| 亚洲AV日韩AV一区二区三曲| 麻豆AV无码精品一区二区| 久久久久人妻精品一区| 精品女同一区二区三区免费站| 人体内射精一区二区三区| 一区二区视频在线播放| 精品一区二区三区波多野结衣| 亚洲爆乳精品无码一区二区三区| 亚洲高清日韩精品第一区| 亚洲国产老鸭窝一区二区三区 | 精品视频一区二区三区| 亚洲一区精品伊人久久伊人| 国产精品99无码一区二区| 久夜色精品国产一区二区三区| 久久精品国产一区二区电影| 国产在线视频一区| 亚洲AV无码一区二区三区DV| 久久一本一区二区三区| 亚洲午夜在线一区| 濑亚美莉在线视频一区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 久久精品中文字幕一区| 波多野结衣AV无码久久一区| 日本不卡一区二区三区视频|