1. 程式人生 > >JavaScript基礎(3)-JS中的面向物件、定時器、BOM、位置資訊

JavaScript基礎(3)-JS中的面向物件、定時器、BOM、位置資訊

一、建立物件的幾種常用方式、

1、使用Object或物件字面量建立物件;

       a、使用Object()內建的建構函式來建立物件,例如:

    var student = new Object();  // 建立一個student物件
    student.name = "easy";  // 屬性name
    student.age = 20;  // 屬性age

      b、字面量方式,例如:

    var student = {
        name : "easy",
        age : 20
    };

2、工廠模式建立物件;

       JS中沒有類的概念,那麼我們不妨就使用一種函式將以上物件建立過程封裝起來以便於重複呼叫,同時可以給出特定介面來初始化物件,例如:

  function createStudent(name, age){
      var obj = new Object();
      obj.name = name;
      obj.age = age;
      return obj;
  }
  function createFruit(name, color){
      var obj = new Object();
      obj.name = name;
      obj.color = color;
      return obj;
  }
  var s1 = createStudent("easy", 20);
  var f1 = createFruit("apple", "green");
  console.log(s1,f1); 
  // Object {name: "easy", age: 20} Object {name: "apple", color: "green"}

       總結:對於以上程式碼建立的物件s1、f1,我們用instanceof操作符去檢測,他們統統都是Object型別,而我們希望s1是Student型別的,而f1是Fruit型別的,為了實現這個目標,我們可以用自定義建構函式的方法來建立物件。

3、建構函式模式建立物件;

       上面建立Object這樣的原生物件的時候就使用過其建構函式:var obj = new Object();

       建立原生陣列Array型別物件時也使用過其建構函式:var obj = new Array();

       那麼我們現在介紹一下建構函式和普通函式有什麼區別:

              a、實際上並不存在建立建構函式的特殊語法,其與普通函式唯一的區別在於呼叫方法。對於任意函式,使用new操作符呼叫,那麼它就是建構函式;不使用new操作符呼叫,那麼它就是普通函式;

              b、按照慣例,我們約定建構函式名以大寫字母開頭,普通函式以小寫字母開頭,這樣有利於顯性區分二者,例如上面的new Array(),new Object();

              c、使用new操作符呼叫建構函式時,會經歷(1)建立一個新物件;(2)將建構函式作用域賦給新物件(使this指向該新物件);(3)執行建構函式程式碼;(4)返回新物件;四個階段;

       瞭解建構函式和普通函式的區別後,我們用建構函式將工廠模式的函式重寫,並新增一個方法屬性,如:c

  function Student(name, age) {   // 自定義建構函式Student
      this.name = name;
      this.age = age;
      this.alertName = function(){
          alert(this.name)
      };
  }
  function Fruit(name, color) {   // 自定義建構函式Fruit
      this.name = name;
      this.color = color;
      this.alertName = function(){
          alert(this.name)
      };
  }
  var s1 = new Student("easy", 20);
  var f1 = new Fruit("apple", "green");

  console.log(s1 instanceof Student);  // true
  console.log(f1 instanceof Fruit);  // true
  console.log(s1 instanceof Object);  // true  任何物件均繼承自Object
  console.log(f1 instanceof Object);  // true  任何物件均繼承自Object

       總結:這樣我們解決了工廠模式無法區分物件型別的尷尬,但是使用建構函式來建立物件時,我們發現,Student和Fruit物件中有同樣的方法,所以我們完全可以將物件方法(函式)移到建構函式外部,於是就有了原型模式建立物件。

 

4、原型模式建立物件;

       原型鏈甚至原型繼承,是整個JS中最難的一部分也是最不好理解的一部分,在此沒有過多介紹,對js有興趣的話,可以去查閱一下相關JS原型的一些知識點。

       下面是原型模式建立物件的示例:

  function Student() {
      this.name = 'easy';
      this.age = 20;
  }
  Student.prototype.alertName = function(){
  // Student.prototype是Student的父類
      alert(this.name);
  };
  var stu1 = new Student();
  var stu2 = new Student();

  stu1.alertName();  // easy
  stu2.alertName();  // easy
  alert(stu1.alertName == stu2.alertName);  // true 二者共享同一函式

二、定時器

       js中的定時器分兩種:setTimeout()、setInterval()。

       setTimeout()和setInterval()是HTML DOM Window物件的兩個方法。

1、setTimeout():在指定的毫秒數後執行指定程式碼(一次性定時器)

       語法:myVar = window.setTimeout(回撥函式,毫秒數);  例如:

  <button>點我</button>
  <p>取消</p>
  <script type="text/javascript">
      var oBtn = document.getElementsByTagName('button')[0];
      var oP = document.getElementsByTagName('p')[0];
      oBtn.onclick = function myFunction(){
          var timer = setTimeout(function(){
              alert("Hello")
          },3000);
      }
      oP.onclick = function () {
          clearTimeout(timer); // 停止執行setTimeout()方法的函式程式碼
      }
  </script>

       總結:

    1)window.setTimeout 和window.clearTimeout()方法可以不使用window 字首;

    2)一次性定時器可以做非同步(資料互動時,若資料阻塞了,可以考慮加一個一次性定時器來處理);

 

2、setInterval():間隔指定的毫秒數不停地執行指定的程式碼,例如:

       語法:window.setInterval(回撥函式,毫秒數);  例如:

  <p>頁面上顯示時鐘:</p>
  <p id="demo"></p>
  <button onclick = "myStopFunction()">停止</button>
  <script>
      var timer = setInterval(function(){myTimer()},1000);
      function myTimer(){
          var d = new Date();
          var t = d.toLocaleTimeString();
          document.getElementById("demo").innerHTML = t;
      }
      function myStopFunction(){
          clearInterval(timer);
      }
  </script>

       總結:

    1)window.setInterval()和window.clearInterval()方法可以不使用window字首;

    2)可以做動畫;

       注意:js跟python一樣,都有垃圾回收機制,但是垃圾回收不能收回定時器物件,所以記得關定時器。兩種方法根據不同的場景和業務需求擇而取之,對於這兩個方法,需要注意的是如果要求在每隔一個固定的時間間隔後就精確地執行某動作,那麼最好使用setInterval,而如果不想由於連續呼叫產生互相干擾的問題,尤其是每次函式的呼叫需要繁重的計算以及很長的處理時間,那麼最好使用setTimeout。

三、BOM

       BOM:Browser Object Model,瀏覽器物件模型。

       window物件是BOM的頂級(核心)物件,所有物件都是通過它延伸出來的,也可以稱為window的子物件。因此DOM是BOM的一部分。

  window物件:

    window物件是JavaScript中的頂級物件;

    全域性變數、自定義函式也是window物件的屬性和方法;

    window物件下的屬性和方法呼叫時,可以省略window;

       下面介紹幾個BOM的常見內建方法和內建物件:

1、開啟視窗、關閉視窗

    window.open(url,target); // window可不寫
    // url: 要開啟的地址    target: _blank 、_self 、_parent 

2、location物件

       window.location可以簡寫成location。location相當於瀏覽器位址列,可以將url解析成獨立的片段。

       a、location物件的屬性:

    1)href:跳轉;

    2)hash: 返回url中#後面的內容,包含#;

    3)host: 主機名,包括埠;

    4)hostname: 主機名;

    5)pathname: url中的路徑部分;

    6)protocol: 協議,一般是http、https;

    7)search: 查詢字串;

       b、location物件的方法:

    1)location.reload():重新載入,例如:

    setTimeout(function(){
         // 3 秒之後讓網頁整個重新整理
        window.location.reload();
    },3000)

3、history物件(用的不多,因為瀏覽器中已自帶了這些功能的按鈕)

       window.history 物件包含瀏覽器的歷史,在編寫時可不使用 window 這個字首。

       a、後退(與在瀏覽器點選後退按鈕相同)

    history.back();

    history.go(-1);

       b、前進(與在瀏覽器中點擊向前按鈕相同)

    history.forward();

    history.go(1);

       c、重新整理(與在瀏覽器中點選重新整理鈕相同)

    history.go(0);

 

4、navigator物件

       window.navigator 物件包含有關訪問者瀏覽器的資訊,在編寫時可不使用 window 這個字首。

       window.navigator 的一些屬性可以獲取客戶端的一些資訊,例如:

    userAgent:使用者代理,系統,瀏覽器;

    platform:硬體平臺,瀏覽器支援的系統,win/mac/linux;

       注意:來自 navigator 物件的資訊具有誤導性,不應該被用於檢測瀏覽器版本,這是因為:

    1)navigator 資料可被瀏覽器使用者更改;

    2)一些瀏覽器對測試站點會識別錯誤;

    3)瀏覽器無法報告晚於瀏覽器釋出的新作業系統;

 

四、位置資訊(client、offset、scroll系列)

1、client系列

  <div class="box" style="width: 200px; height: 200px; border: 10px solid red; padding: 80px;"></div>
  <script type="text/javascript">
       /*
       * clientTop 內容區域到邊框頂部的距離,說白了,就是邊框的高度
       * clientLeft 內容區域到邊框左部的距離,說白了就是邊框的寬度
       * clientWidth 內容區域 + 左右padding   可視寬度
       * clientHeight 內容區域 + 上下padding   可視高度
       */
      var oBox = document.getElementsByClassName('box')[0];
      console.log(oBox.clientTop);  // 10
      console.log(oBox.clientLeft);  // 10
      console.log(oBox.clientWidth);  // 360
      console.log(oBox.clientHeight)  // 360
  </script>

       應用:獲取螢幕的可視區域  

  <script type="text/javascript">
      // 螢幕的可視區域
      window.onload = function(){
          // document.documentElement 獲取的是html標籤
          console.log(document.documentElement.clientWidth);
          console.log(document.documentElement.clientHeight);
          // 視窗大小發生變化時,會呼叫此方法
          window.onresize = function(){
              console.log(document.documentElement.clientWidth);
              console.log(document.documentElement.clientHeight);
          }
      }
  </script>

2、offset系列

  <div class="wrap" style=" width: 300px; height: 300px; background-color: green; margin-left: 20px; position: relative;">
      <div id="box" style="width: 200px; height: 200px; border: 5px solid red; position: absolute; top:50px; left: 30px;">
      </div>
  </div>
  </body>
  <script type="text/javascript">
      window.onload = function(){
          var oBox = document.getElementById('box');
          /*
          * offsetWidth 佔位寬  內容 + padding + border
          * offsetHeight 佔位高
          * offsetTop: 如果盒子沒有設定定位 到body的頂部的距離,如果盒子設定定位,那麼是以父輩為基準的top值
          * offsetLeft: 如果盒子沒有設定定位 到body的左部的距離,如果盒子設定定位,那麼是以父輩為基準的left值
          */
          console.log(oBox.offsetWidth); // 210
          console.log(oBox.offsetHeight);  // 210
          console.log(oBox.offsetTop);  // 50
          console.log(oBox.offsetLeft); // 30
      }
  </script>

3、scroll系列

  <div class="wrap" style=" width: 300px; height: 300px; background-color: green; margin-left: 20px; position: relative;">
      <div id="box" style="width: 200px; height: 200px; border: 5px solid red; position: absolute; top:50px; left: 30px;">
      </div>
  </div>
  </body>
  <script type="text/javascript">
      window.onload = function(){
          var oBox = document.getElementById('box');
          /*
          * offsetWidth 佔位寬  內容 + padding + border
          * offsetHeight 佔位高
          * offsetTop: 如果盒子沒有設定定位 到body的頂部的距離,如果盒子設定定位,那麼是以父輩為基準的top值
          * offsetLeft: 如果盒子沒有設定定位 到body的左部的距離,如果盒子設定定位,那麼是以父輩為基準的left值
          */
          console.log(oBox.offsetWidth); // 210
          console.log(oBox.offsetHeight);  // 210
          console.log(oBox.offsetTop);  // 50
          console.log(oBox.offsetLeft); // 30
      }
  </script>
複製程式碼
3、scroll系列

複製程式碼
  <body style="width: 2000px; height: 2000px;">
      <div style="height: 200px;background-color: red;"></div>
      <div style="height: 200px;background-color: green;"></div>
      <div style="height: 200px;background-color: yellow;"></div>
      <div style="height: 200px;background-color: blue;"></div>
      <div style="height: 200px;background-color: gray;"></div>
      <div id = 'scroll' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;">
          <p style="height: 800px;">這裡是內容</p>
      </div>
  </body>
  <script type="text/javascript">
      window.onload = function(){
          //實時監聽滾動事件
          window.onscroll = function(){
          console.log(1111);
          console.log('上'+document.documentElement.scrollTop);
          console.log('左'+document.documentElement.scrollLeft);
          console.log('寬'+document.documentElement.scrollWidth);
          console.log('高'+document.documentElement.scrollHeight);
          };

          var oS = document.getElementById('scroll');
          oS.onscroll = function(){
          // scrollHeight : 內容的高度 + padding  不包含邊框
              console.log('上'+oS.scrollTop);
              console.log('左'+oS.scrollLeft);
              console.log('寬'+oS.scrollWidth);
              console.log('高'+oS.scrollHeight);
          }
      }
  </script>