ポジローぽけっと

昨日より今日、今日より明日を信じて、トライトライ

HTMLのtableでexcelのウィンドウ枠固定のようにスクロールさせたくなったら

HTMLのtableでexcelのウィンドウ枠固定のようにスクロールさせたくなったら

実装

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <script src="js/vendor/jquery-1.12.0.min.js"></script>
    <title>Title</title>
    <script>
        function initializeTable () {
            $("table th").css("background-color", "aqua");
            $("table td").css("background-color", "aquamarine");

            var thl = $(".table_head_left");
            var thr = $(".table_head_right");
            var tbl = $(".table_body_left");
            var tbr = $(".table_body_right");
            var dhr = $(".div_head_right");
            var dbl = $(".div_body_left");
            var dbr = $(".div_body_right");

            //左上
            thl.css("height", thr.outerHeight());
            thl.css("width", tbl.outerWidth());

            //右上
            dhr.css("position", "absolute");
            dhr.css("top", thl.offset().top);
            dhr.css("left", thl.offset().left + thl.outerWidth());
            dhr.css("overflow-x", "hidden");

            //左下
            dbl.css("position", "absolute");
            dbl.css("top", thl.offset().top + thl.outerHeight());
            dbl.css("overflow-y", "hidden");

            //右下
            dbr.css("position", "absolute");
            dbr.css("top", thl.offset().top + thr.outerHeight());
            dbr.css("left", thl.offset().left + tbl.outerWidth());
            dbr.css("overflow-x", "scroll");
            dbr.css("overflow-y", "scroll");

            if (thr.width() > tbr.width()) {
                //ボディ幅をヘッダ幅に合わせる
                tbr.width(thr.width());
            } else {
                thr.width(tbr.width());
            }

            //scroll連動
            dbr.scroll(function(){
                dhr.scrollLeft($(this).scrollLeft());
                dbl.scrollTop($(this).scrollTop());
            });

            //画面広さ制限模
            var scrollbarwidth = window.innerWidth - document.body.clientWidth;
            dhr.width(tbr.width()/2);
            dbr.width(tbr.width()/2+scrollbarwidth);
            dbl.height(tbr.height()/2);
            dbr.height(tbr.height()/2+scrollbarwidth);
        }
        $(initializeTable);
    </script>
</head>
<body>
<div class="div_head_left">
    <table class="table_head_left">
        <tr>
            <th></th>
        </tr>
    </table>
</div>
<div class="div_head_right">
    <table class="table_head_right">
        <tr>
            <th>hogehoge</th>
        </tr>
    </table>
</div>
<div class="div_body_left">
    <table class="table_body_left">
        <tr>
            <th>1</td>
        </tr>
        <tr>
            <th>2</th>
        </tr>
        <tr>
            <th>3</td>
        </tr>
        <tr>
            <th>4</th>
        </tr>
    </table>
</div>
<div class="div_body_right">
    <table class="table_body_right">
        <tr>
            <td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</td>
        </tr>
        <tr>
            <td>b</td>
        </tr>
        <tr>
            <td>c</td>
        </tr>
        <tr>
            <td>d</td>
        </tr>
    </table>
</div>
</body>
</html>

POINT

PhpStormで、ajaxのdone, fail, alwaysの実行順序を確認した

PhpStorm設定

JavaScript Debug

URL:http://localhost:63342/test/test.html

PHP Built-in Web Server

HOST: localhost
Port: 63342
Document root:hogehoge/test

jQuery入門道場から引用

AJAXでは、 見ているページと同じドメイン(同じプロトコル、ポート、ホスト)の サーバと通信しなければならないという決まりがあります。

test.js

function sleepDeferred(ms) {
    "use strict";
    var kind = "Deferred";
    var d = new $.Deferred();
    //if (ms > 2000) {
    setTimeout(function () {
        // statements
        console.log("test.js:%s:resolve", kind);
        d.resolve(kind);
    }, ms);
    return d.promise();
}
function init() {
    "use strict";
    sleepDeferred(3000);
}
init();

testajax.php

  <?php
  session_start();
  sleep(5);
  header("content-type: text/html; charset=utf-8");
  echo "hoge";

test4.html

<script type="text/javascript" >
   function init() {
       //$("#table_area").css("width", $("#table_head").width());
       // scroll連動
       $("#table_area").scroll(function(){
           var off = $(this).scrollLeft();
           $("#head_area").scrollLeft(off);
       });
       $.ajax({
           type: "GET",
           url: "test.js",
           dataType: "script",
           timeout: 10000
       }).done(function () {
           "use strict";
           setTimeout(function () {
               console.log("setTimeout");
           }, 5000);
           console.log("done");
       }).fail(function () {
           "use strict";
           console.log("fail");
       }).always(function () {
           "use strict";
           console.log("always");
       });
       $.ajax({
           type: "GET",
           url: "http://localhost:63342/test/testajax.php",
           dataType: "text",
           timeout: 10000
       }).done(function () {
           "use strict";
           sleepDeferred(0).then(function() { console.log("done"); });
           setTimeout(function () {
               console.log("setTimeout");
           }, 5000);
       }).fail(function () {
           "use strict";
           console.log("fail");
       }).always(function () {
           "use strict";
           console.log("always");
       });
   }
   function sleepDeferred(ms) {
       "use strict";
       var kind = "Deferred";
       var d = new $.Deferred();
       //if (ms > 2000) {
           setTimeout(function () {
               // statements
               console.log("%s:resolve", kind);
               d.resolve(kind);
           }, ms);
       return d.promise();
   }
   $(init);
</script>

テストまとめ

  • done, fail, alwaysは$.ajax({})の実行完了を待って実行される PHP内でのsleepはしっかり待つ、つまり、GETの応答を待つ GETしたjsの実行はまたない、つまり応答を検知したら、done(fail), alwaysを実行する
  • done(fail)とalwaysは並列実行される