成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

高程3總結(jié)#第22章高級(jí)技巧

CKJOKER / 3296人閱讀

摘要:如果構(gòu)造函數(shù)竊取結(jié)合使用原型鏈或者寄生組合則可以解決這個(gè)問題惰性載入函數(shù)惰性載入表示函數(shù)執(zhí)行的分支僅會(huì)發(fā)生一次。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。,用于注銷某個(gè)事件類型的事件處理程序。

高級(jí)技巧 高級(jí)函數(shù) 安全的類型檢測

typeof操作符在檢測數(shù)據(jù)類型時(shí),可能會(huì)得到不靠譜的結(jié)果

instanceof操作符在存在多個(gè)全局作用域,也就是頁面包含多個(gè)iframe的情況下,也會(huì)出現(xiàn)問題

在任何值上調(diào)用Object原生的toString()方法,都會(huì)返回一個(gè)[object NativeConstructorName]格式的字符串

原生數(shù)組的構(gòu)造函數(shù)名與全局作用域無關(guān),因此使用toString()就能保證返回一致的值

function isArray(value){
  return Object.prototype.toString.call(value)=="[object Array]";
}

基于這一思路來測試某個(gè)值是不是原生函數(shù)或正則表達(dá)式

function isFunction(value){
  return Object.prototype.toString.call(value)=="[object Function]";
}
function isRegExp(value){
  return Object.prototype.toString.call(value)=="[object RegExp]";
}

作用域安全的構(gòu)造函數(shù)

作用域安全的構(gòu)造函數(shù)在進(jìn)行任何更改之前,首先確認(rèn)this對象是正確類型的實(shí)例,如果不是,那么會(huì)創(chuàng)建新的實(shí)例并返回

function Person(name, age, job){
  if (this instanceof Person){
    this.name = name;
    this.age = age;
    this.job = job;
  } else {
    return new Person(name, age, job);
  }
}
var person1 = Person("Nicholas", 29, "Software Engineer");
alert(window.name); //""
alert(person1.name); //"Nicholas"
var person2 = new Person("Shelby", 34, "Ergonomist");
alert(person2.name); //"Shelby

使用構(gòu)造函數(shù)竊取模式的繼承且不適用原型鏈,這個(gè)繼承可能被破壞

function Polygon(sides){
  if (this instanceof Polygon) {
    this.sides = sides;
    this.getArea = function(){
      return 0;
    };
  } else {
    return new Polygon(sides);
  }
}
function Rectangle(width, height){
  Polygon.call(this, 2);
  this.width = width;
  this.height = height;
  this.getArea = function(){
    return this.width * this.height;
  };
}
var rect = new Rectangle(5, 10);
alert(rect.sides); //undefined

上面的代碼中,Polygon構(gòu)造函數(shù)是作用域安全的,然而Rectangle構(gòu)造函數(shù)則不是。如果構(gòu)造函數(shù)竊取結(jié)合使用原型鏈或者寄生組合則可以解決這個(gè)問題

function Polygon(sides){
  if (this instanceof Polygon) {
    this.sides = sides;
    this.getArea = function(){
      return 0;
    };
  } else {
    return new Polygon(sides);
  }
}
function Rectangle(width, height){
  Polygon.call(this, 2);
  this.width = width;
  this.height = height;
  this.getArea = function(){
    return this.width * this.height;
  };
}
Rectangle.prototype = new Polygon();
var rect = new Rectangle(5, 10);
alert(rect.sides); //2

惰性載入函數(shù)

惰性載入表示函數(shù)執(zhí)行的分支僅會(huì)發(fā)生一次。

第一種實(shí)現(xiàn)惰性載入的方法,在函數(shù)被調(diào)用時(shí)再處理函數(shù)。在第一次調(diào)用的過程中,該函數(shù)會(huì)覆蓋為另一個(gè)按何時(shí)方式執(zhí)行的函數(shù),這樣任何對原函數(shù)的調(diào)用都不用再經(jīng)過執(zhí)行的分支了

function createXHR(){
  if (typeof XMLHttpRequest != "undefined"){
    createXHR = function(){
      return new XMLHttpRequest();
    };
  } else if (typeof ActiveXObject != "undefined"){
    createXHR = function(){
      if (typeof arguments.callee.activeXString != "string"){
        var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                        "MSXML2.XMLHttp"],
            i, len;
        for (i=0,len=versions.length; i < len; i++){
          try {
            new ActiveXObject(versions[i]);
            arguments.callee.activeXString = versions[i];
            break;
          } catch (ex){
            //skip
          }
        }
      }
      return new ActiveXObject(arguments.callee.activeXString);
    };
  } else {
    createXHR = function(){
      throw new Error("No XHR object available.");
    };
  }
  return createXHR();
}

第二種實(shí)現(xiàn)惰性載入的方式是在聲明函數(shù)時(shí)就指定適當(dāng)?shù)暮瘮?shù),這樣,第一次調(diào)用函數(shù)時(shí)就不會(huì)喪失性能了,而在代碼首次加載的時(shí)候回?fù)p失一點(diǎn)性能

var createXHR = (function(){
  if (typeof XMLHttpRequest != "undefined"){
    return function(){
      return new XMLHttpRequest();
    };
  } else if (typeof ActiveXObject != "undefined"){
    return function(){
      if (typeof arguments.callee.activeXString != "string"){
        var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                        "MSXML2.XMLHttp"],
            i, len;
        for (i=0,len=versions.length; i < len; i++){
          try {
            new ActiveXObject(versions[i]);
            arguments.callee.activeXString = versions[i];
            break;
          } catch (ex){
            //skip
          }
        }
      }
      return new ActiveXObject(arguments.callee.activeXString);
    };
  } else {
    return function(){
      throw new Error("No XHR object available.");
    };
  }
})();

函數(shù)綁定

一個(gè)簡單的bind()函數(shù)接受一個(gè)函數(shù)和一個(gè)環(huán)境,并返回一個(gè)在給定環(huán)境中調(diào)用給定函數(shù)的函數(shù),并且將所有參數(shù)原封不動(dòng)傳遞過去

function bind(fn, context){
  return function(){
    return fn.apply(context, arguments);
  };
}

當(dāng)調(diào)用返回的函數(shù)時(shí),它會(huì)在給定環(huán)境中執(zhí)行被傳入的函數(shù)并給出所有參數(shù)

var handler = {
  message: "Event handled",
  handleClick: function(event){
    alert(this.message);
  }
};
var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler))

ECMAScript5為所有函數(shù)定義了一個(gè)原生的bind()方法,進(jìn)一步簡單了操作,不用再自己定義bind()函數(shù)了,而是可以直接在函數(shù)上調(diào)用這個(gè)方法

var handler = {
  message: "Event handled",
  handleClick: function(event){
    alert(this.message + ":" + event.type);
  }
};
var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));

函數(shù)的柯里化

用于創(chuàng)建已經(jīng)設(shè)置好了一個(gè)或者多個(gè)參數(shù)的函數(shù)。函數(shù)柯里化的基本方法和函數(shù)綁定是一樣的。使用一個(gè)閉包返回一個(gè)函數(shù),兩者的區(qū)別在于,當(dāng)函數(shù)被調(diào)用時(shí),返回的函數(shù)還需要設(shè)置一些傳入的參數(shù)

柯里化函數(shù)通常由一下步驟動(dòng)態(tài)創(chuàng)建:調(diào)用另一個(gè)函數(shù)并為它傳入要柯里化的函數(shù)和必要參數(shù)

function curry(fn){
  var args = Array.prototype.slice.call(arguments, 1);
  return function(){
    var innerArgs = Array.prototype.slice.call(arguments);
    var finalArgs = args.concat(innerArgs);
    return fn.apply(null, finalArgs);
  };
}

ECMAScript5的bind()方法也實(shí)現(xiàn)函數(shù)柯里化,只要在this的值之后再傳入另一個(gè)參數(shù)即可

var handler = {
  message: "Event handled",
  handleClick: function(name, event){
    alert(this.message + ":" + name + ":" + event.type);
  }
};
var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "my-btn"));

防篡改對象 不可擴(kuò)展對象

默認(rèn)情況下,所有對象都是可以擴(kuò)展的,也就是說,任何時(shí)候都可以向?qū)ο笾刑砑訉傩院头椒?/p>

Object.preventExtensions()方法可以改變這個(gè)行為,不能再給對象添加屬性和方法

var person={name:"Nicholas"};
Object.preventExtensions(person);
person.age=29;
alert(person.age);//undefined

Object.isExtensible()方法還可以確定對象是否可以擴(kuò)展

var person={name:"Nicholas"};
alert(Object.isExtensible(person));//true
Object.preventExtensions(person);
alert(Object.isExtensible(person));//true

密封的對象

封閉對象不可擴(kuò)展,而且已有成員[Configurable]特性將被設(shè)置為false,這就意味著不能刪除屬性和方法,因?yàn)椴荒苁褂肙bject.defineProperty()把數(shù)據(jù)屬性修改為訪問器屬性

var person = { name: "Nicholas" };
Object.seal(person);
person.age = 29;
alert(person.age); //undefined
delete person.name;
alert(person.name); //"Nicholas"

Object.isSealed()方法可以確定對象是否被密封了,因?yàn)楸幻芊獾膶ο蟛豢蓴U(kuò)展,所以用Object.isExtensible()檢測密封的對象也會(huì)返回false

var person = { name: "Nicholas" };
alert(Object.isExtensible(person)); //true
alert(Object.isSealed(person)); //false
Object.seal(person);
alert(Object.isExtensible(person)); //false
alert(Object.isSealed(person)); //true

凍結(jié)的對象

凍結(jié)的對象既不可擴(kuò)展又是密封的,而且對象數(shù)據(jù)屬性的[Writable]特性會(huì)被設(shè)置為false,如果定義[Set]函數(shù),訪問器屬性仍然是可寫的。ECMAScript5丁意思的Object.freeze()方法可以用來凍結(jié)對象

var person = { name: "Nicholas" };
Object.freeze(person);
person.age = 29;
alert(person.age); //undefined
delete person.name;
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"

Object.isFrozen()方法用于檢測凍結(jié)對象,因?yàn)閮鼋Y(jié)對象既是密封的又是不可擴(kuò)展的,所以O(shè)bject.isExtensible()和Object.isSealed()檢測凍結(jié)對象將分別返回false和true

var person = { name: "Nicholas" };
alert(Object.isExtensible(person)); //true
alert(Object.isSealed(person)); //false
alert(Object.isFrozen(person));  //false
Object.freeze(person);
alert(Object.isExtensible(person)); //false
alert(Object.isSealed(person)); //true
alert(Object.isFrozen(person)); //true

高級(jí)定時(shí)器 重復(fù)的定時(shí)器

使用setInterval()創(chuàng)建的定時(shí)器確保了定時(shí)器代碼規(guī)則地插入隊(duì)列中

使用setInterval()時(shí),僅當(dāng)沒有該定時(shí)器的任何其他代碼實(shí)現(xiàn)時(shí),才將定時(shí)器代碼添加到隊(duì)列中,這確保了定時(shí)器加入到隊(duì)列中的最小時(shí)間間隔為指定間隔

重復(fù)定時(shí)器有兩個(gè)問題:某些間隔會(huì)被跳過;多個(gè)定時(shí)器的代碼執(zhí)行之間的間隔可能會(huì)比預(yù)期小

為了避免setInterval()的重復(fù)定時(shí)器的兩個(gè)問題,使用鏈?zhǔn)絪etTimeout()調(diào)用

setTimeout(function(){
  //處理中
  setTimeout(arguments.callee, interval);
}, interval);

這個(gè)模式主要用于重復(fù)定時(shí)器

setTimeout(function(){
  var div = document.getElementById("myDiv");
  left = parseInt(div.style.left) + 5;
  div.style.left = left + "px";
  if (left < 200){
    setTimeout(arguments.callee, 50);
  }
}, 50)

Yielding Processes

腳本長時(shí)間運(yùn)行的問題通常是由兩個(gè)原因之一造成的:過長的、過深嵌套的函數(shù)調(diào)用或者是進(jìn)行大量處理的循環(huán)

兩個(gè)重要問題:該處理是否必須同步完成;數(shù)據(jù)是否必須按順序完成

如果兩個(gè)問題回答都是否,可以使用定時(shí)器分隔這個(gè)循環(huán),即數(shù)組分塊技術(shù)

小塊小塊地處理數(shù)組,通常每次一小塊,基本的思路是為要處理的項(xiàng)目創(chuàng)建一個(gè)隊(duì)列,然后使用定時(shí)器取出下一個(gè)要處理的項(xiàng)目進(jìn)行處理,接著再設(shè)置另一個(gè)定時(shí)器

setTimeout(function(){
  //取出下一個(gè)條目并處理
  var item = array.shift();
  process(item);
  //若還有條目,再設(shè)置另一個(gè)定時(shí)器
  if(array.length > 0){
    setTimeout(arguments.callee, 100);
  }
}, 100);

數(shù)組分塊模式中,array變量本質(zhì)上就是一個(gè)列表,包含了要處理的項(xiàng)目。使用shift()方法獲取隊(duì)列中要處理的項(xiàng)目,然后將其傳遞給某個(gè)函數(shù)。如果在隊(duì)列中還有其他項(xiàng)目,則設(shè)置另一個(gè)定時(shí)器,并通過arguments.callee調(diào)用同一個(gè)匿名函數(shù),要實(shí)現(xiàn)數(shù)組分塊非常簡單,可以使用下面的函數(shù)

function chunk(array, process, context){
  setTimeout(function(){
    var item = array.shift();
    process.call(context, item);
    if (array.length > 0){
      setTimeout(arguments.callee, 100);
    }
  }, 100);
}

chunk()方法接收三個(gè)參數(shù):要處理的項(xiàng)目的數(shù)組,用于處理項(xiàng)目的函數(shù),以及可選的運(yùn)行該函數(shù)的環(huán)境

var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342];
function printValue(item){
  var div = document.getElementById("myDiv");
  div.innerHTML += item + "
"; } chunk(data, printValue);

函數(shù)節(jié)流

函數(shù)節(jié)流背后的基本思想是指,某些代碼不可以在沒有間斷的情況連續(xù)重復(fù)執(zhí)行。第一次調(diào)用函數(shù),創(chuàng)建一個(gè)定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè)。如果前一個(gè)定時(shí)器已經(jīng)執(zhí)行過了,這個(gè)操作就沒有任何意義。然而,如果前一個(gè)定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個(gè)新的定時(shí)器。目的是只有在執(zhí)行函數(shù)的請求停止了一段時(shí)間之后才執(zhí)行。

var processor = {
  timeoutId: null,
  //實(shí)際進(jìn)行處理的方法
  performProcessing: function(){
    //實(shí)際執(zhí)行的代碼
  },
  //初始處理調(diào)用的方法
  process: function(){
    clearTimeout(this.timeoutId);
    var that = this;
    this.timeoutId = setTimeout(function(){
      that.performProcessing();
    }, 100);
  }
};
//嘗試開始執(zhí)行
processor.process();

自定義事件

觀察者模式由兩類對象組成:主體和觀察者。主體負(fù)責(zé)發(fā)布事件,同時(shí)觀察者通過訂閱這些事件來觀察該主體

自定義事件背后的概念是創(chuàng)建一個(gè)管理事件的對象,讓其他對象監(jiān)聽事件

function EventTarget(){
  this.handlers = {};
}
EventTarget.prototype = {
  constructor: EventTarget,
  addHandler: function(type, handler){
    if (typeof this.handlers[type] == "undefined"){
      this.handlers[type] = [];
    }
    this.handlers[type].push(handler);
  },
  fire: function(event){
    if (!event.target){
      event.target = this;
    }
    if (this.handlers[event.type] instanceof Array){
      var handlers = this.handlers[event.type];
      for (var i=0, len=handlers.length; i < len; i++){
        handlers[i](event);
      }
    }
  },
  removeHandler: function(type, handler){
    if (this.handlers[type] instanceof Array){
      var handlers = this.handlers[type];
      for (var i=0, len=handlers.length; i < len; i++){
        if (handlers[i] === handler){
          break;
        }
      }
      handlers.splice(i, 1);
    }
  }
};

EventTarget類型有一個(gè)多帶帶的屬性handlers ,用于儲(chǔ)存事件處理程序。

還有三個(gè)方法:

addHandler() ,用于注冊給定類型事件的事件處理程序

addHandler() 方法接受兩個(gè)參數(shù):事件類型和用于處理該事件的函數(shù)。當(dāng)調(diào)用該方法時(shí),會(huì)進(jìn)行一次檢查,看看 handlers 屬性中是否已經(jīng)存在一個(gè)針對該事件類型的數(shù)組;如果沒有,則創(chuàng)建一個(gè)新的。然后使用 push() 將該處理程序添加到數(shù)組的末尾。

fire() ,用于觸發(fā)一個(gè)事件

如果要觸發(fā)一個(gè)事件,要調(diào)用 fire() 函數(shù)。該方法接受一個(gè)多帶帶的參數(shù),是一個(gè)至少包含 type屬性的對象。 fire() 方法先給 event 對象設(shè)置一個(gè) target 屬性,如果它尚未被指定的話。然后它就查找對應(yīng)該事件類型的一組處理程序,調(diào)用各個(gè)函數(shù),并給出 event 對象。

removeHandler() ,用于注銷某個(gè)事件類型的事件處理程序。

removeHandler() 方法是 addHandler() 的輔助,它們接受的參數(shù)一樣:事件的類型和事件處理程序。這個(gè)方法搜索事件處理程序的數(shù)組找到要?jiǎng)h除的處理程序的位置。如果找到了,則使用 break操作符退出 for 循環(huán)。然后使用 splice() 方法將該項(xiàng)目從數(shù)組中刪除。

function handleMessage(event){
  alert("Message received: " + event.message);
}
//創(chuàng)建一個(gè)新對象
var target = new EventTarget();
//添加一個(gè)事件處理程序
target.addHandler("message", handleMessage);
//觸發(fā)事件
target.fire({ type: "message", message: "Hello world!"});
//刪除事件處理程序
target.removeHandler("message", handleMessage);
//再次,應(yīng)沒有處理程序
target.fire({ type: "message", message: "Hello world!"});
拖放

基本實(shí)現(xiàn)過程

var DragDrop = function(){
  var dragging = null;
  function handleEvent(event){
    //獲取事件和目標(biāo)
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
    //確定事件類型
    switch(event.type){
      case "mousedown":
        if (target.className.indexOf("draggable") > -1){
          dragging = target;
        }
        break;
      case "mousemove":
        if (dragging !== null){
          //指定位置
          dragging.style.left = event.clientX + "px";
          dragging.style.top = event.clientY + "px";
        }
        break;
      case "mouseup":
        dragging = null;
        break;
    }
  };
  //公共接口
  return {
    enable: function(){
      EventUtil.addHandler(document, "mousedown", handleEvent);
      EventUtil.addHandler(document, "mousemove", handleEvent);
      EventUtil.addHandler(document, "mouseup", handleEvent);
    },
    disable: function(){
      EventUtil.removeHandler(document, "mousedown", handleEvent);
      EventUtil.removeHandler(document, "mousemove", handleEvent);
      EventUtil.removeHandler(document, "mouseup", handleEvent);
    }
  }
}();

修繕拖動(dòng)功能

為防止出現(xiàn)上圖情況。計(jì)算元素左上角和指針位置之間的差值。這個(gè)差值應(yīng)該在 mousedown 事件發(fā)生的時(shí)候確定,并且一直保持,直到 mouseup 事件發(fā)生。通過將 event的 clientX 和 clientY 屬性與該元素的 offsetLeft 和 offsetTop 屬性進(jìn)行比較,就可以算出水平方向和垂直方向上需要多少空間

var DragDrop = function(){
  var dragging = null;
  diffX = 0;
  diffY = 0;
  function handleEvent(event){
    //獲取事件和目標(biāo)
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
    //確定事件類型
    switch(event.type){
      case "mousedown":
        if (target.className.indexOf("draggable") > -1){
          dragging = target;
          diffX = event.clientX - target.offsetLeft;
          diffY = event.clientY - target.offsetTop;
        }
        break;
      case "mousemove":
        if (dragging !== null){
          //指定位置
          dragging.style.left = (event.clientX - diffX) + "px";
          dragging.style.top = (event.clientY - diffY) + "px";
        }
        break;
      case "mouseup":
        dragging = null;
        break;
    }
  };
  //公共接口
  return {
    enable: function(){
      EventUtil.addHandler(document, "mousedown", handleEvent);
      EventUtil.addHandler(document, "mousemove", handleEvent);
      EventUtil.addHandler(document, "mouseup", handleEvent);
    },
    disable: function(){
      EventUtil.removeHandler(document, "mousedown", handleEvent);
      EventUtil.removeHandler(document, "mousemove", handleEvent);
      EventUtil.removeHandler(document, "mouseup", handleEvent);
    }
  }
}()

添加自定義事件
var DragDrop = function(){
var dragdrop = new EventTarget(),
    dragging = null,
    diffX = 0,
    diffY = 0;
function handleEvent(event){
  //獲取事件和對象
  event = EventUtil.getEvent(event);
  var target = EventUtil.getTarget(event);
  //確定事件類型
  switch(event.type){
    case "mousedown":
      if (target.className.indexOf("draggable") > -1){
        dragging = target;
        diffX = event.clientX - target.offsetLeft;
        diffY = event.clientY - target.offsetTop;
        dragdrop.fire({type:"dragstart", target: dragging,
                       x: event.clientX, y: event.clientY});
      }
      break;
    case "mousemove":
      if (dragging !== null){
        //指定位置
        dragging.style.left = (event.clientX - diffX) + "px";
        dragging.style.top = (event.clientY - diffY) + "px";
        // 觸發(fā)自定義事件
        dragdrop.fire({type:"drag", target: dragging,
                       x: event.clientX, y: event.clientY});
      }
      break;
    case "mouseup":
      dragdrop.fire({type:"dragend", target: dragging,
                     x: event.clientX, y: event.clientY});
      dragging = null;
      break;
  }
};
//公共接口
dragdrop.enable = function(){
  EventUtil.addHandler(document, "mousedown", handleEvent);
  EventUtil.addHandler(document, "mousemove", handleEvent);
  EventUtil.addHandler(document, "mouseup", handleEvent);
};
dragdrop.disable = function(){
  EventUtil.removeHandler(document, "mousedown", handleEvent);
  EventUtil.removeHandler(document, "mousemove", handleEvent);
  EventUtil.removeHandler(document, "mouseup", handleEvent);
};
return dragdrop;
}();

這段代碼定義了三個(gè)事件: dragstart 、 drag 和 dragend 。它們都將被拖動(dòng)的元素設(shè)置為了 target ,并給出了 x 和 y 屬性來表示當(dāng)前的位置。它們觸發(fā)于 dragdrop 對象上,之后在返回對象前給對象增加 enable() 和 disable() 方法。這些模塊模式中的細(xì)小更改令 DragDrop 對象支持了事件

DragDrop.addHandler("dragstart", function(event){
  var status = document.getElementById("status");
  status.innerHTML = "Started dragging " + event.target.id;
});
DragDrop.addHandler("drag", function(event){
  var status = document.getElementById("status");
  status.innerHTML += "
Dragged " + event.target.id + " to (" + event.x + "," + event.y + ")"; }); DragDrop.addHandler("dragend", function(event){ var status = document.getElementById("status"); status.innerHTML += "
Dropped " + event.target.id + " at (" + event.x + "," + event.y + ")"; });

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98189.html

相關(guān)文章

  • 高程3總結(jié)#3基本概念

    摘要:基本概念語法區(qū)分大小寫,中的一切變量函數(shù)名和操作符都區(qū)分大小寫。要將一個(gè)值轉(zhuǎn)換成對應(yīng)的值,可以調(diào)用類型包括整數(shù)和浮點(diǎn)數(shù)值,基本數(shù)值字面量格式是十進(jìn)制整數(shù),除了十進(jìn)制外還有八進(jìn)制十六進(jìn)制。八進(jìn)制第一位必須是,十六進(jìn)制第一位必須是。 基本概念 語法 區(qū)分大小寫,ECMAScript中的一切(變量、函數(shù)名和操作符)都區(qū)分大小寫。函數(shù)名不能使用typeof,因?yàn)樗且粋€(gè)關(guān)鍵字,但typeOf...

    Rindia 評(píng)論0 收藏0
  • 高程3總結(jié)#4變量、作用域和內(nèi)存問題

    摘要:當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對象的一個(gè)作用域鏈。作用域鏈的用途,是保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個(gè)對象。 變量、作用域和內(nèi)存問題 基本類型和引用類型的值 基本類型值指的是簡單的數(shù)據(jù)段,而引用類型值值那些可能由多個(gè)值構(gòu)成的對象。 定義基本類型值的引用和引用類型值的方法是類似的,創(chuàng)建...

    xumenger 評(píng)論0 收藏0
  • 高程3總結(jié)#9客戶端檢測

    摘要:能力檢測無法精確地檢測特定的瀏覽器和版本。用戶代理檢測通過檢測用戶代理字符串來識(shí)別瀏覽器。用戶代理檢測需要特殊的技巧,特別是要注意會(huì)隱瞞其用戶代理字符串的情況。 客戶端檢測 能力檢測 能力檢測的目的不是識(shí)別特定的瀏覽器,而是識(shí)別瀏覽器的能力,采用這種方式不必顧忌特定的瀏覽器,只要確定瀏覽器支持的特定的能力,就能給出解決方案,檢測基本模式 if(object.propertyInQu...

    BigNerdCoding 評(píng)論0 收藏0
  • 高程3總結(jié)#8BOM

    摘要:對象的核心對象是,它表示瀏覽器的一個(gè)實(shí)例。而和則表示該容器中頁面視圖區(qū)的大小。在中,與返回相同的值,即視口大小而非瀏覽器窗口大小。第三個(gè)參數(shù)是一個(gè)逗號(hào)分隔的設(shè)置字符串,表示在新窗口中都顯示哪些特性。這應(yīng)該是用戶打開窗口后的第一個(gè)頁面 BOM window對象 BOM的核心對象是window,它表示瀏覽器的一個(gè)實(shí)例。在瀏覽器中,window對象有雙重角色,它既是通過JavaScript訪...

    MASAILA 評(píng)論0 收藏0
  • 高程3總結(jié)#7函數(shù)表達(dá)式

    摘要:匿名函數(shù)可以用來模仿塊級(jí)作用域來避免這個(gè)問題這里是塊級(jí)作用域代碼定義并立即調(diào)用了一個(gè)匿名函數(shù),將函數(shù)聲明包含在一對圓括號(hào)中,表示它實(shí)際上是一個(gè)函數(shù)表達(dá)式,而緊隨其后的另一對圓括號(hào)會(huì)立即調(diào)用這個(gè)函數(shù)。 函數(shù)表達(dá)式 遞歸 遞歸函數(shù)是在一個(gè)函數(shù)通過名字調(diào)用自身的情況下構(gòu)成的 function factrial(num){ if(num

    sevi_stuo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

CKJOKER

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<