FixedMidashiで縦スクロールした時にIEの時だけヘッダが上下にがたつく挙動の対処法

　業務で複数の行および列が固定されたテーブルを作成するにあたり、[FixedMidashi.js](http://hp.vector.co.jp/authors/VA056612/fixed_midashi/manual/index.html)を使用しました。大変使いやすいライブラリですが、IEで縦スクロールを行ったときに上部ヘッダが一瞬上下にがたつくため、その対処法を記載します。

## 発生条件
1. ブラウザ ⇒ IE（私はIE11を使用しています。下のバージョンで現象が発生するかは未確認です）。
2. 縦スクロールが**一番上**にある状態でマウスホイールでスクロール

## FixedMidashiを用いたテーブルの用意
まず[FixedMidashi公式ページの使用方法](http://hp.vector.co.jp/authors/VA056612/fixed_midashi/manual/index.html#usage)に従ってテーブルを作成しました。
※業務では**divモード**を使用したので、**divモード**で記載します。

　・tableタグをdivタグで囲み、そのdivタグにclassを付けます。
　　（本記事では`class="scroll_div"`を付与）
　・``<table>``に `_fixedhead="rows:x; cols:y"`を付けます。
　　（x,yにはそれぞれ固定したい行数、列数を記載）

```html

<body>
    <div class="scroll_div">
        <table _fixedhead="rows:2; cols:2">
            
　　　　　　～省略～

        </table>
    </div>
</body>
```
onloadイベントで`FixedMidashi.create()`を呼び出します。

```js
window.onload = function () {
            FixedMidashi.create();
}
```

・bodyタグを囲っている``<div class="scroll_div">``に`overflow: auto`を付けます。

``` css
table tr,
table th,
table td {
    border: 1px solid black;
}
table {
    border-collapse: collapse;
    white-space: nowrap;
    box-sizing: content-box;
}
.scroll_div {
    overflow: auto;
    width: 312px; /* 任意の数字*/
    height: 159px; /* 任意の数字*/
}
```
![table.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401696/bda9ac64-3fba-df2f-8e97-0d4e693ee437.png)

## 対応方法

FixedMidashiの公式ページに以下の記載があります。
> FixedMidashiは固定する見出し部分を別 table にコピーし、それを元 table の上に重ねて表示する、 という方法で実現しています

　　FixedMidashi公式ページの概要より引用（http://hp.vector.co.jp/authors/VA056612/fixed_midashi/manual/index.html#summary）

　対応方法としては元テーブルの上に重ねて表示された固定見出しに手を加えることになります。
### 行固定見出しへの対応

**縦スクロール前**
　行固定見出しが`visibility: hidden`となっています。
![scroll.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401696/3883851c-f901-0a72-8221-9d78bbda22da.png)

**縦スクロール後**
　`visibility: visible`となります。
![scrolled.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401696/aa4bcb21-7bbc-1732-cb79-9a65d3930b16.png)

一番上からスクロールした時に行固定見出しの`visibility`の値が`hidden`から`visible`へ変わり、またスクロールを一番上へ戻すと`visible`から`hidden`へ変わります。
これががたつきの要因となっています。
ここで、`visibility`が常に`visible`となるクラスを作成します。

``` css
// スクロールがたつき対応
.copyheader_visible {
   visibility: visible !important;
}
```
スクロールバーが一番上に来た時に行固定見出しに`class="copyheader_visible"`を追加します。

``` js
 // IEの時のみ対応
 if (navigator.userAgent.match(/MSIE 10/i) || navigator.userAgent.match(/Trident\/7\./)) {
     // 行固定見出しに、スクロールがたつき対応クラスを追加
     $(".scroll_div").eq(2).addClass("copyheader_visible");

     $(".scroll_div").scroll(function () {
        // 縦スクロール量を取得
        var scrollTop = $('.scroll_div').scrollTop();

       if (scrollTop == 0) {
          // 縦スクロールの位置が一番上に来た時
          var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
          if (!topHeaderVisible) {
            // 行固定見出しをvisibleとする
            $('.scroll_div').eq(2).addClass('copyheader_visible');
          }
       } else {
          var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
          if (topHeaderVisible) {
             $('.scroll_div').eq(2).removeClass('copyheader_visible');
          }
       }
  })
            
```
### 行列固定見出しへの対応
このままだと横スクロールをした時に行固定見出しが左へ突き出てしまいます。
![scrollLeft.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401696/15d58b69-ba25-aeeb-852d-cccfc8743e39.png)

そのため、縦スクロールをしていない状態で横スクロールを行った際に**行列固定見出し**の`visibility`が常に`visible`となるようにします。

``` js
  /* ～該当箇所のみ抜粋～ */

 // 縦スクロール量を取得
 var scrollTop = $('.scroll_div').scrollTop();
// 横スクロール量を取得
 var scrollLeft = $('.scroll_div').scrollLeft();

 if (scrollTop == 0 && scrollLeft == 0) {
    // 縦スクロールの位置が一番上かつ、横スクロールの位置が一番左の時
    var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
    if (!topHeaderVisible) {
        // 行固定見出しをvisibleとする
        $('.scroll_div').eq(2).addClass('copyheader_visible');
    }
 }else if(scrollTop == 0 && scrollLeft != 0){
       // 縦スクロールの位置が一番上のときかつ、横スクロールされている時
       var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
       var leftTopHeaderVisible = $('.scroll_div').eq(3).hasClass("copyheader_visible");
       if (!topHeaderVisible) {
          // 行固定見出しをvisibleとする
          $('.scroll_div').eq(2).addClass('copyheader_visible');
       }
       if (!leftTopHeaderVisible) {
          // 行列固定見出しをvisibleとする
          $('.scroll_div').eq(3).addClass('copyheader_visible');
       }
 } else {
        var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
        var leftTopHeaderVisible = $('.scroll_div').eq(3).hasClass("copyheader_visible");
          // 初期状態に戻す
          if (topHeaderVisible) {
               $('.scroll_div').eq(2).removeClass('copyheader_visible');
          }
          if(leftTopHeaderVisible){
               $('.scroll_div').eq(3).removeClass('copyheader_visible');
          }

}
```
### まとめると
以上をまとめると以下のようなコードになります。
※一枚のhtmlにまとめました。

``` table.html
<!DOCTYPE html>
<html>
<head>
    <title>FixedMidashi</title>
    <meta charset="utf-8" />
    <style type="text/css">
        .scroll_div {
            overflow: auto;
            width: 312px;
            height: 159px;
        }
        table tr,
        table th,
        table td {
            border: 1px solid black;
        }
        table {
            border-collapse: collapse;
            white-space: nowrap;
            box-sizing: content-box;
        }
        /* がたつき対応 */
        .copyheader_visible {
            visibility: visible !important;
        }
    </style>
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="./fixed_midashi_1.11/fixed_midashi.js"></script>
    <script>
        window.onload = function () {
            FixedMidashi.create();
            // IEの時のみ対応
            if (navigator.userAgent.match(/MSIE 10/i) || navigator.userAgent.match(/Trident\/7\./)) {
                // 行固定見出しに、スクロールがたつき対応クラスを追加
                $(".scroll_div").eq(2).addClass("copyheader_visible");

                $(".scroll_div").scroll(function () {
                    // 縦スクロール量を取得
                    var scrollTop = $('.scroll_div').scrollTop();
                    // 横スクロール量を取得
                    var scrollLeft = $('.scroll_div').scrollLeft();

                    if (scrollTop == 0 && scrollLeft == 0) {
                        // 縦スクロールの位置が一番上かつ、横スクロールの位置が一番左の時
                        var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
                        if (!topHeaderVisible) {
                            // 行固定見出しをvisibleとする
                            $('.scroll_div').eq(2).addClass('copyheader_visible');
                        }
                    }else if(scrollTop == 0 && scrollLeft != 0){
                        // 縦スクロールの位置が一番上のときかつ、横スクロールされている時
                        var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
                        var leftTopHeaderVisible = $('.scroll_div').eq(3).hasClass("copyheader_visible");
                        if (!topHeaderVisible) {
                            // 行固定見出しをvisibleとする
                            $('.scroll_div').eq(2).addClass('copyheader_visible');
                        }
                        if (!leftTopHeaderVisible) {
                            // 行列固定見出しをvisibleとする
                            $('.scroll_div').eq(3).addClass('copyheader_visible');
                        }
                    } else {
                        var topHeaderVisible = $('.scroll_div').eq(2).hasClass("copyheader_visible");
                        var leftTopHeaderVisible = $('.scroll_div').eq(3).hasClass("copyheader_visible");
                        // 初期状態に戻す
                        if (topHeaderVisible) {
                            $('.scroll_div').eq(2).removeClass('copyheader_visible');
                        }
                        if(leftTopHeaderVisible){
                            $('.scroll_div').eq(3).removeClass('copyheader_visible');
                        }

                    }
                })
            }
        };

    </script>
</head>
<body>
    <div class="scroll_div">
        <table _fixedhead="rows:2; cols:2">
            ～省略～
        </table>
    </div>
</body>
</html>
```

これでIEで縦スクロールした際にヘッダのがたつきが無くなります。