1. 程式人生 > >前端小問題總結(一)

前端小問題總結(一)

旨在記錄自己在實際專案中遇見的一些小問題,簡單做個記錄。以便以後翻閱。

document.domain

通常,解決跨域問題的方法有:
1. document.domain
2. jsonp
3. iframe
4. 代理
5. CORS

用document.domain來指定域,是可以的,但是有侷限性,也就是一級域名一致才可以。
參考document.domain

拖動

ondragstart 事件在使用者開始拖動元素或選擇的文字時觸發。

PS:

  1. 為了讓元素可拖動,需要使用 HTML5 draggable=true 屬性。
  2. 連結和圖片預設是可拖動的,不需要 draggable 屬性。
  3. Internet Explorer 8 及更早 IE 版本或 Safari 5.1 及更早版本的瀏覽器不支援 drag 事件。
    在拖放的過程中會觸發以下事件:
    在拖動目標上觸發事件 (源元素):
    • ondragstart - 使用者開始拖動元素時觸發
    • ondrag - 元素正在拖動時觸發
    • ondragend - 使用者完成元素拖動後觸發

釋放目標時觸發的事件:
+ ondragenter - 當被滑鼠拖動的物件進入其容器範圍內時觸發此事件
+ ondragover - 當某被拖動的物件在另一物件容器範圍內拖動時觸發此事件
+ ondragleave - 當被滑鼠拖動的物件離開其容器範圍內時觸發此事件
+ ondrop - 在一個拖動過程中,釋放滑鼠鍵時觸發此事件

bind()

bind() 方法的主要作用就是將函式繫結至某個物件,bind() 方法會建立一個函式,函式體內this物件的值會被繫結到傳入bind() 函式的值

1. 原理

Function.prototype.bind = function(context) {
 var self = this; // 儲存原函式
 return function() { // 返回一個新函式
  return self.apply(context, arguments); // 執行新函式時,將傳入的上下文context作為新函式的this
 }
}

2. bind的應用場景

實現物件繼承

var A = function(name) {
 this.name = name;
}

var B = function() {
 A.bind(this, arguments);
}

B.prototype.getName = function() {
 return this.name;
}

var b = new B("hello");
console.log(b.getName()); // "hello"

事件處理

var paint = {
 color: "red",
 count: 0,
 updateCount: function() {
  this.count++;
  console.log(this.count);
 }
};

// 事件處理函式繫結的錯誤方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount); // paint.updateCount函式的this指向變成了該DOM物件

// 事件處理函式繫結的正確方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount.bind(paint)); // paint.updateCount函式的this指向變成了paint

時間間隔函式

var notify = {
 text: "Hello World!",
 beforeRender: function() {
  console.log(this.text);
 },
 render: function() {

  // 錯誤方法:
  setTimeout(this.beforeRender, 0); // undefined

  // 正確方法:
  setTimeout(this.beforeRender.bind(this), 0); // "Hello World!"
 }
};

notify.render();

借用Array的原生方法

var a = {};
Array.prototype.push.bind(a, "hello", "world")();

console.log(a); // "hello", "world"

3. 與call/apply的區別

共同點:

都可以改變函式執行的上下文環境;

不同點:

bind: 不立即執行函式,一般用在非同步呼叫和事件; call/apply: 立即執行函式。

console

  1. console.assert(expression, obj[, obj...])

接收至少兩個引數,第一個引數的值或返回值為false的時候,將會在控制檯上輸出後續引數的值. eg:

console.assert(1 == 1, object); // 無輸出,返回 undefined  
console.assert(1 == 2, object); // 輸出 object
  1. console.error(obj[, obj...])

用於輸出錯誤資訊,用法和常見的console.log一樣,不同點在於輸出內容會標記為錯誤的樣式,便於分辨。

  1. console.dir(obj)

將傳入物件的屬性,包括子物件的屬性以列表形式輸出. eg:

var obj = { name: 'classicemi', college: 'HUST', major: 'ei'};  
console.dir(obj);
  1. console.group()

能夠讓控制檯輸出的語句產生不同的層級巢狀關係,每一個console.group()會增加一層巢狀,相反要減少一層巢狀可以使用console.groupEnd()方法。和console.group()相似的方法是console.groupCollapsed()作用相同,不同點是巢狀的輸出內容是摺疊狀態,在有大段內容輸出的時候使用這個方法可以使輸出版面不至於太長吧.

  1. console.info(obj[, obj...])
    與之前說到的console.error一樣,用於輸出資訊,沒有什麼特別之處。

  2. console.table()

可將傳入的物件,或陣列以表格形式輸出,相比傳統樹形輸出,這種輸出方案更適合內部元素排列整齊的物件或陣列,不然可能會出現很多的 undefined。實際中感覺用得少。

  1. console.profile([profileLabel])

藉助控制檯以及console.profile()方法我們可以很方便地監控執行效能。

  1. console.time(name)

將成對的console.time()和console.timeEnd()之間程式碼的執行時間輸出到控制檯上,name引數可作為標籤名。

  1. console.trace()

console.trace()用來追蹤函式的呼叫過程。在大型專案尤其是框架開發中,函式的呼叫軌跡可以十分複雜,console.trace()方法可以將函式的被呼叫過程清楚地輸出到控制檯上。

  1. console.warn(object[, object...])

輸出引數的內容,作為警告提示。

console物件上的五個直接輸出方法,console.log(),console.warn(),console.error(),console.exception()(等同於console.error())和console.info(),都可以使用佔位符。支援的佔位符有四種,分別是字元(%s)、整數(%d或%i)、浮點數(%f)和物件(%o)。 eg:

console.log('%s是%d年%d月%d日', '今天', 2014, 4, 15);
console.log('圓周率是%f', 3.14159);
var obj = { name: 'classicemi'}
console.log('%o', obj);

還有一種特殊的標示符%c,對輸出的文字可以附加特殊的樣式,當進行大型專案開發的時候,程式碼中可能有很多其他開發者新增的控制檯語句。開發者對自己的輸出定製特別的樣式就可以方便自己在眼花繚亂的輸出結果中一眼看到自己需要的內容。 eg:

console.log('%cMy name is classicemi.', 'color: #fff; background: #f40; font-size: 24px;');