スポンサー
Support Framework7

メッセージ

    メッセージコンポーネントは、アプリ内のコメントやメッセージングシステムの視覚化に役立ちます。

    メッセージのレイアウト

    <div class="page">
      <div class="page-content messages-content">
        <div class="messages">
          <!-- 日付スタンプ -->
          <div class="messages-title"><b>Sunday, Feb 9</b> 12:58</div>
    
          <!-- 送信済みメッセージ(デフォルトでは緑色で右側に表示されています -->
          <div class="message message-sent">
            <div class="message-content">
              <!-- テキストの入った泡 -->
              <div class="message-bubble">
                <div class="message-text">Hi, Kate</div>
              </div>
            </div>
          </div>
    
          <!-- 別の送信済みメッセージ -->
          <div class="message message-sent">
            <div class="message-content">
              <div class="message-bubble">
                <div class="message-text">How are you?</div>
              </div>
            </div>
          </div>
    
          <!-- 受信したメッセージ(デフォルトでは、左側にグレーで表示されます -->
          <div class="message message-received">
            <!-- 送信者のアバター -->
            <div class="message-avatar" style="background-image:url(path/to/avatar.jpg)"></div>
            <div class="message-content">
              <!-- 送信者の名前 -->
              <div class="message-name">Blue Ninja</div>
              <!-- テキスト付きバブル -->
              <div class="message-bubble">
                <div class="message-text">Hi there, I am also fine, thanks! And how are you?</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    メッセージページのレイアウト。

    • messages-content - メッセージラッパーの必須追加クラスです。page-content` に追加する必要があります。

    • messages - メッセージバブルのための必須の追加ラッパーです。必須の要素です。

    • messages-title - メッセージのタイトルです。

    • message - シングルメッセージ

    シングルメッセージのレイアウト

    以下はシングルメッセージの完全なレイアウトです。

    <div class="message">
      <div class="message-avatar" style="background-image:url(path/to/avatar)"></div>
      <div class="message-content">
        <div class="message-name">John Doe</div>
        <div class="message-header">Message header</div>
        <div class="message-bubble">
          <div class="message-text-header">Text header</div>
          <div class="message-image">
            <img src="path/to/image" />
          </div>
          <div class="message-text">Hello world!</div>
          <div class="message-text-footer">Text footer</div>
        </div>
        <div class="message-footer">Message footer</div>
      </div>
    </div>
    • message-avatar - 送信者のアバター、オプションで指定します。

    • message-name - 送信者の名前、オプションです。

    • message-header - 単一のメッセージヘッダ、オプションです。

    • message-text-header - バブルの中のテキストヘッダー、オプションです。

    • message-image - メッセージのイメージ、オプションです。

    • message-text - メッセージのテキスト、オプションです。

    • message-text-footer - バブルの中のテキストフッター、オプションです。

    • message-footer - バブルの後に表示されるフッターテキスト、オプション

    シングルメッセージコンテナの追加クラス

    • message-sent - シングルメッセージ用の追加クラスで、このメッセージがユーザーによって送信されたことを示します。右側に緑の背景色で表示されます。

    • message-received - 単一のメッセージのための追加クラスで、このメッセージがユーザーによって受信されたことを示します。左側にグレーの背景色で表示されます。

    • message-tail - 単一のメッセージ (受信または送信) に対して、バブルの "tail" を追加するクラスです。

    • message-same-name - メッセージの送信者が、前のメッセージと同じ名前であることを示す追加クラスです。

    • message-same-avatar - メッセージが前のメッセージと同じアバターを持っていることを示すための追加クラスです。

    • message-same-header - メッセージが以前のメッセージと同じメッセージヘッダーを持つことを示すための追加クラスです。

    • message-same-footer - メッセージが前のメッセージと同じメッセージフッターを持つことを示すための追加クラスです。

    • message-last - 単一のメッセージ (受信または送信) に対する追加クラスで、現在の会話において一人の送信者が最後に受信した、または最後に送信したメッセージを示します。

    • message-first - 現在の会話において、ある送信者が最初に受信した、または最初に送信したメッセージを示す、単一のメッセージ(受信または送信)用の追加クラス。

    メッセージアプリのメソッド

    さて、メッセージのHTMLができたら、それを初期化する必要があります。関連するAppのメソッドを使用します。

    app.messages.create(parameters)パラメータ付きメッセージの初期化
    • parameters - object - メッセージのパラメータを持つオブジェクト。
    • 初期化されたメッセージのインスタンスを返す
    app.messages.destroy(el)メッセージインスタンスの破棄
    • el - HTMLElementまたはstring(CSSセレクタ付き)またはobject。破壊するメッセージ要素またはメッセージインスタンス。
    app.messages.get(el)HTML要素でメッセージのインスタンスを取得
    • el - HTMLElement または string (CSSセレクタ使用時). メッセージの要素です。
    • メソッドはメッセージのインスタンスを返します

    メッセージのパラメータ

    利用可能なパラメータの一覧を見てみましょう。

    ParameterTypeDefaultDescription
    autoLayoutbooleantrue自動レイアウトを有効にすると、渡された条件に基づいて必要なすべての追加クラスが自動的に追加されます。
    newMessagesFirstbooleanfalse新しいメッセージを下に表示するのではなく、上に表示したい場合に有効にします。
    scrollMessagesbooleantrue新しいメッセージを追加する際のメッセージの自動スクロールを有効/無効にする。
    scrollMessagesOnEdgebooleantrue有効にした場合、メッセージの自動スクロールは、ユーザーがメッセージビューの上部または下部にいるときにのみ行われます。
    messagesarray初期メッセージの配列。配列内の各メッセージは、単一のメッセージパラメータを持つオブジェクトとして表示されます。
    onobject

    イベントハンドラーを持つオブジェクト。例えば

    var messages = app.messages.create({
      el: '.messages',
      on: {
        change: function () {
          console.log('Textarea value changed')
        }
      }
    })
    renderMessagefunction(message)単一のメッセージをレンダリングする関数。完全なメッセージの HTML 文字列を返さなければならない
    Autolayout Conditions
    firstMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて true または false のブール値を返さなければならない関数です。一致した場合には、メッセージに message-first クラスが追加されます。
    lastMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、trueまたはfalseのブール値を返さなければならない関数です。一致した場合には、メッセージに message-last クラスが追加されます。
    tailMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、trueまたはfalseのブール値を返さなければならない関数です。一致した場合には、メッセージに message-tail クラスが追加されます。
    sameNameMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、trueまたはfalseのブール値を返さなければならない関数です。一致した場合には、メッセージに message-same-name クラスが追加されます。
    sameHeaderMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、真偽値 true または false を返さなければならない関数です。一致した場合には、メッセージに message-same-header クラスが追加されます。
    sameFooterMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて真偽値を返さなければならない関数です。一致した場合には、メッセージに message-same-footer クラスが追加されます。
    sameAvatarMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、真偽値 true または false を返さなければならない関数です。一致した場合には、メッセージに message-same-avatar クラスが追加されます。
    customClassMessageRulefunction(message, previousMessage, nextMessage)前後のメッセージに応じて、要求された条件に基づいて、追加のメッセージクラスを文字列として返す関数です。

    シングルメッセージのパラメータ

    ここでは、messages 配列を渡す際に使用する、単一のメッセージパラメータオブジェクトについて説明します。

    ParameterTypeDefaultDescription
    textstringメッセージのテキスト
    headerstring単一メッセージのヘッダ
    footerstringシングルメッセージのフッター
    namestring送信者名
    avatarstring送信者アバターの URL 文字列
    typestringsentメッセージの種類 - sent または `received'
    textHeaderstringメッセージのテキストヘッダ
    textFooterstringメッセージテキストフッター
    imagestringメッセージ画像のHTML文字列(例:<img src="path/to/image" />)。imageSrc`パラメータの代わりに使うことができます。
    imageSrcstringメッセージ画像のURL文字列。image`パラメータの代わりに使うことができます。
    isTitlebooleanメッセージとして表示されるか、メッセージのタイトルとして表示されるかを定義します。
    cssClassstringメッセージのHTML要素に設定する追加のCSSクラス
    attrsobjectメッセージのHTML要素に設定される追加のHTML属性を持つオブジェクトです。例えば、追加の data 属性を設定する場合は、以下のようになります。
    var message = {
      text: 'Hello!',
      attrs: {
        'data-id': 1,
        'data-author-id': 150
      }
    }

    メッセージのメソッドとプロパティ

    メッセージを作成するためには、メッセージを呼び出す必要があります。

    var messages = app.messages.create({ /* parameters */ })

    メッセージを初期化すると、その初期化されたインスタンスが変数(上記の例では messages 変数)に格納され、便利なメソッドやプロパティが用意されます。

    Properties
    messages.params初期化パラメータが渡されたオブジェクト
    messages.elメッセージコンテナ HTML 要素 (<div class="messages">)
    messages.$elメッセージを持つHTML要素を持つDom7要素
    messages.messagesメッセージを含む配列
    Methods
    messages.showTyping(message)入力中のメッセージを表示する
    messages.hideTyping()入力中のメッセージ表示を隠す
    messages.addMessage(message, method, animate);

    methodパラメータに応じて、新しいメッセージを最後または最初に追加する

    • message - object - 追加するメッセージのパラメータ。必須です。
    • method - string - (append または prepend) メッセージコンテナの最後または最初に新しいメッセージを追加するかどうかを指定します。オプションで、指定されていない場合は、newMessagesFirstパラメータに応じてメッセージが追加されます。
    • animate - boolean - (デフォルトでは true) ここに false を渡すと、メッセージは遷移やスクロールのアニメーションをせずに、すぐに追加されます。オプションです。
    • メソッドはメッセージ・インスタンスを返します。
    messages.addMessages(messages, method, animate);一度に複数のメッセージを追加することができます。
    • messages - arrayに追加するメッセージを指定します。配列の各メッセージは、メッセージのパラメータを持つオブジェクトとして表示されます。
    • メソッドはメッセージのインスタンスを返します。
    messages.removeMessage(message);メッセージの削除
    • message - 削除するメッセージの HTMLElement または string (CSSセレクタ付き) または number (配列 messages からメッセージのインデックス番号を指定したもの)。
    • メソッドはメッセージのインスタンスを返します。
    messages.removeMessages(messages);複数のメッセージの削除
    • messages - array 削除するメッセージを指定します。
    • メソッドはメッセージのインスタンスを返します
    messages.scroll(duration, position);newMessagesFirst`パラメータに応じてメッセージを上下にスクロールする
    • duration - number スクロール時間(単位:ミリ秒
    • position - number スクロール位置 (px)
    messages.renderMessages()メッセージをHTMLで表示する
    messages.layout();メッセージの自動レイアウトを強制する
    messages.clear();すべてのメッセージを消去/削除する
    messages.destroy();メッセージインスタンスの破棄

    メッセージのイベント

    メッセージは以下のDOMイベントをmessages要素に、イベントをappとmessagesインスタンスに発行します。

    DOMイベント

    EventTargetDescription
    messages:beforedestroyMessages Element<div class="messages">Event will be triggered right before Messages instance will be destroyed

    アプリとメッセージ・インスタンスのイベント

    Messages インスタンスは、self インスタンスと app インスタンスの両方に対してイベントを発行します。App インスタンスのイベントは、同じ名前でプレフィックスとして messages が付きます。

    EventTargetArgumentsDescription
    beforeDestroymessages(messages)イベントは、メッセージのインスタンスが破棄される直前に発生します。
    messagesBeforeDestroyapp

    メッセージの自動初期化

    メッセージ API を使用する必要がなく、メッセージがページ内にあり、ページの初期化時に DOM に表示される場合は、messages 要素に messages-init クラスを追加するだけで、自動初期化が可能です。

    <div class="messages messages-init" data-new-messages-first="true">
      ...
    </div>

    キャメルケースで使われているパラメータ、例えばnewMessagesFirstは、data-属性ではdata-new-messages-firstとしてケバブケースで使われます。

    CSS Variables

    Below is the list of related CSS variables (CSS custom properties).

    Note that commented variables are not specified by default and their values is what they fallback to in this case.

    :root {
      --f7-message-text-header-text-color: inherit;
      --f7-message-text-header-opacity: 0.65;
      --f7-message-text-header-font-size: 12px;
      --f7-message-text-footer-text-color: inherit;
      --f7-message-text-footer-opacity: 0.65;
      --f7-message-text-footer-font-size: 12px;
      --f7-message-bubble-line-height: 1.2;
      --f7-message-header-font-size: 12px;
      --f7-message-footer-font-size: 11px;
      --f7-message-name-font-size: 12px;
      --f7-message-name-font-weight: inherit;
      --f7-message-avatar-border-radius: 50%;
      --f7-messages-title-font-weight: inherit;
      /*
      --f7-message-sent-bg-color: var(--f7-theme-color);
      */
      --f7-message-sent-text-color: #fff;
      --f7-messages-content-bg-color: #fff;
      --f7-message-typing-indicator-bg-color: #000;
      --f7-message-received-bg-color: #e5e5ea;
      --f7-message-received-text-color: #000;
    }
    :root .theme-dark,
    :root.theme-dark {
      --f7-messages-title-text-color: rgba(255, 255, 255, 0.54);
      --f7-message-header-text-color: rgba(255, 255, 255, 0.54);
      --f7-message-name-text-color: rgba(255, 255, 255, 0.54);
      --f7-message-footer-text-color: rgba(255, 255, 255, 0.54);
      --f7-messages-content-bg-color: transparent;
      --f7-message-received-bg-color: #252525;
      --f7-message-received-text-color: #fff;
      --f7-message-typing-indicator-bg-color: #fff;
    }
    .ios {
      --f7-messages-title-text-color: rgba(0, 0, 0, 0.45);
      --f7-messages-title-font-size: 11px;
      --f7-message-header-text-color: rgba(0, 0, 0, 0.45);
      --f7-message-footer-text-color: rgba(0, 0, 0, 0.45);
      --f7-message-name-text-color: rgba(0, 0, 0, 0.45);
      --f7-message-avatar-size: 29px;
      --f7-message-margin: 10px;
      --f7-message-bubble-min-height: 32px;
      --f7-message-bubble-font-size: 17px;
      --f7-message-bubble-border-radius: 16px;
      --f7-message-bubble-padding-vertical: 6px;
      --f7-message-bubble-padding-horizontal: 16px;
      --f7-message-typing-indicator-opacity: 0.35;
    }
    .md {
      --f7-messages-title-font-size: 12px;
      --f7-message-avatar-size: 32px;
      --f7-message-margin: 16px;
      --f7-message-bubble-min-height: 32px;
      --f7-message-bubble-font-size: 16px;
      --f7-message-bubble-border-radius: 4px;
      --f7-message-bubble-padding-vertical: 6px;
      --f7-message-bubble-padding-horizontal: 8px;
      --f7-message-typing-indicator-opacity: 0.6;
      --f7-messages-title-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-header-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-footer-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-name-text-color: rgba(0, 0, 0, 0.51);
    }
    .aurora {
      --f7-messages-title-font-size: 14px;
      --f7-message-avatar-size: 32px;
      --f7-message-margin: 16px;
      --f7-message-bubble-min-height: 34px;
      --f7-message-bubble-font-size: 16px;
      --f7-message-bubble-line-height: 1.4;
      --f7-message-bubble-border-radius: 16px;
      --f7-message-bubble-padding-vertical: 6px;
      --f7-message-bubble-padding-horizontal: 10px;
      --f7-message-typing-indicator-opacity: 0.5;
      --f7-message-header-font-size: 14px;
      --f7-message-footer-font-size: 12px;
      --f7-message-name-font-size: 14px;
      --f7-messages-title-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-header-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-footer-text-color: rgba(0, 0, 0, 0.51);
      --f7-message-name-text-color: rgba(0, 0, 0, 0.51);
    }
    

    Examples

    <template>
      <div class="page">
        <div class="navbar">
          <div class="navbar-bg"></div>
          <div class="navbar-inner">
            <div class="title">Messages</div>
          </div>
        </div>
        <div class="toolbar messagebar">
          <div class="toolbar-inner">
            <div class="messagebar-area">
              <textarea class="resizable" placeholder="Message"></textarea>
            </div>
            <a class="link send-link" href="#" @click=${sendMessage}>Send</a>
          </div>
        </div>
        <div class="page-content messages-content">
          <div class="messages">
            <div class="messages-title"><b>Sunday, Feb 9,</b> 12:58</div>
            <div class="message message-sent">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
              <div class="message-content">
                <div class="message-name">John Doe</div>
                <div class="message-header">Message header</div>
                <div class="message-bubble">
                  <div class="message-text-header">Text header</div>
                  <div class="message-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
                  <div class="message-text-footer">Text footer</div>
                </div>
                <div class="message-footer">Message footer</div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
              <div class="message-content">
                <div class="message-name">John Doe</div>
                <div class="message-header">Message header</div>
                <div class="message-bubble">
                  <div class="message-text-header">Text header</div>
                  <div class="message-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
                  <div class="message-text-footer">Text footer</div>
                </div>
                <div class="message-footer">Message footer</div>
              </div>
            </div>
            <div class="message message-sent">
              <div class="message-content">
                <div class="message-bubble">
                  <div class="message-text">Hi, Kate</div>
                </div>
              </div>
            </div>
            <div class="message message-sent">
              <div class="message-content">
                <div class="message-bubble">
                  <div class="message-text">How are you?</div>
                </div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
              <div class="message-content">
                <div class="message-name">Kate</div>
                <div class="message-bubble">
                  <div class="message-text">Hi, I am good!</div>
                </div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
              <div class="message-content">
                <div class="message-name">Blue Ninja</div>
                <div class="message-bubble">
                  <div class="message-text">Hi there, I am also fine, thanks! And how are you?</div>
                </div>
              </div>
            </div>
            <div class="message message-sent">
              <div class="message-content">
                <div class="message-bubble">
                  <div class="message-text">Hey, Blue Ninja! Glad to see you ;)</div>
                </div>
              </div>
            </div>
            <div class="message message-sent">
              <div class="message-content">
                <div class="message-bubble">
                  <div class="message-text">Hey, look, cutest kitten ever!</div>
                </div>
              </div>
            </div>
            <div class="message message-sent">
              <div class="message-content">
                <div class="message-bubble">
                  <div class="message-image">
                    <img src="https://cdn.framework7.io/placeholder/cats-200x260-4.jpg"
                      style="width:200px; height: 260px" />
                  </div>
                </div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
              <div class="message-content">
                <div class="message-name">Kate</div>
                <div class="message-bubble">
                  <div class="message-text">Nice!</div>
                </div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
              <div class="message-content">
                <div class="message-name">Kate</div>
                <div class="message-bubble">
                  <div class="message-text">Like it very much!</div>
                </div>
              </div>
            </div>
            <div class="message message-received">
              <div class="message-avatar"
                style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
              <div class="message-content">
                <div class="message-name">Blue Ninja</div>
                <div class="message-bubble">
                  <div class="message-text">Awesome!</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
    <script>
      export default (props, { $f7, $, $on }) => {
        let messages;
        let messagebar;
    
        // Response flag
        var responseInProgress = false;
    
        // Dummy response
        var answers = [
          'Yes!',
          'No',
          'Hm...',
          'I am not sure',
          'And what about you?',
          'May be ;)',
          'Lorem ipsum dolor sit amet, consectetur',
          'What?',
          'Are you sure?',
          'Of course',
          'Need to think about it',
          'Amazing!!!'
        ]
        var people = [
          {
            name: 'Kate Johnson',
            avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg'
          },
          {
            name: 'Blue Ninja',
            avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg'
          }
        ];
    
        // Receive Message
        const receiveMessage = () => {
          responseInProgress = true;
          setTimeout(function () {
            // Get random answer and random person
            var answer = answers[Math.floor(Math.random() * answers.length)];
            var person = people[Math.floor(Math.random() * people.length)];
    
            // Show typing indicator
            messages.showTyping({
              header: person.name + ' is typing',
              avatar: person.avatar
            });
    
            setTimeout(function () {
              // Add received dummy message
              messages.addMessage({
                text: answer,
                type: 'received',
                name: person.name,
                avatar: person.avatar
              });
              // Hide typing indicator
              messages.hideTyping();
              responseInProgress = false;
            }, 4000);
          }, 1000);
        }
    
        // Send Message
        const sendMessage = () => {
          var text = messagebar.getValue().replace(/\n/g, '<br>').trim();
          // return if empty message
          if (!text.length) return;
    
          // Clear area
          messagebar.clear();
    
          // Return focus to area
          messagebar.focus();
    
          // Add message to messages
          messages.addMessage({
            text: text,
          });
    
          if (responseInProgress) return;
          // Receive dummy message
          receiveMessage();
        }
    
        $on('pageInit', () => {
          // Init Messages
          messages = app.messages.create({
            el: '.messages',
    
            // First message rule
            firstMessageRule: function (message, previousMessage, nextMessage) {
              // Skip if title
              if (message.isTitle) return false;
              /* if:
                - there is no previous message
                - or previous message type (send/received) is different
                - or previous message sender name is different
              */
              if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
              return false;
            },
            // Last message rule
            lastMessageRule: function (message, previousMessage, nextMessage) {
              // Skip if title
              if (message.isTitle) return false;
              /* if:
                - there is no next message
                - or next message type (send/received) is different
                - or next message sender name is different
              */
              if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
              return false;
            },
            // Last message rule
            tailMessageRule: function (message, previousMessage, nextMessage) {
              // Skip if title
              if (message.isTitle) return false;
              /* if (basically same as lastMessageRule):
              - there is no next message
              - or next message type (send/received) is different
              - or next message sender name is different
            */
              if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
              return false;
            }
          });
    
          // Init Messagebar
          messagebar = app.messagebar.create({
            el: '.messagebar'
          });
        });
    
        return $render;
      }
    
    
    
    </script>