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

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

ただいまの
回答率

87.50%

チャットアプリで、最新のメッセージを常に表示させたい

解決済

回答 1

投稿 編集

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

score 21

先日、mBaaSとPusherを使ったチャットアプリで、チャットの内容がすぐに反映されないと言うタイトルで下記質問をさせていただいた者です。
その後、開発を進めていったのですが、最新のメッセージを常に表示するように機能を追加したのですが、上手く動作しませんでした。

ソースコードとしては、下記となります。
chat.html

<ons-page id="chat">
    <ons-toolbar>
      <div class="left"><ons-back-button>Back</ons-back-button></div>
      <div class="center"></div>
    </ons-toolbar>
    <input type="hidden" id="channelId" />
    <div id="your_container">
      <!-- チャットの外側部分① -->
      <div id="bms_messages_container">

          <!-- タイムライン部分② -->
          <div id="bms_messages">
            <div id="chats"></div>
          </div>

          <!-- テキストボックス、送信ボタン④ -->
          <div class="send-area">
            <ons-input id="message" placeholder="メッセージ"></ons-input>
            <ons-button onclick="send()" modifier="quiet">送信</ons-button>
            <ons-button onclick="positiondata()" modifier="quiet">位置確認</ons-button>
          </div>
      </div>
    </div>
</ons-page>


style.css

/**/

.send-area {
    padding: 0 5px;
    box-sizing: border-box;
    line-height: 49px;
    position: fixed;
    bottom: 0px;
    width: 100%;
    border-top: solid 1px #ccc;
  }

  .send-area ons-input {
      display: inline-block;
      position: relative;
      width: calc(100% - 60px);
  }

  .send-area input {
      vertical-align: middle;
    position: relative;
    width: 98%;
  }

  #your_container{
    /* 高さや幅など、好きな様に設定
    bms_messages_containerの方で、縦横いっぱいに広がってくれるので、
    ここで充てた高さと横幅がそのままスタイルになる仕組み */

    height:80%;/*ここはご自由に*/
    width: 100%;/*ここはご自由に*/
}
/* チャットの外側部分① */
#bms_messages_container{
    height: 100%;/*your_containerに対して100%になる */
    width: 100%;/*your_containerに対して100%になる */
    background-color: #eee;
}

/* タイムライン部分② */
#bms_messages {
    overflow: auto;/* スクロールを効かせつつ、メッセージがタイムラインの外に出ないようにする */
    height:100%;/*テキストエリアが下に張り付く様にする*/
    border-right: 1px solid #ddd;
    border-left: 1px solid #ddd;
    background-color: #eee;
}
    /* メッセージ全般のスタイル */
    .bms_message {
        margin: 0px;
        padding: 0 14px;/*吹き出しがタイムラインの側面にひっつかない様に隙間を開ける*/
        font-size: 16px;
        word-wrap: break-word;/* 吹き出し内で自動で改行 */
        white-space: normal;/*指定widthに合わせて、文字を自動的に改行*/
    }
        .bms_message_box{
            margin-top: 20px;/*上下の吹き出しがひっつかない様に隙間を入れる*/
            max-width: 100%;/*文字が長くなった時に吹き出しがタイムラインからはみ出さない様にする*/
            font-size: 16px;
        }
            .bms_message_content{
                padding: 10px;/*文字や画像(コンテンツ)の外側に隙間を入れる*/
            }
        /* メッセージ1(左側) */
        .bms_left {
            float: left;/*吹き出しをbms_messagesに対して左寄せ*/
            line-height: 1.3em;
        }
            .bms_left .bms_message_box {
                color: #fff;/*テキストを白にする*/
                background: rgb(0, 145, 197);
                border: 2px solid rgb(0, 145, 197);
                /* border-radius: 30px 30px 30px 0px; 左下だけ尖らせて吹き出し感を出す*/
                margin-right: 50px;/*左側の発言だとわかる様に、吹き出し右側に隙間を入れる*/
            }
        /* メッセージ2(右側) */
        .bms_right {
            float: right;/*吹き出しをbms_messagesに対して右寄せ*/
            line-height: 1.3em;
        }
            .bms_right .bms_message_box {
                color: #fff;/*テキストを白にする*/
                background: rgb(0, 154, 87);
                border: 2px solid rgb(0, 154, 87);
                /*border-radius: 30px 30px 0px 30px;右下だけ尖らせて吹き出し感を出す*/
                margin-left: 50px;/*右側の発言だとわかる様に、吹き出し左側に隙間を入れる*/
            }
            .bms_right .bms_message_time {
                margin-left: 50px;/*右側の発言だとわかる様に、吹き出し左側に隙間を入れる*/
            }
        /* 回り込みを解除 */
        .bms_clear {
            clear: both; /* 左メッセージと右メッセージの回り込み(float)の効果の干渉を防ぐために必要(これが無いと、自分より下のメッセージにfloatが影響する) */
        }

/* テキストエリア、送信ボタン④ */
#bms_send {
    background-color:#eee;/*タイムラインの色と同じにする*/
    border-right: 1px solid #ddd;
    border-left: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    height: 48px;
    padding: 4px;
}
    #bms_send_message{
        width: calc(100% - 75px);/*常に送信ボタンの横幅を引いたサイズに動的に計算*/
        line-height: 16px;
        height: 48px;
        padding: 14px 6px 0px 6px;/*文字がテキストエリアの中心になる様に隙間調整*/
        border: 1px solid #ccc;
        border-radius: 4px;/*角丸*/
        text-align: left;/*文字を左寄せ*/
        box-shadow: 2px 2px 4px 0px rgba(0,0,0,0.2) inset;/*内側に影を入れてテキストエリアらしくした*/
        box-sizing: border-box;/*paddingとborderの要素の高さと幅の影響をなくす(要素に高さと幅を含める)*/

    }
    #bms_send_btn {
        width: 72px;
        height: 48px;
        font-size: 16px;
        line-height: 3em;
        float: right;/*bms_sendに対して右寄せ*/
        color: #fff;
        font-weight: bold;
        background: #bcbcbc;
        text-align: center;/*文字をボタン中央に表示*/
        border: 1px solid #bbb;
        border-radius: 4px;/*角丸*/
        box-sizing: border-box;/*paddingとborderの要素の高さと幅の影響をなくす(要素に高さと幅を含める)*/
    }
    #bms_send_btn:hover {
        background: #13178E; /*マウスポインタを当てた時にアクティブな色になる*/
        cursor: pointer;/*マウスポインタを当てた時に、カーソルが指の形になる*/
    }

app.js

function task1(data) {
  return new Promise(function (resolve, reject) {
    connectPusher(data.userName, data.chatId);
    loadChat(data.userName, data.chatId);
    console.log('task1 完了');
    resolve('task完了');
  });

};

// チャット画面を表示したときの処理
$(document).on('show', (event) => {
  if (event.target.id === 'chat') {
    const data = event.target.data;
    $('#channelId').val(data.chatId);

    Promise.resolve()
      .then(task1.bind(this, data))
      .then(function() {
        return new Promise(function (resolve, reject) {
          // スクロール位置の取得
          var scrollPos = $('#bms_messages').offset().top;
          console.log(scrollPos);
          $('#bms_messages').animate({scrollTop: scrollPos});
          resolve('成功');
        });
      });
  }
});


const positiondata = () => {
  // スクロール位置の取得
  var scrollPos = $('#bms_messages').scrollTop();
  console.log(scrollPos);
};

現在のつまずいている場所としては、app.jsの中の49行目
var scrollPos = $('#bms_messages').offset().top;
で、最新のメッセージがある位置(最下部)の値を取りたいのですが、ネットで調べてもよくわかりませんでした。
ちなみに、このscrollPosに、100と言ったリテラル値を入れると正常に動作します。
試しに、
var scrollPos = $('#bms_messages').offset().bottom;
var scrollPos = $('#bms_messages').weight();
と試して見たのですが、値がundefinedになってしまい、ほしい値が入ってきません。

もう一点確認したい点としては、同じくapp.jsの中の51行目
$('#bms_messages').animate({scrollTop: scrollPos});
で今は、animateを使用しているのですが、本当はスクロールする画面を見せず、始めから一番最新のメッセージ
が見れるようにしたいのですが、その方法が分かりませんでした。
こちらに関しては、ネットを検索してみても、解決方法が見つかりませんでした。

ご教授いただけると助かります。よろしくお願いします。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

check解決した方法

0

自己解決しました。

var scrollPos = $('#bms_messages').offset().top;
の部分に関してですが、メッセージを取得する時、メッセージ数×リテラル値(今回の場合は100としました)を予め保持しておき、その値をscrollPosに当てはめる事で最終の位置を取得するようにしました。

var scrollPos = msgcnt * 100;

また、
$('#bms_messages').animate({scrollTop: scrollPos});

に関しては、
$('#bms_messages').scrollTop(scrollPos );
と言う事が出来る事が分かったため、上記のように変更いたしました。
以上です。
ご助力ありがとうございました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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