面試題(包括一些ie的兼容)

ajax、axios、fetch 的異同點?(這種問題一般直接分別說三者的特點)

ajax

$.ajax({
   type: 'POST',
   url: 'xxxx',
   data: 'xxxxx',
   dataType: 'xxxxx',
   success: function () {},
   error: function () {}
});

特點:

  • ajax 是基於 MVC模式的,沒有適應 MVVM 的大軍
  • ajax 是基於 XMLHttpRequest(XHR)進行的封裝,api 操作不夠簡潔
  • 基於Jquery , 不能夠被單獨使用(必須引入jquery,有點坑爹)
  • 異步請求不是特別友好,操作繁瑣
  • 有新生的fetch即將取代

axios

axios({
    method: 'post',
    url: 'xxxxx',
    data: {
        firstName: 'xxxx',
        lastName: 'xxxxx'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

特點:

  • 支持 Promise API
  • 是從 node.js 創建 http 請求
  • 提供豐富的 api
  • 支持請求、響應攔截
  • 客戶端支持防止CSRF
  • 自動進行數據的裝換(默認返回JSON數據)

fetch

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

特點:

  • 脫離的 XHR,直接掛載在window對象上
  • API豐富,更加底層
  • 使用上更加簡潔
  • 不支持超時控制
  • 無法檢測進度
  • 瀏覽器的支持不夠友好

仁者見仁,智者見智,不管白貓黑貓,能抓老鼠就是好貓,喜歡那個用哪個,沒有絕對的好壞

vue中在哪個階段進行異步請求比較合適(阿里,百度),爲什麼?

一般在 created 裏面就可以,如果涉及到需要頁面加載完成之後對頁面有操作的的話就用 mounted。

vue中vuex的mapSetter是怎麼實現的

vue中vuex的mapSetter實現原理

export function mapGetters (getters) {
  const res = {}
  normalizeMap(getters).forEach(({ key, val }) => {
    res[key] = function mappedGetter () {
      if (!(val in this.$store.getters)) {
        console.error(`[vuex] unknown getter: ${val}`)
      }
      return this.$store.getters[val]
    }
  })
  return res
}

function normalizeMap (map) {
  return Array.isArray(map)
    ? map.map(key => ({ key, val: key }))
    : Object.keys(map).map(key => ({ key, val: map[key] }))
}

ES6 模塊與 CommonJS 模塊的差異

阮一峯教程

什麼是尾遞歸?

參見阮一峯的es6

application cache是怎麼設置的(網易)

該特性已經從 Web 標準中刪除,只做簡單瞭解
參見MDN文檔

vue項目中使用到的優化手段

根據項目實際情況,怎麼用就這麼說,千萬別給自己挖坑

解決瀏覽器的兼容問題

html5shiv.js

解決 ie9 以下瀏覽器對 html5 新增標籤不識別的問題。

<!--[if lt IE 9]>
  <script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->
respond.js

解決 ie9 以下瀏覽器不支持 CSS3 Media Query 的問題。

<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
picturefill.js

解決 IE 9 10 11 等瀏覽器不支持 標籤的問題

<script src="https://cdn.bootcss.com/picturefill/3.0.3/picturefill.min.js"></script>
瀏覽器 CSS 兼容前綴
-o-transform:rotate(7deg); // Opera

-ms-transform:rotate(7deg); // IE

-moz-transform:rotate(7deg); // Firefox

-webkit-transform:rotate(7deg); // Chrome

transform:rotate(7deg); // 統一標識語句
完美解決 Placeholder
<input type="text" value="Name *" onFocus="this.value = '';" onBlur="if (this.value == '') {this.value = 'Name *';}">
清除浮動 最佳實踐
.fl { float: left; }
.fr { float: right; }
.clearfix:after { display: block; clear: both; content: ""; visibility: hidden; height: 0; }
.clearfix { zoom: 1; }
BFC 解決邊距重疊問題

當相鄰元素都設置了 margin 邊距時,margin 將取最大值,捨棄小值。爲了不讓邊距重疊,可以給子元素加一個父元素,並設置該父元素爲 BFC:overflow: hidden;

<div class="box" id="box">
  <p>Lorem ipsum dolor sit.</p>

  <div style="overflow: hidden;">
    <p>Lorem ipsum dolor sit.</p>
  </div>

  <p>Lorem ipsum dolor sit.</p>
</div>
解決 IE9 以下瀏覽器不能使用 opacity
opacity: 0.5;
filter: alpha(opacity = 50);
filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);
鍵盤事件 keyCode 兼容性寫法
var inp = document.getElementById('inp')
var result = document.getElementById('result')

function getKeyCode(e) {
  e = e ? e : (window.event ? window.event : "")
  return e.keyCode ? e.keyCode : e.which
}

inp.onkeypress = function(e) {
  result.innerHTML = getKeyCode(e)
}
求窗口大小的兼容寫法
// 瀏覽器窗口可視區域大小(不包括工具欄和滾動條等邊線)
// 1600 * 525
var client_w = document.documentElement.clientWidth || document.body.clientWidth;
var client_h = document.documentElement.clientHeight || document.body.clientHeight;

// 網頁內容實際寬高(包括工具欄和滾動條等邊線)
// 1600 * 8
var scroll_w = document.documentElement.scrollWidth || document.body.scrollWidth;
var scroll_h = document.documentElement.scrollHeight || document.body.scrollHeight;

// 網頁內容實際寬高 (不包括工具欄和滾動條等邊線)
// 1600 * 8
var offset_w = document.documentElement.offsetWidth || document.body.offsetWidth;
var offset_h = document.documentElement.offsetHeight || document.body.offsetHeight;

// 滾動的高度
var scroll_Top = document.documentElement.scrollTop||document.body.scrollTop;
跨瀏覽器事件對象
var EventUtil = {
  // 事件監聽(添加事件)
  addHandler: function(element, type, handler) {
    if (element.addEventListener) {
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
      element.attachEvent("on" + type, handler);
    } else {
      element["on" + type] = handler;
    }
  },
  // 事件監聽(移除事件)
  removeHandler: function(element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
      element.detachEvent("on" + type, handler);
    } else {
      element["on" + type] = null;
    }
  },
  // 獲取事件對象
  getEvent: function(event) {
    return event ? event : window.event;
  },
  // 獲取目標對象
  getTarget: function(event) {
    return event.target || event.srcElement;
  },
  // 組織默認事件
  preventDefault: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  },
  // 阻止冒泡
  stopPropagation: function(event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
  },
  //  獲取鍵碼
  getCharCode: function(event) {
    if (typeof event.charCode == "number") {
      return event.charCode;
    } else {
      return event.keyCode; // IE8及之前版本
    }
    0;
  },
  // mousewheel 事件  非常流行,而且所有瀏覽器都支持它,所以 HTML 5 也加入了該事件 )
  getWheelDelta: function(event) {
    if (event.wheelDelta) {
      return client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta;
    } else {
      return -event.detail * 40;
    }
  },
  // 跨瀏覽器取得相關元素(鼠標當前進入的元素)
  getRelatedTarget: function(event) {
    if (event.relatedTarget) {
      return event.relatedTarget;
    } else if (event.toElement) {
      return event.toElement; // IE9+
    } else if (event.fromElement) {
      return event.fromElement; // IE8
    } else {
      return null;
    }
  },
  // 獲取剪切版的內容
  getClipboardText: function(event) {
    var clipboardData = event.clipboardData || window.clipboardData;
    return clipboardData.getData("text");
  },
  // 發送剪切版的內容
  setClipboardText: function(event, value) {
    if (event.clipboardData) {
      return event.clipboardData.setData("text/plain", value);
    } else if (window.clipboardData) {
      return window.clipboardData.setData("text", value);
    }
  }
};
// 跨瀏覽器的寫法:獲取鼠標頁面座標位置
EventUtil.addHandler(div, "click", function(event) {
  event = EventUtil.getEvent(event);
  let obj = {};
  (obj.pageX = event.pageX), (obj.pageY = event.pageY);
  if (pageX === undefined) {
    pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
  }
  if (pageY === undefined) {
    pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
  }
  return obj;
});
// 某個鼠標事件發生時,通過檢測這幾個屬性就可以確定用戶是否同時按下了其中的鍵。
EventUtil.addHandler(div, "click", function(event) {
  event = EventUtil.getEvent(event);
  var keys = new Array();
  (event.shiftKey) && (keys.push("shift"));
  (event.ctrlKey) && (keys.push("ctrl"));
  (event.altKey) && (keys.push("alt"));
  (event.metaKey) && (keys.push("meta"));
  window.console.log("Keys: " + keys.join(","));
});

更多的乾貨請點擊這裏
react-native 實戰項目學習
歡迎各位看官的批評和指正,共同學習和成長
希望該文章對您有幫助,也希望得到您的鼓勵和支持

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章