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

          首頁

          js獲取video任意時間的畫面截圖

          seo達人

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

          首先就是要把視頻加載出來,然后使用canvas.getContext(‘2d’).drawImage(videoElement, 0, 0, canvas.width, canvas.height);獲取到當前視頻時間的截圖,需要不同時間的video視頻圖,設置video的currentTime(單位秒),然后videoElement這個對象信息會實時更新。

          如果是視頻是在阿里云OSS上就更方便了,poster=“http://a-image-demo.oss-cn-qingdao.aliyuncs.com/demo.mp4?x-oss-process=video/snapshot,t_6000,m_fast”

          如果是要獲取上傳本地視頻預覽圖,可采用下面的方法,但有兼容性問題,目前測試移動端安卓機只有Chrome瀏覽器支持,微信和QQ瀏覽器都無法響應本地視頻的canplay事件。

          <div contenteditable="true" id="in-box" style="width:1000px;margin: 20px auto;"></div>
          <div style="width:1000px;margin: 20px auto;">        
             <input type="file" name="" accept="video/*" id="upload-ipt">
             <div class="review" id="out-box"></div>
          </div>

          function getVideoImage() {
              var obj_file = document.getElementById("upload-ipt");
              var file = obj_file.files[0];
              var blob = new Blob([file]), // 文件轉化成二進制文件
                  url = URL.createObjectURL(blob); //轉化成url
              if (file && /video/g.test(file.type)) {
                  var $video = $('<div><video controls src="' + url + '"></video></div><div>&nbsp;</div>');
                  //后面加一個空格div是為了解決在富文本中按Backspace時刪除無反應的問題
                  $('#in-box').html($video);
                  var videoElement = $("video")[0];
                  videoElement.addEventListener("canplay", function (_event) {
                      var canvas = document.createElement("canvas");                    
                      canvas.width = videoElement.videoWidth;
                      canvas.height = videoElement.videoHeight;
                      console.log(videoElement.videoWidth)
                      canvas.getContext('2d').drawImage(videoElement, 0, 0, canvas.width, canvas.height);
                      var img = document.createElement("img");
                      img.src = canvas.toDataURL("image/png");
                      $("#out-box").html(img);
                      URL.revokeObjectURL(this.src); // 釋放createObjectURL創建的對象
                      console.log("loadedmetadata")
                  });
              }else{
                  alert("請上傳一個視頻文件!");
                  obj_file.value = ""
              }
          };
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          javascript對數組和json數組的操作

          seo達人

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

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>javascript數組操作</title>
              <script type="application/javascript" src="lib/jquery.min.js"></script>
          </head>
          <body>
          <h2>javascript操作數組</h2>
          <input type="button" value="js數組" "jsArrays();">
          <br>
          <input type="button" value="json數組1" "jsonArrays();">
          </body>
          <script type="application/javascript">
          //數組操作
              function jsArrays() {
              //創建一個javascript數組
                  var a=new Array();
                  a.push('a');
                  a.push('b');
                  a.push('c');
                  //往數組添加三個元素
                  alert(a);
                  //利用indexof可以指出該元素在數組中所在位置
                  alert('a index of a'+a.indexOf('a'));
                  //利用jquery對數組進行便利
                  $(a).each(function (index,row) {
                      alert('index is '+index);
                      alert('row is '+row);
                  })
              }
              //json數組操作
              function jsonArrays() {
              //首先也是創建一個json數組
                  var a=new Array();
                  a.push({a:1});
                  a.push({a:2});
                  a.push({a:3});
                  //同樣的往數組添加三個元素
                  //alert出的結果是[{object,object},{object,object},{object,object}]
                  alert('a is '+a);
                  //利用JSON的方法將json數組轉換為字符串這時候alert的就是json字符串了
                  alert(JSON.stringify(a));
                  //直接獲取json數組第一個元素的值,此時知道json的key是a
                  alert(a[0].a);
                  //遍歷json數組第一個元素的key,這時候可以alert出的結果是a,同樣的可以得出對應的value
                  for(var key in a[1]){
                      alert('key is '+key);
                      alert('value is '+a[0][key]);
                  }
                  //用jquery對json數組進行遍歷
                  $(a).each(function (index,row) {
                      for(var key in row){
                          alert('each key is '+key);
                          alert('each value is '+row[key]);
                      }
                  })
              }
          </script>
          </html>
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          調試移動端網頁工具Weinre使用整理

          seo達人

          一、Weinre 說明



          Weinre的本意是Web Inspector Remote,它是一種遠程調試工具。功能與Firebug、Webkit inspector類似,可以幫助我們即時更改頁面元素、樣式,調試JS等。



          使用Weinre工具,Weinre的本意是Web Inspector Remote,它是一種遠程調試工具:



          1.它可以將遠程的頁面經過代理在PC上調試頁面元素、樣式,JS。



          2.可以監聽頁面內部的Ajax請求等。



          3.可以監聽頁面加載成功時候的Console控制臺輸出



          官網首頁:http://people.apache.org/~pmuellr/weinre/docs/latest/



          Weinre的原理







          三個端的含義:客戶端(client):本地的WebInspector,遠程調試客戶端。服務端(agent):本地的HTTPServer,為目標頁面與客戶端建立通信。目標頁面(target):被調試的頁面,頁面已嵌入weinre的遠程js。



          調試過程:



          客戶端將指令(請求DOM、執行js)post到代理服務端,目標頁面定時(大概5s)從服務端get指令,然后將結果post回服務端,最終客戶端定時從服務端get結果。



          PS:由于Weinre的客戶端是基于Web Inspector開發,而Web Inspector只兼容WebKit核心的瀏覽器,所以只能在Chrome/Safari瀏覽器打開Weinre客戶端進行調試。





          二、Weinre安裝和使用



          1.weinre是基于NodeJs,因此首先要安裝NodeJs,然后使用npm命令安裝weinre



          npm -g install weinre

          2.運行,啟動weinre服務器,默認端口8080



          node.exe node_modules\weinre\weinre --boundHost -all-

          node.exe node_modules\weinre\weinre --boundHost  192.168.1.125 

          在windows下,系統防火墻可能會彈出是否允許其訪問網絡的提示,點擊充許即可。

          3.從瀏覽器訪問,http://localhost:8080,或者,http://192.168.1.125:8080,顯示如下表示啟動服務器監視成功











          三、Weinre需要監聽調試的Web頁面配置處理



          1.在所有頁面引入js文件



          2.特別說明,當前js文件的域名需要指定為本機的IP地址,因為在手機模擬器中無法訪問電腦‘localhost’



















          更多:



          cordova-plugin-whitelist 協議白名單配置整理 



          VS Code插件安裝位置



          Visual Studio Code插件之Atom One Dark Syntax Theme



          相關參考文章:



          http://blog.csdn.net/freshlover/article/details/42640253



          http://www.cnblogs.com/diva/p/3995674.html

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

          豆瓣API實踐項目-前言-0

          seo達人

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

          這是一個 app從獲取獲取數據 用于顯示的經典實踐項目,數據來源于 豆瓣官方公開的api接口:https://developers.douban.com/wiki/?title=movie_v2



          先上圖:

                

             





          項目使用了如下第三方library:

          下拉刷新:Android-PullToRefresh

          網絡數據加載:android-async-http

          圖片加載:universal-image-loader



          后面的博客,會把項目的制作流程發出來

          豆瓣API實踐項目-前言-0(可下載源碼): http://blog.csdn.net/mario_faker/article/details/79618210

          豆瓣API實踐項目-數據api接口-1:http://blog.csdn.net/mario_faker/article/details/79618235

          豆瓣API實踐項目-搭建項目基本框架-2:http://blog.csdn.net/mario_faker/article/details/79618245

          豆瓣API實踐項目-導入第三方library-3:http://blog.csdn.net/mario_faker/article/details/79618261

          豆瓣API實踐項目-單頁細講4: http://blog.csdn.net/mario_faker/article/details/79618272

          豆瓣API實踐項目-apk打包:http://blog.csdn.net/mario_faker/article/details/79618291





          項目源代碼下載地址:

          http://download.csdn.net/download/mario_faker/10253201

          或github:https://github.com/MarioFaker/DBMovie

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

          Android5.0以后,materialDesign風格的加陰影和裁剪效果

          seo達人

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

          5.0以后,materialDesign風格,出現了立體這種概念,高光,陰影,也就是Z軸,凸顯層次;同時,裁剪view也變得方便簡單了很多。
          1,先說說陰影的實現。
          方案1:在xml中設置 
          xml中設置有兩個方式,android:elevation="2dp" 
          android:translationZ="2dp"這兩句代碼是可以同時并存的,而且是疊加的效果;當然只使用其中一個屬性進行z軸的陰影設置也是OK的。

          方案2:在代碼中設置 
          (下面說這個實現方式,其實就是輪廓的實現)

          設置陰影,有一個需要注意的地方:
          ①:view的大小要比它的父布局小,才會有陰影效果,如果相同大小,是看不到陰影效果的; 
          ②:給圖片設置陰影的時候,如果這種圖片的background屬性是shape,那直接通過xml設置陰影是OK的,但是,如果是一張png或者其他格式的圖片,直接通過xml設置android:elevation="2dp" 
          android:translationZ="2dp"陰影是看不到效果的,得通過其他代碼設置才行。。。**

          2,view的輪廓,輪廓其實也是陰影
          默認情況下,所有的view都是矩形的,雖然可以給view設置背景圓形的圖片,即可以在界面顯示出圓形的內容,但是view的大小實際上依然是矩形,并且設置的圖片實際上也是矩形的,只是圓形以外的區域是透明色。 
          如果根據view大小來生成對應的陰影,就會出現很奇怪的效果,(一個看起來圓形的view展示出的確實一個矩形的陰影)我了解決這個問題,view增加了一個新的描述來指明內容顯示的形狀,這就是 輪廓

          輪廓的實現
          ①通過shape設置的背景,view會自動根據shape的形狀進行輪廓判定,
          ②通過color設置的背景,view默認其輪廓和view的大小一樣。
          ③但是通過圖片進行背景設置,view則無法獲知輪廓的形狀,這個時候就需要手動進行指定了。
          1
          2
          3
          一:在xml中可以通過android:outlineProvider來指定輪廓的判定方式: 
          1,none即使設置了Z屬性,也不會顯示陰影 
          2,background會按照背景來設置陰影形狀 
          3,bounds會按照view的大小來描繪陰影

          **對于①和②這種情況,也是可以通過設置`android:outlineProvider`
          來改變陰影的形狀以及輪廓外觀的。**

          對于③這種背景是一張png或者其他格式的圖片的情況,
          `android:outlineProvider=“background”`
          是沒有效果的,屬性設置成`android:outlineProvider=bounds`
          雖然也是有效果的,但是陰影輪廓是一個方形的輪廓,
          并不是我們想要的效果了。

          不設置`android:outlineProvider`屬性就更沒有效果了。
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          對于這種使用了png圖片作為背景的view加陰影輪廓的時候情況解決辦法也非常簡單,解決辦法就是:
          就通過Java代碼設置,也就是說,一個圓形的png圖(我們知道,看起來是圓形的,
          但是它其實還是方形的圖片,只是圓形之外的區域是透明不可見的),
           通過Java代碼設置輪廓,就會顯示出圓形的陰影輪廓了。
          1
          2
          3
          具體實現,繼續看: 
          二:在代碼中,課通過setOutlineProvider來指定一個view的輪廓。 
          對于③這種情況在代碼中設置輪廓才會有效果。

          TextView textView= findViewById(R.id.tv);
          ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
                      @Override
                      public void getOutline(View view, Outline outline) {
                   //x,y軸表示位置,后兩個參數表示長,寬 
                         outline.setOval(0,0,textView.getWidth(),textView.getHeight());
                      }
                  };
          textView.setOutlineProvider(viewOutlineProvider);
          1
          2
          3
          4
          5
          6
          7
          8
          9
          強調:
          如果采用圓形圖片作為背景,即使在xml布局中指定android:outlineProvider=“background”,也不會顯示陰影,設置為android:outlineProvider=bounds,雖然也有效果,但是效果很差,所以一般都是通過代碼來指定輪廓顯示。

          1,一個shape圓形作為背景,設置陰影,設置android:outlineProvider的4種屬性的效果:


          2,一個圓形png作為背景,設置陰影,設置android:outlineProvider的4種屬性的效果:


          3,一個png作為背景,設置陰影,通過代碼設置的效果:


          3,view的裁剪
          裁剪,默認的ImageView是矩形的,很多時候,需要的是圓角的ImageView或者圓形的ImageView,這就需要裁剪view了。

          實現,裁剪圓形:

          final TextView textView= findViewById(R.id.tv);

          ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
                      @Override
                      public void getOutline(View view, Outline outline) {
                          //設置圓形oval
                          outline.setOval(0,0,textView.getWidth(),textView.getHeight());
                      }
                  };
          //設置裁剪
          textView.setClipToOutline(true);
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          實現,裁剪圓角矩形:

          final TextView textView= findViewById(R.id.tv);

          ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
                      @Override
                      public void getOutline(View view, Outline outline) {
                          //設置圓角矩形
                         outline.setRoundRect(0,0,view.getWidth(),view.getHeight(),25);
                      }
                  };
          textView.setOutlineProvider(viewOutlineProvider);
          //設置裁剪
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

          TabLayout 全面總結

          seo達人

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

          一、簡介

          TabLayout提供了一個水平布局用于展示tabs,繼承自HorizontalScrollView。一般與Viewpager結合使用實現頁面和標簽聯動的效果,是時下APP中非常常用的一個控件



          二、基本用法

          1. 添加design依賴

            compile 'com.android.support:design:25.3.1'

            1
          2. xml引用
          3. xml中添加tab

            <android.support.design.widget.TabLayout

                android:id="@+id/tab_layout"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <android.support.design.widget.TabItem

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:text="Tab1"/>

                <android.support.design.widget.TabItem

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:text="Tab2"/>

                <android.support.design.widget.TabItem

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:text="Tab3"/>

                <android.support.design.widget.TabItem

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:text="Tab4"/>

            </android.support.design.widget.TabLayout>

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            11

            12

            13

            14

            15

            16

            17

            18

            19

            20

            21
          4. 代碼中添加tab

            <android.support.design.widget.TabLayout

                android:id="@+id/tab_layout"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

            </android.support.design.widget.TabLayout>

            1

            2

            3

            4

            5

            // tablayout,Tab是TabLayout的內部類,且Tab的構造方法是包訪問權限

            TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

            tabLayout.addTab(tabLayout.newTab().setText("Tab1"));

            tabLayout.addTab(tabLayout.newTab().setText("Tab2"));

            tabLayout.addTab(tabLayout.newTab().setText("Tab3"));

            tabLayout.addTab(tabLayout.newTab().setText("Tab4"));

            1

            2

            3

            4

            5

            6





            三、屬性詳解

            <declare-styleable name="TabLayout">

                <!--指示器顏色-->

                <attr name="tabIndicatorColor" format="color"/>

                <!--指示器高度-->

                <attr name="tabIndicatorHeight" format="dimension"/>

                <!--tabs距TabLayout開始位置的偏移量,但app:tabMode="scrollable"才生效-->

                <attr name="tabContentStart" format="dimension"/>

                <!--僅是Tab背景,設置TabLayout背景用android:background-->

                <attr name="tabBackground" format="reference"/>

                <!--默認fixed,所有Tab只能在屏幕內顯示,超出會被擠壓;scrollable,tab數量多會超出屏幕,可滑動-->

                <attr name="tabMode">

                    <enum name="scrollable" value="0"/>

                    <enum name="fixed" value="1"/>

                </attr>

                <!--默認fill,tab填滿TabLayout,但tabMode=“fixed”才生效;center,tabs位于TabLayout的中間-->

                <attr name="tabGravity">

                    <enum name="fill" value="0"/>

                    <enum name="center" value="1"/>

                </attr>

                <!--Tab的最小寬度-->

                <attr name="tabMinWidth" format="dimension"/>

                <!--Tab的最大寬度-->

                <attr name="tabMaxWidth" format="dimension"/>

                <!--Tab文本設置樣式-->

                <attr name="tabTextAppearance" format="reference"/>

                <!--Tab未選中字體顏色-->

                <attr name="tabTextColor" format="color"/>

                <!--Tab選中字體顏色-->

                <attr name="tabSelectedTextColor" format="color"/>

                <!--Tab內填充相關-->

                <attr name="tabPaddingStart" format="dimension"/>

                <attr name="tabPaddingTop" format="dimension"/>

                <attr name="tabPaddingEnd" format="dimension"/>

                <attr name="tabPaddingBottom" format="dimension"/>

                <attr name="tabPadding" format="dimension"/>

            </declare-styleable>

            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

            使用示例



             <android.support.design.widget.TabLayout

                android:id="@+id/tab_layout"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                app:tabIndicatorColor="@color/colorPrimaryDark"

                app:tabIndicatorHeight="2dp"

                app:tabContentStart="50dp"

                app:tabBackground="@color/colorAccent"

                app:tabMode="scrollable"

                app:tabGravity="fill"

                app:tabTextAppearance="@style/MyTabTextAppearance"

                app:tabTextColor="@android:color/black"

                app:tabSelectedTextColor="@android:color/white"/>

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            11

            12

            13

            <style name="MyTabTextAppearance" parent="TextAppearance.Design.Tab">

                <item name="textAllCaps">false</item>

                <item name="android:textSize">18sp</item>

            </style>

            1

            2

            3

            4





            四、圖文混排,Tab中添加圖片
          5. 通過SpannableString設置圖片

            @NonNull

            private SpannableString setImageSpan(String string,int drawableId) {

                SpannableString ss = new SpannableString("  "+string);

                Drawable drawable = ContextCompat.getDrawable(this, drawableId);

                drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());

                ImageSpan imageSpan = new ImageSpan(drawable);

                ss.setSpan(imageSpan,0,1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

                return ss;

            }

            1

            2

            3

            4

            5

            6

            7

            8

            9

            TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

            tabLayout.addTab(tabLayout.newTab().setText(setImageSpan("Tab1",R.drawable.ic_home)));

            tabLayout.addTab(tabLayout.newTab().setText(setImageSpan("Tab2",R.drawable.ic_info)));

            ……

            1

            2

            3

            4





            我們會發現個問題,通過ImageSpan設置的圖片和文字沒有對齊,先百度到一個可用方法解決:重寫ImageSpan的draw()方法



            package com.strivestay.tablayoutdemo;



            import android.graphics.Bitmap;

            import android.graphics.Canvas;

            import android.graphics.Paint;

            import android.graphics.drawable.Drawable;

            import android.support.annotation.NonNull;

            import android.text.style.ImageSpan;



            public class CenterImageSpan extends ImageSpan {

                public CenterImageSpan(Drawable drawable) {

                    super(drawable);



                }



                public CenterImageSpan(Bitmap b) {

                    super(b);

                }



                @Override

                public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,

                                 @NonNull Paint paint) {



                    Drawable b = getDrawable();

                    Paint.FontMetricsInt fm = paint.getFontMetricsInt();

                    int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//計算y方向的位移

                    canvas.save();

                    canvas.translate(x, transY);//繪制圖片位移一段距離

                    b.draw(canvas);

                    canvas.restore();

                }

            }

            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

            將上面的ImageSpan替換為現在的CenterImageSpan,即可實現圖文混排時對齊






          6. 通過Tab.setCustomView()設置圖片
          7. 自定義view布局

            <?xml version="1.0" encoding="utf-8"?>

            <LinearLayout

                xmlns:android="http://schemas.android.com/apk/res/android"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:orientation="vertical"

                android:gravity="center">

                <ImageView

                    android:id="@+id/iv"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:src="@drawable/ic_home"/>

                <TextView

                    android:id="@+id/tv"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_margin="2dp"

                    android:textSize="16sp"

                    android:text="首頁"/>

            </LinearLayout>

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            11

            12

            13

            14

            15

            16

            17

            18

            19

            20
          8. 代碼設置

             TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

            tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_home,"首頁")));

            tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_info,"資訊")));

            tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_live,"直播")));

            tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_me,"我")));

            1

            2

            3

            4

            5

             private View setCustomView(int drawableId,String tabText) {

                View view = View.inflate(this, R.layout.item_tab, null);

                ImageView iv = (ImageView) view.findViewById(R.id.iv);

                TextView tv = (TextView) view.findViewById(R.id.tv);

                iv.setImageResource(drawableId);

                tv.setText(tabText);

                return view;

            }

            1

            2

            3

            4

            5

            6

            7

            8





            五、TabLayout與Viewpager聯動
          9. xml設置TabLayout和Viewpager

            第一種:TabLayout放置在Viewpager的上方,放在AppbarLayout中會有陰影效果



            <?xml version="1.0" encoding="utf-8"?>

            <android.support.design.widget.CoordinatorLayout

                xmlns:android="http://schemas.android.com/apk/res/android"

                xmlns:app="http://schemas.android.com/apk/res-auto"

                xmlns:tools="http://schemas.android.com/tools"

                android:id="@+id/main_content"

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:fitsSystemWindows="true"

                tools:context="com.strivestay.tablayoutdemo.MainActivity">



                <android.support.design.widget.AppBarLayout

                    android:id="@+id/appbar"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:paddingTop="@dimen/appbar_padding_top"

                    android:theme="@style/AppTheme.AppBarOverlay">



                    <android.support.v7.widget.Toolbar

                        android:id="@+id/toolbar"

                        android:layout_width="match_parent"

                        android:layout_height="?attr/actionBarSize"

                        android:background="?attr/colorPrimary"

                        app:layout_scrollFlags="scroll|enterAlways"

                        app:popupTheme="@style/AppTheme.PopupOverlay">



                    </android.support.v7.widget.Toolbar>



                    <android.support.design.widget.TabLayout

                        android:id="@+id/tab_layout"

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        app:tabIndicatorColor="@color/colorAccent"

                        app:tabIndicatorHeight="2dp"

                        app:tabBackground="@android:color/white"

                        app:tabTextAppearance="@style/MyTabTextAppearance"

                        app:tabTextColor="@android:color/black"

                        app:tabSelectedTextColor="@android:color/holo_blue_light">

                    </android.support.design.widget.TabLayout>



                </android.support.design.widget.AppBarLayout>



                <android.support.v4.view.ViewPager

                    android:id="@+id/container"

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>



                <android.support.design.widget.FloatingActionButton

                    android:id="@+id/fab"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_gravity="end|bottom"

                    android:layout_margin="@dimen/fab_margin"

                    app:srcCompat="@android:drawable/ic_dialog_email"/>



            </android.support.design.widget.CoordinatorLayout>

            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





            第二種:TabLayout直接放在Viewpager,無陰影



            <android.support.v4.view.ViewPager

                android:id="@+id/container"

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.design.widget.TabLayout

                    android:id="@+id/tab_layout"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    app:tabIndicatorColor="@color/colorAccent"

                    app:tabIndicatorHeight="2dp"

                    app:tabBackground="@android:color/white"

                    app:tabTextAppearance="@style/MyTabTextAppearance"

                    app:tabTextColor="@android:color/black"

                    app:tabSelectedTextColor="@android:color/holo_blue_light">

                </android.support.design.widget.TabLayout>

            </android.support.v4.view.ViewPager>

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            11

            12

            13

            14

            15

            16

            17




          10. 為Viewpager創建適配器

            /

              fragment

             
            /

            public static class PlaceholderFragment extends Fragment {

                private static final String ARG_SECTION = "section";



                public PlaceholderFragment() {

                }



                public static PlaceholderFragment newInstance(String section) {

                    PlaceholderFragment fragment = new PlaceholderFragment();

                    Bundle args = new Bundle();

                    args.putString(ARG_SECTION, section);

                    fragment.setArguments(args);

                    return fragment;

                }



                @Override

                public View onCreateView(LayoutInflater inflater, ViewGroup container,

                                         Bundle savedInstanceState) {

                    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

                    TextView textView = (TextView) rootView.findViewById(R.id.section_label);

                    textView.setText(getArguments().getString(ARG_SECTION));

                    return rootView;

                }

            }



            /


              pagerAdapter

             
            /

            public class SectionsPagerAdapter extends FragmentPagerAdapter {

                String[] tabs = {"首頁","資訊","直播","我"};



                public SectionsPagerAdapter(FragmentManager fm) {

                    super(fm);

                }



                @Override

                public Fragment getItem(int position) {

                    return PlaceholderFragment.newInstance(tabs[position]);

                }



                @Override

                public int getCount() {

                    return tabs.length;

                }



                @Override

                public CharSequence getPageTitle(int position) {

                    return tabs[position];

                }

            }

            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

            主要是重寫getPageTitle()方法


          11. 代碼設置 TabLayout和Viewpager綁定

             // tablayout

            TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);



            // vp

            mViewPager = (ViewPager) findViewById(R.id.container);

            mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

            mViewPager.setAdapter(mSectionsPagerAdapter);



            // 綁定,要在viewpager設置完數據后,調用此方法,否則不顯示 tabs文本

            tabLayout.setupWithViewPager(mViewPager);

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            調用setupWithViewPager()方法,則使用TabLayout.addtab()方法無效,TabLayout會清除之前添加的所有tabs,并將根據Viewpager的頁數添加Tab,Tab標題為對應頁通過getPageTitle()返回的文本






          12. 圖文混排
          13. 同上,使用SpannableString

            修改Adapter如下:



            /*

             
            pagerAdapter

             */

            public class SectionsPagerAdapter extends FragmentPagerAdapter {



                String[] tabs = {"首頁","資訊","直播","我"};

                int[] imgs = {R.drawable.ic_home,R.drawable.ic_info,R.drawable.ic_live,R.drawable.ic_me};



                public SectionsPagerAdapter(FragmentManager fm) {

                    super(fm);

                }



                @Override

                public Fragment getItem(int position) {

                    return PlaceholderFragment.newInstance(tabs[position]);

                }



                @Override

                public int getCount() {

                    return tabs.length;

                }



                @Override

                public CharSequence getPageTitle(int position) {

            //            return tabs[position];

                    return setImageSpan(tabs[position],imgs[position]);

                }

            }

            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

            setImageSpan()方法同上






          14. 同上,使用Tab.setCustomView()

            修改pagerAdapter如下:



            /

              pagerAdapter

             
            /

            public class SectionsPagerAdapter extends FragmentPagerAdapter {



                String[] tabs = {"首頁","資訊","直播","我"};

                int[] imgs = {R.drawable.ic_home,R.drawable.ic_info,R.drawable.ic_live,R.drawable.ic_me};



                public SectionsPagerAdapter(FragmentManager fm) {

                    super(fm);

                }



                @Override

                public Fragment getItem(int position) {

                    return PlaceholderFragment.newInstance(tabs[position]);

                }



                @Override

                public int getCount() {

                    return tabs.length;

                }



                @Override

                public CharSequence getPageTitle(int position) {

            //            return tabs[position];

            //            return setImageSpan(tabs[position],imgs[position]);

                    return null;

                }



                /


                  設置自定義view

                 
            @param position

                  @return

                 
            /

                public View setCustomView(int position) {

                    View view = View.inflate(getApplicationContext(), R.layout.item_tab, null);

                    ImageView iv = (ImageView) view.findViewById(R.id.iv);

                    TextView tv = (TextView) view.findViewById(R.id.tv);

                    iv.setImageResource(imgs[position]);

                    tv.setText(tabs[position]);

                    return view;

                }

            }

            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

            代碼修改如下:



            …………

            // 綁定,要在viewpager設置完數據后,調用此方法,否則不顯示 tabs文本

            tabLayout.setupWithViewPager(mViewPager);



            // 為綁定viewpager后的TabLayout的tabs設置自定義view

            for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {

                tabLayout.getTabAt(i).setCustomView(mSectionsPagerAdapter.setCustomView(i));

            }

            1

            2

            3

            4

            5

            6

            7

            8

            發現問題:我使用的仍然是上面的item_tab,但是只顯示圖片,不顯示文字如下







            翻了翻源碼,也沒發現有對Tab的標題有特別的設置;后來,就感覺是不是顏色問題,給item_tab中的textview加上屬性android:textColor="@android:color/black",就顯示出來了







            六、FlycoTabLayout

            這是一個不錯的TabLayout開源項目,效果挺好,可以了解一下。





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

          jQuery中的Ajax操作

          seo達人

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

          jQuery對Ajax操作進行了封裝,常用的方法包括 $.get(),$.post(),$.ajax()。 
          分別對其進行介紹

          $.get()
          $.get()方法使用GET方式來進行異步請求。
          $.get()結構
          $.get(url,[. data][. callback][. type])
          1
          $.get()方法參數解釋
          參數名稱 類型 說明
          url String 請求的HTML頁的url地址
          data(可選) Object 發送至服務器的key/value數據會作為QueryString附加到請求的url中
          callback(可選) Function 載入成功時回調函數(只有當Response的返回狀態是success才調用該方法)自動將請求結果和狀態傳遞給該方法
          type(可選) String 服務器端返回內容的格式,包括xml、html、script、json、text和_default
          示例 
          json數據:data.json(后面的$.post()和$.ajax()方法都用這個數據)
          {
              "name":"龍貓",
              "hobby":"睡覺",
              "friend":"加菲貓"
          }

          jq_get.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Document</title>

          </head>
          <body>
              <input type="button" value="$.get方法" id="jQget">
              <div id="content"></div>
          </body>
          </html>
          <!-- 導入jquery.js文件 -->
          <script type="text/javascript" src="js/jquery.min.js"></script>
          <script type="text/javascript">
              $(function(){
                  $('#jQget').on('click',function(){

                      /*

                      參數1:url
                          參數2:發送的數據 支持 直接寫js對象的方式
                          參數3:回調函數
                          參數4:從服務端獲取的 數據類型 可以不寫
                          注意
                              如果type 為json 
                                  并且服務端返回的就是 json格式字符串
                                  jq內部 會幫助我們自動轉化
                                  在回調函數中 獲取的 實參 就是轉化完成的 js對象 直接使用即可

                          參數的 順序 是更換的
                              但是 如果 把data 放到后面 會出現 無法傳遞數據的問題,
                              所以 不要擅自更換 嚴格按照 jq文檔中的 順序 進行使用
                      */
                      $.get('jq_get.php',{name:"jack",age:18},function(data){
                              console.log(data);

                              $('#content').html('name:'+data.name+'<br>'+'hobby:'+data.hobby+'<br>'+'friend:'+data.friend); 

                      },'json');
                  });

              });
          </script>

          jq_get.php (后面的$.post()和$.ajax()方法都用這個頁面的內容,只是在html請求時分別對應的php頁面)

          <?php
              header('content-type:text/html;charset=utf-8');
              echo file_get_contents('datas/data.json');
          ?>

          結果展示: 


          $.post()方法
            它與$.get()方法的結構和使用方式都相同,不過它們之間仍然有以下區別:

          GET請求會將參數跟在URL后進行傳遞,而POST請求則是作為HTTP消息的實體內容發送個Web服務器,當然,在Ajax中,這種區別對用戶是不可見的。
          GET方式對傳輸的數據有大小限制(通常不能大于2KB),而使用POST方式傳遞的數據量要比GET方式大得多(理論上不受限制,但是可以在服務端進行限制)。
          GET方式請求的數據會被瀏覽器緩存起來,因此其他人就可以從瀏覽器的歷史記錄中讀取這些數據,例如賬號和密碼等。在某種情況下,GET方式會帶來嚴重的安全性問題,而POST方式相對來說就可以避免這些問題。(但是也是不安全的,所以密碼之類的還是要加密的)
          GET方式和POST方式傳遞的數據在服務器的獲取方式也不相同。在PHP中,GET方式數據可以用$_GET[]獲取,而POST可以用$_POST[]獲取、兩種方式都可以用$_REQUEST[]來獲取。 
          其實這完全是對這篇文章中post()和get()方法不同的總結?。?點擊查看) 
          $.post()演示
          <script type="text/javascript" src="js/jquery.min.js"></script>
          <script type="text/javascript">
              $(function(){
                  $('#jQpost').on('click',function(){
                      // 跟$.get用法及其類似
                      /*
                          參數1:url
                          參數2:發送的數據 支持 直接寫js對象的方式
                          參數3:回調函數
                          參數4:從服務端獲取的 數據類型 可以不寫,如果寫為json jq內部 會幫我們進行一個 JSON.parse()的轉化 
                      */
                       $.post('jq_post.php',{name:"kong",age:18},function(data){
                              console.log(data);
                       },'json');
                  });
              });
          </script>

          $.ajax()
          $.ajax()方法是jQuery最底層的Ajax實現
          其結構為
          $.ajax(options)
          1
          該方法只有1個參數,但在這個對象里包含了$.ajax()方法所需要的請求設置以及回調函數等信息,參數以key/value的形式存在,所有參數都是可選的,只寫幾個常用的參數,如下:

          參數名稱 類型 說明
          url String 請求的HTML頁的url地址
          type String 請求方式,默認GET。注意其他的HTTP請求方法,例如PUT和DELETE也可以使用,但僅部分瀏覽器支持
          data Object或String 發送到服務器的數據,如果已經不是字符串,將自動轉換為字符串格式。
          dataType String 服務器端返回內容的格式,包括xml、html、script、json、jsonp 、jQuery
          beforeSend Function 發送請求前可以修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次Ajax請求。XMLHttpRequest對象的唯一參數。
          success Function 請求成功后嗲用的回調函數,有兩個參數。
          (1)由服務器返回,并根據dataType參數進行處理后的數據。
          (2)描述狀態的字符串。
          function(data,textStatus){
                  //data可能是xmlDoc、jsonObj、html、text等等。
                  this//調用本次Ajax請求時傳遞的options參數
            }
          error Function 請求失敗時被調用的函數,該函數有3個參數,即
          XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。
          Ajax事件函數如下。
          function(XMLHttpRequest,textStatus,errorThrown){//通常情況下textStatus和errorThown只有其中一個包含信息
          this;//調用本次Ajax請求時傳遞的options參數
          }
          示例
          <script type="text/javascript" src="js/jquery.min.js"></script>
          <script type="text/javascript">
              $(function(){
                  $('#jqAjax').on('click',function(){
              /*
                          常見參數:
                              url:請求的地址
                              success:請求成功的回調函數
                              type:不寫是get 可以指定 get,post
                              dataType:數據的類型
                              data:發數據 可以寫js對象
                              beforeSend:發送之前調用的匿名函數
                                  可以return false 阻止該次請求
                                  驗證用戶的數據 是否填了
                              error:請求失敗以后 會調用
                      */
                      $.ajax({
                          url:'jq_ajax.php',
                          success:function(data){
                              console.log(data);
                              $('#box').append(data.name+'<br>'+data.hobby);
                          },
                          type:'post',
                          dataType:'json',
                          data:{"name":"張信哲","skill":"情歌王子"},
                          beforeSend:function(){
                              console.log('發送之前調用');
                          },
                          error:function(){
                              console.log('請求失敗了');
                          }
                      });
                  });

              });
          </script>
          --------------------- 
          作者:diligentkong 
          來源:CSDN 
          原文:https://blog.csdn.net/diligentkong/article/details/72851443 
          版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

          ionic用插件(cordova-plugin-baidumaplocation)定位并調百度地圖在上面顯示

          seo達人

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

          之前研究了定位,想用百度地圖,但是用百度地圖的 
          JavaScript API里面的瀏覽器定位根本不行,要用插件,很多人說本身帶的這個cordova-plugin-geolocation插件因為網絡問題,只有ios可以用,然后找到了專門針對安卓的cordova-qdc-baidu-location插件,但是這個插件不知道是不是我使用的問題,得到的數據可以彈出來,但是數據并不像這個插件所說的數據格式是

          {
            latitude : 緯度,
            lontitude: 經度, ... }
              
          • 1
          • 2
          • 3
          • 4
          • 5

          這樣的,而是字符串,不是json字符串,弄了半天還是取不到里面的關于經緯度的值,然后發現了現在的這個定位插件cordova-plugin-baidumaplocation這個插件返回的數據格式是json的,可以直接獲取。 
          因為網絡配代理的原因,一直添加不上插件,今天才發現用cordova-plugin-baidumaplocation插件定位其實挺簡單的。 
          1.申請AK值。 
          地址:http://lbsyun.baidu.com/ 
          需要申請兩個或者三個(配置ios),一個是js的,一個是android的(三個的話還有一個ios的,但是這邊直接只寫安卓的,其實ios是一樣的) 
          注:包名要一致 
          2.添加插件. 
          命令:

          cordova plugin add cordova-plugin-baidumaplocation --variable ANDROID_KEY="<API_KEY_ANDROID>" --variable IOS_KEY="<API_KEY_IOS>"
              
          • 1

          注意:是沒有<>這種尖括號的。 
          到此為止準備工作基本上晚了,開始代碼部分: 
          1.引入百度地圖:

          <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=nLsK9qUii8uBZlkPAQUozAf9mR5xNVZF"></script>
              
          • 1

          這個引入是為了轉化經緯度為地址和顯示地圖。 
          2.在html頁面上寫兩個 標簽:

          <button class="button" ng-click="getarea()">點擊我獲取地址百度</button> <div id='allmap' style=""></div>
              
          • 1
          • 2

          div標簽是為了放地圖的。 
          3.js部分:

          $scope.getarea=function(){ //myaddr(116.324499,39.899216); // 進行定位 baidumap_location.getCurrentPosition(function (result) { var latitude=result.latitude; var lontitude=result.lontitude;
                  myaddr(lontitude,latitude);
                }, function (error) { });
              } //根據定位得到的經緯度對地址進行解析 function myaddr(lontitude,latitude){ //alert("我的地址是:"+lontitude+","+latitude); // 百度地圖API功能 var map = new BMap.Map("allmap"); var point = new BMap.Point(lontitude, latitude);//34.7534880000,113.6313490000 map.centerAndZoom(point, 12); var marker = new BMap.Marker(point); // 創建標注 map.addOverlay(marker); // 將標注添加到地圖中 //把地址在地圖上標出來 var geoc = new BMap.Geocoder();
                geoc.getLocation(point, function(rs){ var addrmsg=rs.address; //var addComp = rs.addressComponents;  //詳細的分省市縣街道的信息 //alert(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber); var opts = {
                    width : 200, // 信息窗口寬度 height: 50, // 信息窗口高度 } var infoWindow = new BMap.InfoWindow("地址:"+addrmsg, opts); //創建信息窗口對象  map.openInfoWindow(infoWindow,point); //開啟信息窗口 }); 
          
              }
              
          • 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

          4.css部分:其實可以不要的,這是因為地圖中的地址顯示的窗口看起來有點問題,雖然改了依舊不好看,但是功能實現了。

          .BMap_pop{ top: 70px !important; } .BMap_bubble_content{ width: 95% !important; } .BMap_center{ top: 26px !important; }
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          注:現在得到的地址是省市縣街道地址,想得到諸如:北京市朝陽區XX大廈附近這樣的地址的話還沒有研究,等研究出來了再補上。 

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


          js 模塊化編程

          seo達人

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

          了解一個技術,首先要了解這個技術產生的背景及解決的問題,而不應該只是單純的知道該怎么用。之前的狀態可能就是只是為了了解而了解,并不知道實際產生的原因及帶來的好處,所以今天就來總結一下。

          1. 什么是模塊化編程

          來看百度百科的定義

          模塊化程序設計是指在進行程序設計時將一個大程序按照功能劃分為若干小程序模塊,每個小程序模塊完成一個確定的功能,并在這些模塊之間建立必要的聯系,通過模塊的互相協作完成整個功能的程序設計方法。

          比如 java 的 import,C# 的 using。我的理解是通過模塊化編程,可以將不同的功能獨立出來,修改某個功能時不會對其他功能產生影響。

          2. 為什么要模塊化

          來看下面一個例子

          // A.js function sayWord(type){ if(type === 1){
                  console.log("hello");
              }else if(type === 2){
                  console.log("world");
              }
          } // B.js function Hello(){ sayWord(1);
          } // C.js Hello()  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          假設上面三個文件,B.js 引用了 A.js 里面的內容,C.js 又引用了 B.js 里面的內容,如果編寫 C.js 的人只知道引用了 B.js,那他就不會引用 A.js 就會導致程序出錯,而且文件的引用順序也不能出錯。給整體代碼的調試修改帶來不便。

          還有個問題,上述代碼暴露了兩個全局變量,容易造成全局變量的污染

          3. AMD

          AMD 即 Asynchronous Module Definition(異步模塊定義)。采取異步加載的方式加載模塊,模塊的加載不會影響它后面的語句執行。而且只有用到的時候才會去加載相關文件,屬于瀏覽器端的標準

          假設下面這種情況

          // util.js define(function(){ return {
                  getFormatDate:function(date,type){ if(type === 1){ return '2018-08-9' } if(type === 2){ return '2018 年 8 月 9 日' }
                  }
              }
          }) // a-util.js define(['./util.js'],function(util){ return {
                  aGetFormatDate:function(date){ return util.getFormatDate(date,2)
                  }
              }
          }) // a.js define(['./a-util.js'],function(aUtil){ return {
                  printDate:function(date){ console.log(aUtil.aGetFormatDate(date))
                  }
              }
          }) // main.js require(['./a.js'],function(a){ var date = new Date()
              a.printDate(date)
          })
          console.log(1); // 使用 // <script src = "/require.min.js" data-main="./main.js"></script>   
          
          • 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

          頁面上先打印 1,然后才會打印 2018 年 8 月 9 日。因此 AMD 的加載并不會影響后續的語句執行。

          如果不是異步加載會出現什么情況呢

          var a = require('a');
          console.log(1) 
          
          • 1
          • 2

          后面的語句需要等待 a 加載完成才能執行,如果加載時間過長,整個程序都會卡在這。因此,瀏覽器不能同步加載資源,這也是 AMD 的產生背景。

          AMD 是在瀏覽器端實現模塊化開發的規范。由于該規范不是 JavaScript 原始支持的,使用 AMD 規范進行開發的時候需要引入第三方的庫函數,也就是 RequireJS。

          RequireJS 主要解決的問題

          • 使 JS 異步加載,避免頁面失去響應
          • 管理代碼之間的依賴性,有利于代碼的編寫和維護

          下面來看看如何使用 require.js

          要想使用 require.js,首先要 define

          // ? 代表該參數可選 define(id?, dependencies?, factory); 
          
          • 1
          • 2
          • id:指的是定義的模塊的名字
          • dependencies:是定義的模塊所依賴模塊的數組
          • factory:為模塊初始化要執行的函數或對象。如果為函數,它應該只被執行一次。如果是對象,此對象應該為模塊的輸出值。

            具體的規范說明可以參考 AMD (中文版) 
            舉個例子,創建一個名為 “alpha” 的模塊,使用了 require,exports,和名為 “beta” 的模塊:

          define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb();
                 }
             }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          一個返回對象的匿名模塊:

          define(["alpha"], function (alpha) { return {
                   verb: function(){ return alpha.verb() + 2;
                   }
                 };
             }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          一個沒有依賴性的模塊可以直接定義對象:

          define({
               add: function(x, y){ return x + y;
               }
             }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          如何使用

          AMD 采用 require 語句加載模塊

          require([module],callback); 
          
          • 1
          • module:是一個數組,里面的成員是要加載的模塊
          • callback:加載成功之后的回調函數

          例如

          require(['./a.js'],function(a){ var date = new Date()
              a.printDate(date)
          }) 
          
          • 1
          • 2
          • 3
          • 4

          具體的使用方法如下

          // util.js define(function(){ return {
                  getFormatDate:function(date,type){ if(type === 1){ return '2018-08-09' } if(type === 2){ return '2018 年 8 月 9 日' }
                  }
              }
          }) // a-util.js define(['./util.js'],function(util){ return {
                  aGetFormatDate:function(date){ return util.getFormatDate(date,2)
                  }
              }
          }) // a.js define(['./a-util.js'],function(aUtil){ return {
                  printDate:function(date){ console.log(aUtil.aGetFormatDate(date))
                  }
              }
          }) // main.js require(['./a.js'],function(a){ var date = new Date()
              a.printDate(date)
          }) // 使用 // <script src = "/require.min.js" data-main="./main.js"></script>  
          
          • 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

          假設這里有 4 個文件,util.js,a-util.js 引用了 util.js,a.js 引用了 a-util.js,main.js 引用了 a.js。

          其中,data-main 屬性的作用是加載網頁程序的主模塊。

          上例演示了一個主模塊最簡單的寫法,默認情況下,require.js 假設依賴和主模塊在同一個目錄。

          使用 require.config() 方法可以對模塊的加載行為進行自定義。require.config() 就寫在主模塊(main.js)的頭部,參數是一個對象,這個對象的 paths 屬性指定各個模塊的加載路徑

          require.config({
              paths:{ "a":"src/a.js", "b":"src/b.js" }
          }) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6

          還有一種方法是改變基礎目錄(baseUrl)

          require.config({
          
              baseUrl: "src",
          
              paths: { "a": "a.js", "b": "b.js",
          
              }
          
            }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          4. CommonJS

          commonJS 是 nodejs 的模塊化規范,現在被大量用在前端,由于構建工具的高度自動化,使得使用 npm 的成本非常低。commonJS 不會異步加載 JS,而是同步一次性加載出來

          在 commonJS 中,有一個全局性的方法 require(),用于加載模塊,例如

          const util = require('util'); 
          
          • 1

          然后,就可以調用 util 提供的方法了

          const util = require('util'); var date = new date();
          util.getFormatDate(date,1); 
          
          • 1
          • 2
          • 3

          commonJS 對于模塊的定義分三種,模塊定義(exports),模塊引用(require)和模塊標示(module)

          exports() 對象用于導出當前模塊的變量或方法,唯一的導出口。require() 用來引入外部模塊。module 對象代表模塊本身。

          舉個栗子

          // util.js module.exports = {
              getFormatDate:function(date, type){ if(type === 1){ return '2017-06-15' } if(type === 2){ return '2017 年 6 月 15 日' }
              }
          } // a-util.js const util = require('util.js')
          module.exports = {
              aGetFormatDate:function(date){ return util.getFormatDate(date,2)
              }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19

          或者下面這種方式

           // foobar.js // 定義行為 function foobar(){ this.foo = function(){ console.log('Hello foo');
                  } this.bar = function(){ console.log('Hello bar');
                    }
           } // 把 foobar 暴露給其它模塊 exports.foobar = foobar; // main.js //使用文件與模塊文件在同一目錄 var foobar = require('./foobar').foobar,
          test = new foobar();
          test.bar(); // 'Hello bar' 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18

          5. ES6 Module

          ES6 模塊的設計思想是盡量靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量,而 CommonJS 和 AMD 模塊都只能在運行時確定這些關系。如 CommonJS 加載方式為 “運行時加載”,ES6 的加載方式為 “編譯時加載” 或者靜態加載,即 ES6 可以在編譯時就完成模塊加載,效率比 CommonJS 模塊的加載方式高。

          ES6 模塊自動采用嚴格模式,不管有沒有在模塊頭部加上 “use strict”。

          ES6 export 語句輸出的接口與其對應的值是動態綁定關系,即通過該接口可以取到模塊內部實時的值。而 CommonJS 模塊輸出的是值的緩存,不存在動態更新。

          ES6 與 CommonJS 模塊的差異

          • CommonJS 模塊輸出的是一個值的復制,ES6 模塊輸出的是值的引用。
          • CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。
          • CommonJS 中的 this 指向當前模塊,ES6 模塊 this 為 undefined

          第二個差異是因為 CommonJS 加載的是一個對象(即 Module.exports 屬性),該對象只有在腳本運行結束時才會生成,而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。

          總結

          CommonJS 采用了服務器優先的策略,使用同步方式加載模塊,而 AMD 采用異步加載的方式。所以如果需要使用異步加載 js 的話建議使用 AMD,而當項目使用了 npm 的情況下建議使用 CommonJS。

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


          微信小程序開發(四)獲取用戶openid

          seo達人

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

          在小程序里面有兩個地方獲取用戶的openid。 
          一個是wx.login(OBJECT),第二個是wx.getUserInfo(OBJECT)。 
          這里我使用的是第一種wx.login(OBJECT)。

          步驟

           wx.login({
            success: function(res) { if (res.code) { //  第一步: 獲取code //發起網絡請求 wx.request({
                  url: '后臺接口', // 獲取openid data: {
                    code: res.code
                  }
                })
              } else {
                console.log('獲取用戶登錄態失??!' + res.errMsg)
              }
            }
          }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15

          后端的實現

          后端的實現就是后端調用這個接口:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code。 
          這里寫圖片描述

          /*
           * 根據code獲取微信用戶的openid
           */ router.get('/api/getWxCode', function(req, res, next) { var param = req.query || req.params; var code = param.code; var urlStr = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + wxConfig.AppID + '&secret=' + wxConfig.Secret + '&js_code=' + code + '&grant_type=authorization_code';
              request(urlStr, function (error, response, body) { if (!error && response.statusCode == 200) { var jsBody = JSON.parse(body); 
                      jsBody.status = 100;
                      jsBody.msg = '操作成功';
                      res.end(JSON.stringify(jsBody));
                  }
              })
          }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          具體實例

          /**
           * 生命周期函數--監聽頁面加載
           */ onLoad: function (options) { var self = this;
            wx.login({
              success: function (res) { if (res.code) { //發起網絡請求 wx.request({
                    url: 'https://www.hgdqdev.cn/api/getWxCode',
                    data: {
                      code: res.code
                    },
                    success: function(res){ if(res.data.status == 100){ self.setData({
                          openid: res.data.openid
                        })
                      }
                    },
                    fail: function(){ }
                  })
                } else {
                  console.log('獲取用戶登錄態失??!' + res.errMsg)
                }
              }
            });
          },

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


          日歷

          鏈接

          個人資料

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

          存檔

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