訊息
訊息元件將協助您在應用程式中視覺化留言和訊息系統。
訊息配置
<div class="page">
<div class="page-content messages-content">
<div class="messages">
<!-- Date stamp -->
<div class="messages-title"><b>Sunday, Feb 9</b> 12:58</div>
<!-- Sent message (by default - green and on right side) -->
<div class="message message-sent">
<div class="message-content">
<!-- Bubble with text -->
<div class="message-bubble">
<div class="message-text">Hi, Kate</div>
</div>
</div>
</div>
<!-- Another sent message -->
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-text">How are you?</div>
</div>
</div>
</div>
<!-- Received message (by default - grey on left side) -->
<div class="message message-received">
<!-- Sender avatar -->
<div class="message-avatar" style="background-image:url(path/to/avatar.jpg)"></div>
<div class="message-content">
<!-- Sender name -->
<div class="message-name">Blue Ninja</div>
<!-- Bubble with text -->
<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
- 單一訊息 (接收或傳送) 的額外類別,用於新增氣泡「尾巴」message-same-name
- 指示訊息與前一則訊息具有相同寄件者姓名的額外類別message-same-avatar
- 指示訊息與前一則訊息具有相同頭像的額外類別message-same-header
- 指示訊息與前一則訊息具有相同訊息標頭的額外類別message-same-footer
- 指示訊息與前一則訊息具有相同訊息註腳的額外類別message-last
- 單一訊息 (接收或傳送) 的額外類別,用於指示由一位寄件者在目前對話中接收或傳送的最後一則訊息message-first
- 用於單一訊息(已接收或已傳送)的附加類別,用於表示目前對話中第一個接收或第一個傳送的訊息,由一位傳送者傳送
訊息應用程式方法
現在,當我們有訊息的 HTML 時,我們需要初始化它。我們需要使用相關應用程式的程式碼
app.messages.create(parameters) | 使用參數初始化訊息
|
app.messages.destroy(el) | 銷毀訊息實例
|
app.messages.get(el) | 透過 HTML 元素取得訊息實例
|
訊息參數
讓我們看看所有可用參數的清單
參數 | 類型 | 預設值 | 說明 |
---|---|---|---|
autoLayout | 布林值 | true | 啟用自動版面配置,以根據傳遞的條件自動新增所有必要的附加類別 |
newMessagesFirst | 布林值 | false | 如果你想要使用頂部的最新訊息,而不是在底部,請啟用 |
scrollMessages | 布林值 | true | 啟用/停用新增新訊息時訊息自動捲動 |
scrollMessagesOnEdge | 布林值 | true | 如果啟用,則僅當使用者在訊息檢視的頂部/底部時,訊息才會自動捲動 |
messages | 陣列 | 包含初始訊息的陣列。陣列中的每個訊息應表示為具有 單一訊息參數 的物件 | |
on | 物件 | 包含事件處理常式的物件。例如
| |
renderMessage | function(message) | 用於呈現單一訊息的函式。必須傳回完整的訊息 HTML 字串 | |
自動版面配置條件 | |||
firstMessageRule | function(message, previousMessage, nextMessage) | 函式,必須根據先前的訊息和後續訊息的必要條件傳回布林值 true 或 false 。如果符合條件,則會將 message-first 類別新增至訊息 | |
lastMessageRule | function(message, previousMessage, nextMessage) | 函式,必須根據先前的訊息和後續訊息的必要條件傳回布林值 true 或 false 。如果符合條件,則會將 message-last 類別新增至訊息 | |
tailMessageRule | function(message, previousMessage, nextMessage) | 函式,必須根據先前的訊息和後續訊息的必要條件傳回布林值 true 或 false 。如果符合條件,則會將 message-tail 類別新增至訊息 | |
sameNameMessageRule | function(message, previousMessage, nextMessage) | 函式,必須根據先前的訊息和後續訊息的必要條件傳回布林值 true 或 false 。如果符合條件,則會將 message-same-name 類別新增至訊息 | |
sameHeaderMessageRule | function(message, previousMessage, nextMessage) | 必須根據前則和後則訊息的必要條件回傳布林值 true 或 false 的函數。若符合條件,則會將 message-same-header 類別新增至訊息 | |
sameFooterMessageRule | function(message, previousMessage, nextMessage) | 必須根據前則和後則訊息的必要條件回傳布林值 true 或 false 的函數。若符合條件,則會將 message-same-footer 類別新增至訊息 | |
sameAvatarMessageRule | function(message, previousMessage, nextMessage) | 必須根據前則和後則訊息的必要條件回傳布林值 true 或 false 的函數。若符合條件,則會將 message-same-avatar 類別新增至訊息 | |
customClassMessageRule | function(message, previousMessage, nextMessage) | 必須根據前則和後則訊息的必要條件回傳其他訊息類別為字串的函數。 |
單一訊息參數
當我們傳遞 messages
陣列時,讓我們來看看我們應該使用的單一訊息參數物件
參數 | 類型 | 預設值 | 說明 |
---|---|---|---|
text | 字串 | 訊息文字 | |
header | 字串 | 單一訊息標題 | |
footer | 字串 | 單一訊息頁尾 | |
name | 字串 | 寄件者姓名 | |
avatar | 字串 | 寄件者頭像 URL 字串 | |
type | 字串 | sent | 訊息類型 - sent 或 received |
textHeader | 字串 | 訊息文字標題 | |
textFooter | 字串 | 訊息文字頁尾 | |
image | 字串 | 訊息圖片 HTML 字串,例如 <img src="path/to/image" /> 。可用於取代 imageSrc 參數 | |
imageSrc | 字串 | 訊息圖片 URL 字串。可用於取代 image 參數 | |
isTitle | 布林值 | 定義是否應呈現為訊息或訊息標題 | |
cssClass | 字串 | 設定在訊息 HTML 元素上的其他 CSS 類別 | |
attrs | 物件 | 物件包含要設定在訊息 HTML 元素上的其他 HTML 屬性。例如,若要設定額外的 data 屬性,它應如下所示
|
訊息方法和屬性
因此,若要建立訊息,我們必須呼叫
var messages = app.messages.create({ /* parameters */ })
在初始化訊息後,我們在變數中初始化其執行個體(例如上述範例中的 messages
變數),並具有有用的方法和屬性
屬性 | |
---|---|
messages.params | 包含已傳遞初始化參數的物件 |
messages.el | 訊息容器 HTML 元素(<div class="messages"> ) |
messages.$el | 包含訊息 HTML 元素的 Dom7 元素 |
messages.messages | 包含訊息的陣列 |
方法 | |
messages.showTyping(message) | 顯示輸入訊息指標
|
messages.hideTyping() | 隱藏輸入訊息指標 |
messages.addMessage(message, method, animate); | 根據 method 參數,將新訊息新增至尾端或開頭
|
messages.addMessages(messages, method, animate); | 一次新增多則訊息。
|
messages.removeMessage(message); | 移除訊息
|
messages.removeMessages(messages); | 移除多則訊息
|
messages.scroll(duration, position); | 根據 newMessagesFirst 參數將訊息捲動至頂端/底部
|
messages.renderMessages() | 根據 messages 陣列呈現訊息 HTML |
messages.layout(); | 強制訊息自動佈局 |
messages.clear(); | 清除/移除所有訊息 |
messages.destroy(); | 銷毀訊息實例 |
訊息事件
訊息將在訊息元素上觸發以下 DOM 事件,以及在應用程式和訊息實例上觸發事件
DOM 事件
事件 | 目標 | 說明 |
---|---|---|
messages:beforedestroy | 訊息元素<div class="messages"> | 事件將在訊息實例被銷毀之前觸發 |
應用程式和訊息實例事件
訊息實例會在自身實例和應用程式實例上發出事件。應用程式實例事件具有相同的名稱,但前綴為 messages
。
事件 | 目標 | 參數 | 說明 |
---|---|---|---|
beforeDestroy | messages | (messages) | 事件將在訊息實例被銷毀之前觸發 |
messagesBeforeDestroy | app |
訊息自動初始化
如果您不需要使用訊息 API,而且您的訊息在頁面內部,並在頁面初始化時顯示在 DOM 中,則只需將額外的 messages-init
類別新增到訊息元素即可自動初始化,並且可以使用 data-
屬性傳遞所有必需的參數
<div class="messages messages-init" data-new-messages-first="true">
...
</div>
在 camelCase 中使用的參數,例如 newMessagesFirst,在 data- 屬性中應使用 kebab-case,例如 data-new-messages-first
CSS 變數
以下是相關 CSS 變數 (CSS 自訂屬性) 的清單。
請注意,註解的變數預設未指定,它們的值是它們在此情況下的後備值。
:root {
--f7-message-text-header-opacity: 0.65;
--f7-message-text-header-font-size: 12px;
--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-typing-indicator-bg-color: #000;
}
:root .dark,
:root.dark {
--f7-message-typing-indicator-bg-color: #fff;
}
.ios {
--f7-message-text-header-text-color: inherit;
--f7-message-text-footer-text-color: inherit;
--f7-messages-title-font-size: 11px;
--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;
/*
--f7-message-sent-bg-color: var(--f7-theme-color);
*/
--f7-message-sent-text-color: #fff;
--f7-messages-content-bg-color: #fff;
--f7-message-received-text-color: #000;
--f7-message-received-bg-color: #e5e5ea;
--f7-messages-title-text-color: rgba(0, 0, 0, 0.45);
--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);
}
.ios .dark,
.ios.dark {
--f7-message-received-bg-color: #252525;
--f7-message-received-text-color: #fff;
--f7-messages-content-bg-color: transparent;
--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);
}
.md {
--f7-messages-content-bg-color: transparent;
--f7-messages-title-font-size: 12px;
--f7-message-avatar-size: 32px;
--f7-message-margin: 16px;
--f7-message-bubble-min-height: 40px;
--f7-message-bubble-font-size: 16px;
--f7-message-bubble-border-radius: 20px;
--f7-message-bubble-padding-vertical: 10px;
--f7-message-bubble-padding-horizontal: 16px;
--f7-message-typing-indicator-opacity: 0.6;
}
.md,
.md .dark,
.md [class*='color-'] {
--f7-message-sent-bg-color: var(--f7-md-primary);
--f7-message-sent-text-color: var(--f7-md-on-primary);
--f7-message-received-bg-color: var(--f7-md-surface-variant);
--f7-message-received-text-color: var(--f7-md-on-surface);
--f7-message-text-header-text-color: var(--f7-md-on-surface-variant);
--f7-message-text-footer-text-color: var(--f7-md-on-surface-variant);
--f7-messages-title-text-color: var(--f7-md-on-surface-variant);
--f7-message-header-text-color: var(--f7-md-on-surface-variant);
--f7-message-footer-text-color: var(--f7-md-on-surface-variant);
--f7-message-name-text-color: var(--f7-md-on-surface-variant);
}
範例
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Messages</div>
</div>
</div>
<div class="toolbar messagebar" @messagebar:attachmentdelete=${deleteAttachment}>
<div class="toolbar-inner">
<a class="link icon-only" @click=${sheetToggle}>
<i class="icon f7-icons if-not-md">camera_fill</i>
<i class="icon material-icons md-only">camera_alt</i>
</a>
<div class="messagebar-area">
<textarea class="resizable" placeholder="Message"></textarea>
</div>
<a class="link icon-only demo-send-message-link" @click=${sendMessage}>
<i class="icon f7-icons if-not-md">arrow_up_circle_fill</i>
<i class="icon material-icons md-only">send</i>
</a>
</div>
<div class="messagebar-sheet">
${images.map((image) => $h`
<label class="checkbox messagebar-sheet-image" @change=${handleAttachment}>
<input type="checkbox" />
<i class="icon icon-checkbox"></i>
<img src=${image} />
</label>
`)}
</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-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, $el, $on, $ }) => {
const images = [
'https://cdn.framework7.io/placeholder/cats-300x300-1.jpg',
'https://cdn.framework7.io/placeholder/cats-200x300-2.jpg',
'https://cdn.framework7.io/placeholder/cats-400x300-3.jpg',
'https://cdn.framework7.io/placeholder/cats-300x150-4.jpg',
'https://cdn.framework7.io/placeholder/cats-150x300-5.jpg',
'https://cdn.framework7.io/placeholder/cats-300x300-6.jpg',
'https://cdn.framework7.io/placeholder/cats-300x300-7.jpg',
'https://cdn.framework7.io/placeholder/cats-200x300-8.jpg',
'https://cdn.framework7.io/placeholder/cats-400x300-9.jpg',
'https://cdn.framework7.io/placeholder/cats-300x150-10.jpg'
];
const 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'
},
];
const 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!!!',
];
let responseInProgress = false;
let messagebar;
let messages;
const sheetToggle = () => {
messagebar.sheetToggle();
}
const deleteAttachment = (e, index) => {
var image = messagebar.attachments.splice(index, 1)[0];
messagebar.renderAttachments();
checkAttachments();
// Uncheck in sheet
var imageIndex = images.indexOf(image);
$el.value.find('.messagebar-sheet .checkbox').eq(imageIndex).find('input').prop('checked', false);
}
const handleAttachment = (e) => {
var index = $(e.target).parents('label.checkbox').index();
var image = images[index];
if (e.target.checked) {
// Add to attachments
messagebar.attachments.unshift(image)
} else {
// Remove from attachments
messagebar.attachments.splice(messagebar.attachments.indexOf(image), 1);
}
messagebar.renderAttachments();
checkAttachments();
}
const checkAttachments = () => {
if (messagebar.attachments.length > 0) {
messagebar.attachmentsShow();
messagebar.setPlaceholder('Add comment or Send');
} else {
messagebar.attachmentsHide();
messagebar.setPlaceholder('Message');
}
}
const sendMessage = () => {
var text = messagebar.getValue().replace(/\n/g, '<br />').trim();
var messagesToSend = [];
messagebar.attachments.forEach(function (attachment) {
var size = attachment.split('placeholder/cats-')[1].split('-')[0].split('x');
messagesToSend.push({
image: '<img src="' + attachment + '" style="width: ' + (size[0] / 2) + 'px; height: ' + (size[1] / 2) + 'px">'
});
});
if (text.trim().length) {
messagesToSend.push({
text: text
});
}
// Reset attachments
messagebar.attachments = [];
checkAttachments();
// Hide sheet
messagebar.sheetHide();
// Uncheck selected images in sheet
messagebar.$sheetEl.find('input').prop('checked', false);
// Clear area
messagebar.clear();
// Focus area
if (text.length) messagebar.focus();
// Exit when nothing to send
if (!messagesToSend.length) return;
// Send message
messages.addMessages(messagesToSend);
// Mock response
if (responseInProgress) return;
responseInProgress = true;
setTimeout(function () {
var answer = answers[Math.floor(Math.random() * answers.length)];
var person = people[Math.floor(Math.random() * people.length)];
messages.showTyping({
header: person.name + ' is typing',
avatar: person.avatar
});
setTimeout(function () {
messages.addMessage({
text: answer,
type: 'received',
name: person.name,
avatar: person.avatar
});
messages.hideTyping();
responseInProgress = false;
}, 4000);
}, 1000);
}
$on('pageInit', () => {
messagebar = $f7.messagebar.create({
el: $el.value.find('.messagebar'),
attachments: []
});
messages = $f7.messages.create({
el: $el.value.find('.messages'),
firstMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
return false;
},
lastMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
},
tailMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
}
});
})
$on('pageBeforeRemove', () => {
messagebar.destroy()
messages.destroy()
})
return $render;
};
</script>