---
# System prepended metadata

title: 瀏覽器＆瀏覽器相容性

---

# 瀏覽器＆瀏覽器相容性
做個有格調的前端，尊嚴要顧
「什麼？你們公司要兼容 IE6 以下？ 我們今天面試就到這裡吧告辭！」

---
Can I use? https://caniuse.com/

### 瀏覽器、瀏覽器引擎（內核）

了解瀏覽器相容性前，必須知道現在主流的瀏覽器以及核心處理器
目前主流瀏覽器與其使用的引擎核心：
- IE → Trident  → -ms
- Firefox → Gecko → -moz
- Chrome → Blink
- Edge → Blink
- Safari → webkit  → -webkit
- Opera → Blink

### 瀏覽器引擎：
:::warning
(!) 別跟 JS 引擎搞混
:::

瀏覽器引擎（或稱為排版引擎、渲染引擎）是每個瀏覽器的運作核心，功能在於轉譯 HTML 文件 、其他網頁資源（ 例如 CSS ）成人類可看懂的交互式畫面。

瀏覽器引擎並不是一個獨立的計算機程序，而是發動更大的程序（例如整個網頁瀏覽器）。除了佈局跟渲染外，瀏覽器引擎還會負責執行安全策略，像是超連結、表單發送數據出去，以及生成 DOM 結構給 JS 腳本使用。

負責執行 JS 的引擎跟瀏覽器引擎是不同的，雖然過去 JS 主要是為了瀏覽器使用，但現在 JS 應用在更多的地方，因此 JS 引擎從瀏覽器引擎中分離出來。他們兩個目前是透過 DOM 物件協同合作。

除了網頁瀏覽器外，瀏覽器引擎其實還使用在其他類型的應用，像是電子郵件 client 顯示 email、Electron 使用兩種 Google Chrome 瀏覽器引擎來做桌面應用城市。

### 瀏覽器相容問題：
後來眾多瀏覽器的出現，結束了 IE 稱王的時代。現在瀏覽器會盡量符合 w3c 標準，但他們自己也會擴展功能，促使 w3c 推進。那也因如此各瀏覽器對於畫面的處理都有自己的見解，導致相容性的問題，為我們開發帶來不少難度。

白話一點，瀏覽器相容性問題在於「同樣的程式碼，在不同瀏覽器上的畫面與效果不一樣，因為他們使用不同的瀏覽器引擎，處理事情的思路不同」。

### 判斷處理相容性問題的優先級：
- 產品的需求：功能優先？效果優先？
- 產品的受眾：受眾的瀏覽器比例
- 產品的目標族群：目標族群的習性
- 成本角度：是否有時間、人力、金錢去做兼容

## 怎麼處理？
首先避免人為失誤 - 遵循 W3C 規範、多了解準則、多了解瀏覽器
:::info
瀏覽器相容問題可以大致分為三類
- CSS 佈局樣式相關
- JS 交互腳本相關
- 以上兩種之外的，大多屬於功能性問題，像是瀏覽器自身提供的功能，在瀏覽器引擎之上的。
:::

#### CSS 相容問題

- 透過 CSS Reset 或者 Normalize 抹平差異
- 預處理器：前端框架、SASS、打包工具
- IE 的 img title 沒有作用、opacity 要用 filter 取代

#### JS 相容問題

- ES6 語法 → babel 編譯
- Event 事件
- new Date() 的 2018-07-05
- 用 document.documentElement.scrollTop 兼容 chrome 以外的瀏覽器
```jsx
var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
```
除此之外，還有很多．．．建議大家自己擁有一個專門紀錄相容問題的筆記

#### 瀏覽器 hack （參考網路資料，尚未實作）
- 判斷 IE 版本
用 HTML 判斷

    ```jsx
    <!--[if IE 8]> ie8 <![endif]-->

    <!--[if IE 9]> ie9 <![endif]-->

    // 非 IE 跟 IE10、IE11 可用
    <!--[if !IE]><!-->
    <script>
        $.getScript("<{file js/xxx.min.js }>",function(){});
    </script>
    <!--<![endif]-->
    ```

    也可以用

    ```jsx
    if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
         // MSIE
    }
    ```

- 判斷 Safari

```jsx
/* Safari */
var isSafari = /a/.__proto__=='//';
```

- 判斷 Chrome

```jsx
/* Chrome */
var isChrome = Boolean(window.chrome);
```