質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • JavaScript

    14778questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jsで高さを取得する際にタイムラグが出てしまう。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 95

takane

score 22

先ほど質問を出したのですが、記載内容が悪いというご指摘をいただいたので、立て直します。

http://www.noevir.co.jp/figureskate/

こちらのサイトのNEWS部分ですが、jsで、ボタンを押すとぱかぱかと開く仕組みを作っています。

spモードにすると分かるのですが、一番最初に高さを計算する際に少しタイムラグがでてしまい、一旦100%の高さを表示してからリサイズされるという現象が起きています。

外をかこむ枠の高さをtr3つ分にしたいためにこのようになっています。spモードだとテーブルの高さがデバイスごとに変わるので、jsでtrの高さを計算して、枠の高さとして設定しています。

タイムラグをなくし、最初からtr3つ分の高さにすることはできますでしょうか?

window.onloadでは遅いかと思ったのでaddEventListenerのDOMContentLoadedも試したのですがうまくいきませんでした。

<div class="column ac_wrapper"     id="newstop">
    <h2 class="txt-tit">NEWS</h2>
        <div class="col_news ac" id="ac">
            <table class="news-ta ac_table">
        <tbody>
        <tr>
          <th>2018.5.7</th>
            <td style="line-height:1.3"><a href="topics.htm#massage_201805">樋口選手からメッセージが届きました。</a></td>
        </tr>
        <tr>
          <th>2018.4.20</th>
            <td style="line-height:1.3"><a href="topics.htm#baseball">メットライフドームでの始球式を終えられた樋口選手から写真が届きました。</a></td>
        </tr>
         <tr>
          <th>2018.4.17</th>
            <td style="line-height:1.3">4月20日(金)に行われる埼玉西武ライオンズ対千葉ロッテマリーンズ戦(メットライフドーム)の始球式に登場します。</td>
        </tr>
         <tr>
          <th>2018.3.24</th>
            <td style="line-height:1.3">世界フィギュアスケート選手権大会2018で2位となりました。</td>
        </tr>
         <tr>
          <th>2018.2.24</th>
            <td style="line-height:1.3">チャレンジカップ2018で優勝いたしました。</td>
        </tr>
         <tr>
          <th>2017.12.23</th>
            <td style="line-height:1.3">第86回全日本フィギュアスケート選手権大会で4位となりました。</td>
        </tr>
        <tr>
          <th>2017.12.9</th>
            <td style="line-height:1.3">ISUグランプリファイナル 国際フィギュアスケート競技大会 愛知・名古屋2017で6位となりました。</td>
        </tr>
        <tr>
          <th>2017.11.4</th>
            <td style="line-height:1.3">ISUグランプリ アウディカップオブチャイナで2位となりました。</td>
        </tr>
        <tr>
          <th>2017.10.21</th>
            <td style="line-height:1.3">ISUグランプリ ロステレコムカップで3位となりました。</td>
        </tr>
        <tr>
          <th>2017.9.17</th>
            <td style="line-height:1.3">ロンバルディアトロフィーで2位となりました。</td>
        </tr>

      </tbody>
      </table>
          <div class="switch_ac">
              <div class="css_button parent" id="ac_open">
                <p class="open">さらに表示する</p>
                <p class="close">閉じる</p>
            </div>
          </div>

    </div>

</div>
(function () {
    //関数の中身・・・

/*アコーディオンstart*/

    const ac_table = document.getElementsByClassName('ac_table');

    var acparent = document.getElementsByClassName('ac');
    var button = document.getElementsByClassName('css_button');
    var acopen = document.getElementsByClassName('open');
    var acclose = document.getElementsByClassName('close');
    var ac_wrapper = document.getElementsByClassName('ac_wrapper');

    var sw = false;



    for(var i=0;i<acparent.length;i++){    
        var chageClassOpen = acopen[i];
        var chageClassClose = acclose[i];
        var thisAcparent = acparent[i];
        var thisTable = ac_table[i];
        var bar = ac_table[i];
        var thisButton = button[i];
        var newstop = document.getElementById('newstop');
        var thisAcWrapper = ac_wrapper[i];

        //console.log( "テーブルの高さ" + thisTable.offsetHeight);

        thisAcparent.classList.add('smooth');

        thisButton.addEventListener("click", function(){    
            if(sw==true){
                    sw = false;
                    tableSize();
                    chageClassOpen.className = 'on open';
                    chageClassClose.className = 'off close';
                    thisAcparent.classList.remove('ac_opensesame');
                    move201806();
                }else if(sw==false){
                    const contentHeight = bar.getBoundingClientRect().height;
                    thisAcparent.style.height = contentHeight+70+'px';
                    sw = true;
                    chageClassOpen.className = 'off open';
                    chageClassClose.className = 'on close';
                    thisAcparent.classList.add('ac_opensesame');
                    };

        }, false);

        /*スクロールした高さの取得*/
        var windowTop = document.documentElement.scrollTop || document.body.scrollTop;
        window.onload = function () {
                window.onscroll = function(){
                    getTheScrollPosition( this );
                };
                function getTheScrollPosition( $event ) {
                var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                windowTop = scrollTop ;
                //console.log(windowTop);
                }
            }
        /*スクロールした高さの取得*/

        /*ボックスまでのスクロール量*/
        var box = thisAcWrapper.offsetTop;
        //console.log("ボックスのページ上の位置は"+box);
        /*ボックスまでのスクロール量*/


        function move201806(){            

            var i = 10;

             var howMuchScroll = false;
             if(windowTop-box > 0){
                 howMuchScroll = (windowTop-box)/10;
                 howMuchScroll += 0.5;
                 }else if(windowTop-box < 0){
                howMuchScroll = 0;
                }
            //console.log(howMuchScroll);            

            var int = setInterval(function() {
            window.scrollBy(0,-howMuchScroll);
            i += 20;
            if (i >= 200) clearInterval(int);
          }, 20);
        };

        function tableSize(){
            var tableHeight = thisTable.getElementsByTagName('tbody')[0].childNodes[1].clientHeight + thisTable.getElementsByTagName('tbody')[0].childNodes[3].clientHeight + thisTable.getElementsByTagName('tbody')[0].childNodes[5].clientHeight + 71;
            thisAcparent.style.height = tableHeight + 'px';
            };
        function wholeTableSize(){
            var openHeight = thisTable.clientHeight + 71;
            //console.log("テーブルの高さと71を足すと"+openHeight);
            thisAcparent.style.height = openHeight + 'px';
            }

        //window.onload= tableSize();
        window.addEventListener('DOMContentLoaded', function() {
          tableSize();
        });


        //リサイズした時にする動作
        window.onresize = window_load;    
        function window_load() {
            if (sw == false) {
                tableSize(); 
        //console.log(thisAcparent.style.height);
            } else if (sw == true) {
                wholeTableSize();
            }
            //ボックスの位置を取り直す
            box = thisAcWrapper.offsetTop;
            //console.log("ボックスのページ上の位置は"+box);
        }//リサイズした時にする動作





    };/*for end*/


/*アコーディオンend*/





}());
@charset "utf-8";


#ac{
    height:215px;
    overflow:hidden;
    position:relative;
    }
.ac_opensesame{
    height:auto;
    overflow:hidden;
    position:relative;
    transition:3s all ease 0s;
    }
.switch_ac{
        position: absolute;
    width: 100%;
    bottom: 0;
    height: 46px;
    padding: 15px 0 0 0;
    background-color: #FFFFFF;
    }
.css_button:hover{
    cursor:pointer;
    opacity:0.7;
    }
.switch_ac p{
    color:#F44EAC;
    font-size:0.8rem;
    }
.css_button{
    border:#f5509d 1px solid;
    border-radius:30px;
    width:180px;
    margin-left:auto;
    margin-right:auto;
    height:44px;
    }
.open{
    margin-top:10px;
    }

.open:after{
    content: "";
    position: absolute;
    display:block;
    bottom: 6px;
    left:0;
    right:0;
    margin:auto;
    width:0px;
    height:0px;
    border-top: 10px #f5509d solid;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
    }

.close{
    margin-top:10px;
    display:none;
    }        

.close:after{
    content: "";
    position: absolute;
    display:block;
    bottom: 6px;
    left:0;
    right:0;
    margin:auto;
    width:0px;
    height:0px;
    border-bottom: 10px #f5509d solid;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
    }


.close a:link{
    text-decoration: none;
    color: #f5509d;
    }
.close a:visited{
    text-decoration: none;
    color: #f5509d;
    }
.close a::active{
    text-decoration: none;
    color: #f5509d;
    }

.close a{
    display:block;
    width:182px;
    height:46px;
    }

.subtit_01{
    height:50px;
    text-align:center;
    }

.hr_subtit{
     border:0;
    border-bottom:medium double #999;
    display:block;
        }

.pro{
    position:absolute;
    bottom:10px;
    right:7px;
    }


.button_result{
    text-align:right;
    margin-top:0;
    }
.result table.res-ta{
    margin-bottom:15px;
    }
.css_button p{
    line-height:0.8rem;
    font-family:"ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
    font-size:0.8rem;
    margin-left:auto;
    margin-right:auto;
    text-align:center;
    width: 182px;
    height: 46px;
    margin-top: 0;
    padding-top: 0;
    line-height: 30px;
    }

.column .plans{
    margin-top:0px;
    }

.top-cont1 .top-cont-L  h2,.top-cont1 .top-cont-R h2{
    margin-top:0;
    }

.top-cont1 .top-cont-L .btn-05{
    text-align:right;
    }

@media only screen and (max-width: 767px) {
    #ac {
    height: inherit;
    overflow: hidden;
    position: relative;
}
.css_button:hover{
    cursor:pointer;
    opacity:1.0;
    }
.column {
    margin-top: 35px;
}
.pro {
    position:relative;
    padding-top: 0;
    margin-top: 10px;
    margin-right: 10px;
    bottom:inherit;
    right:inherit;
}
.top-cont1 .top-cont-R .pro{
    margin-right:0;
    }
.mg{
    margin-top:20px;
    width:86%;
    margin-left:auto;
    margin-right:auto;
    }
.top-cont-R .p-th-bg{
    padding:7%;
    width:86%
    }

    .top-cont-R .p-th-bg .mt10.parent{
    padding:10px 4% 10px 4%!important;
    box-sizing:border-box;
    }

.button_result a{
    margin-right:5px;
    }

.top-cont2.column{
    padding-bottom:0;
    }

.top-cont-R{
    margin-top:35px;
    }
.top-cont1.column{
    margin-top:30px;
    }
    }
body.post{
    opacity:0;
    }

.parent{
    position:relative;
    }
.news-ta td{
    text-align:left;
    }
.column{
    margin-top:30px;
    }

/*--アコーディオンの開閉start--*/
.on{
    display:block!important;
    }
.off{
    display:none!important;
    }
.smooth{
    transition: 1s all ease 0s!important;
    }
/*--アコーディオンの開閉end--*/
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

ブラウザ上でのロードが終わらなければ、サイズに依存する「実際の高さ」は計れないですし、
今の状態で一瞬表示されるのを、jsだけでどうにかするのは無理かなぁと思いました。

最初に高さが分かる必要があるのは、先頭のから3つ分のtrまでだと思うので、
cssでもちょっと制御しておいたらいいのではないかと。

例えば。

初期でニュースのテーブルに、trの4つ目以降を非表示にするクラスを付けて置く。
↓ クラス名は適当です
table.limit_row3 tr:nth-child(n+4){ display: none; }

で、load直後のdivの高さを3つ分に設定する処理が終わったら、クラス.limit_row3 を外す。

は、どうでしょう。

これでうまくいくならば、
HTMLはクラスを1つ書き足す、cssとjsは1行書き足すくらいで済むので、
修正も楽かなと思います。

実際に高さを設定しているjsの処理は詳しく見ておりません & 上記提案は試していません
ので、うまくいかない場合は、ご容赦ください^^;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/12 12:16 編集

    これ、ベストですね。
    うまくいけば、見えなくても、JS上では全ニュースの高さ先に取得できるかもですし。
    僕自身、参考にさせていただきます。

    キャンセル

  • 2018/06/12 12:50

    そうですね、タイムラグはしかたない現象だったのですね・・・。
    いつも思うのですが、みなさんは柔軟に対応策を考えてらっしゃるなと思います。
    発想力のあるなしがサイトデザインに現れるのですね・・・。
    cssで操作をできれば、一番美しいと思います。更新時に試してみます。
    有り難うございます。

    キャンセル

+2

これは、ロードのタイミングで、一瞬全ニュースが表示は、
いたしかたない気がします・・・・。
ので、発想を変えてみてはいかがでしょう。

上位三つは、一つのブロック
それより下位のニュースは、別ブロックに格納しておき、(display: none;にしたdivとか)
ロード完了次第、下位のニュースを、上位三つの親ブロックにjsで移動、
下位ニュースを格納していた、display: none;要素をJSで削除
そのあと、クリックイベント等を追加。
こうすれば、
HTML表示直後は、三つしか無いので、全部が表示されることは絶対ありません。

サンプルソースコードは、すみません、少々込み入った内容になるかと思いますので、
ご自身で実装してみてください・・・。
(ここまでネイティブで書ける方なら、わりと余裕で実装できるかと思います)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/12 12:49

    そうですね、タイムラグはしかたない現象だったのですね・・・。
    いつも思うのですが、みなさんは柔軟に対応策を考えてらっしゃるなと思います。
    発想力のあるなしがサイトデザインに現れるのですね・・・。
    テーブルを2つに分けるやりかたを次の更新で試みてみます。
    有り難うございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    14778questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。