- 實(shí)現(xiàn)四種消息類型
分享消息,單圖片消息的模板
/**
* 分享消息模板
* @param {object} 分享消息的內(nèi)容,包含圖片和文字
* @return {string} 返回html字符串
*/
function shareTpl(share) {
var htmlText = [];
htmlText.push('<div class="item-share">');
htmlText.push('<img class="share-img" src="' + share['pic'] + '">');
htmlText.push('<p clss="share-tt">' + share['text'] + '</p>');
htmlText.push('</div>');
return htmlText.join('');
}
/**
* 單圖片消息模板
* @param {object} 單圖片消息的圖片
* @return {string} 返回html字符串
*/
function onlyImgTpl(pics) {
var htmlText = [];
htmlText.push('<img class="item-only-img" src="' + pics[pics.length - 1] + '" >');
return htmlText.join('');
}
通過每一條消息的type值進(jìn)行匹配
switch (content.type) {
// 多圖片消息
case 0:
contentHtml = multiplePicTpl(content.pics);
break;
case 1:
// TODO: 實(shí)現(xiàn)分享消息
contentHtml = shareTpl(content.share);
break;
case 2:
// TODO: 實(shí)現(xiàn)單張圖片消息
contentHtml = onlyImgTpl(content.pics);
break;
case 3:
// TODO: 實(shí)現(xiàn)無圖片消息
contentHtml = '';
break;
}
在頁面渲染函數(shù)里,遍歷data即可
/**
* 頁面渲染函數(shù):render
*/
function render() {
// TODO: 目前只渲染了一個消息(多圖片信息),需要展示data數(shù)組中的所有消息數(shù)據(jù)。
var messageHtml = [];
for (var i = 0; i < data.length; i++) {
messageHtml.push(messageTpl(data[i], i));
}
messageHtml = messageHtml.join('');
$momentsList.html(messageHtml);
}

- 每一條消息都會帶有一個回復(fù)操作面板,
/*
*點(diǎn)擊回復(fù)按鈕彈出回復(fù)模板
*@param {Boolean} hasLiked 是否點(diǎn)過贊
*@return {String} 返回html字符串
*/
function replyPanelTpl(hasLiked) {
var likeText = hasLiked ? '取消' : '點(diǎn)贊';
var htmlText = [];
htmlText.push('<div class="reply-panel">');
htmlText.push('<div class="like">');
htmlText.push('<i class="icon-like"></i>');
htmlText.push('<span class="text-like">' + likeText + '</span>');
htmlText.push('</div>');
htmlText.push('<div class="comment">');
htmlText.push('<i class="icon-comment"></i>');
htmlText.push('<span class="text-comment">評論</span>');
htmlText.push('</div>');
htmlText.push('</div>');
return htmlText.join('');
}
默認(rèn)狀態(tài)均為隱藏,點(diǎn)擊時,通過篩選className,通過改變面板的width使其顯示,并有一個出現(xiàn)動畫
// 彈出回復(fù)操作面板
case 'item-reply':
//隱藏掉所有的回復(fù)操作面板和評論框
hidePanel();
// 顯示當(dāng)前消息的回復(fù)操作面板
$this.siblings('.reply-panel').css('width', '160px');
break;

總結(jié):開始想,只用一個回復(fù)操作面板,可以減少html代碼量和搜索,用一個全局變量curMomentItem來記錄當(dāng)前想要點(diǎn)贊和評論的是哪一條消息。
后來,考慮到之前老師說要盡量少使用全局變量,于是,采用了每一條消息都有一個回復(fù)面板,用增加html代碼量的方法取代了。
最終雖然實(shí)現(xiàn)了功能,但總感覺有點(diǎn)冗余,不夠精簡
想請問老師,有沒有更好的實(shí)現(xiàn)方法?或者在實(shí)際開發(fā)中,那個會更好?
- 實(shí)現(xiàn)點(diǎn)贊功能
當(dāng)點(diǎn)擊了回復(fù)面板中的
// 點(diǎn)贊或取消贊
case 'like':
case 'icon-like':
case 'text-like':
changeLike($this.parents('.moments-item'));
hidePanel();
break;
點(diǎn)贊或取消函數(shù)
/**
* 點(diǎn)贊函數(shù)
* @param {object} 點(diǎn)贊目標(biāo)
*/
function changeLike($target) {
// 點(diǎn)贊的消息索引
var index = $target.attr('data-index');
// 修改data中的點(diǎn)贊狀態(tài)
var like = data[index].reply.hasLiked;
// 若原來沒有點(diǎn)贊,則點(diǎn)贊,
if (!like) {
// 修改本人的點(diǎn)贊狀態(tài)
data[index].reply.hasLiked = !like;
// 修改點(diǎn)贊人列表
data[index].reply.likes.push(userName);
}
// 如果原來點(diǎn)贊,則取消點(diǎn)贊
else {
// 修改本人的點(diǎn)贊狀態(tài)
data[index].reply.hasLiked = !like;
// 在點(diǎn)贊人列表中刪除本人
var likeIndex = data[index].reply.likes.indexOf(userName); //找到本人在點(diǎn)贊列表中的索引
data[index].reply.likes.splice(likeIndex, 1); // 刪除
}
// 刪除原來的點(diǎn)贊列表
$target.find('.reply-like').remove();
// 重新渲染點(diǎn)贊列表
$target.find('.reply-zone').prepend(likesHtmlTpl(data[index].reply.likes));
// 修改點(diǎn)贊面板中的文字
var text = data[index].reply.hasLiked ? '取消' : '點(diǎn)贊';
$target.find('.text-like').html(text);
}
效果

總結(jié):

如上圖,當(dāng)點(diǎn)擊左邊區(qū)域時,都要觸發(fā)點(diǎn)贊或取消
由于之前的點(diǎn)擊事件是通過事件委托的形式實(shí)現(xiàn)的,于是,在這里,將點(diǎn)擊目標(biāo)細(xì)分為三種,整個
div,圖標(biāo)以及點(diǎn)贊文字疑問:如果把這種需要對整個容器都反應(yīng)的點(diǎn)擊是否不使用事件委托會更好?
4.實(shí)現(xiàn)增加評論功能
當(dāng)點(diǎn)擊評論時
// 評論
case 'comment':
case 'icon-comment':
case 'text-comment':
hidePanel();
// 展現(xiàn)當(dāng)前消息的評論框
$this.parents('.item-right').children('.comment-form').css('display', 'flex');
// 讓當(dāng)前消息的評論框獲得焦點(diǎn)
$this.parents('.item-right').children('.comment-form').children('.comment-text')[0].focus();
實(shí)時檢測輸入框是否為空
// 評論輸入框?qū)崟r綁定
$('.comment-text').on('input', function() {
var $this = $(this);
if ($this.val()) {
// 如果內(nèi)容不為空,則發(fā)送按鈕背景為綠色,并且可用
$('.comment-submit').css('background', '#44b00e');
$('.comment-submit').attr('disabled', false);
} else {
// 如果內(nèi)容為空,則發(fā)送按鈕背景為灰色,不可用
$('.comment-submit').css('background', '#808080cc');
$('.comment-submit').attr('disabled', true);
}
});
點(diǎn)擊發(fā)送按鈕
// 發(fā)送評論
case 'comment-submit':
commentSubmit($this);
break;
在輸入框按下enter鍵,同樣可以發(fā)送消息
// 按下enter鍵自動提交評論
$('.comment-text').on('keydown', function(event) {
// 判斷按下的是否為enter鍵
if (event.keyCode === 13) {
commentSubmit($(this).siblings('.comment-submit'));
}
});
發(fā)送評論函數(shù)
/**
* 評論函數(shù)
* @param {object} 提交按鈕
*/
function commentSubmit(target) {
var $this = target;
// 生成新的評論html代碼
var commentHtml = '<div class="comment-item">' +
'<a class="reply-who" href="#">' +
userName +
'</a>:' +
$this.siblings('.comment-text').val() +
'</div>';
// 找到當(dāng)前消息的回復(fù)評論
var $replyComment = $this.parents('.item-right').find('.reply-comment');
// 如果沒有評論列表,需要新建一個評論列表框
if (!$replyComment.length) {
var replyCommentHtml = '<div class="reply-comment"></div>';
var $replyZone = $this.parents('.item-right').find('.reply-zone');
// 新建一個評論列表框
$replyZone.append(replyCommentHtml);
$replyComment = $replyZone.children('.reply-comment');
}
// 添加新評論
$replyComment.append(commentHtml);
// 刪除掉輸入框里的文字
$this.siblings('.comment-text').val('');
// 隱藏評論框
$('.comment-form').css('display', 'none');
// 修改消息體,增加當(dāng)前消息的一條評論
var index = $this.parents('.moments-item').attr('data-index');
data[index].reply.comments.push({
author: userName,
text: $this.siblings('.comment-text').val()
});
console.log(data[index].reply.comments);
}
演示


總結(jié):評論與點(diǎn)贊相同,也是每一條消息有一個評論框,初始都是隱藏的,直到被點(diǎn)擊
4.實(shí)現(xiàn)點(diǎn)擊放大圖片
html代碼
<div class="layer">
<img src="" class="pic-enlarge">
</div>
對應(yīng)的css代碼
.page-moments .layer{
position: absolute;
display: block;
margin: 0 auto;
top: 0;
width: 100%;
max-width: 640px;
height: 0;
background: #000;
z-index: 999;
}
.layer .pic-enlarge{
width: 100%;
max-width: 500px;
max-height: 500px;
position: fixed;
top: 50vh;
left: 50%;
transform: translate(-50%, -50%);
}
點(diǎn)擊處理
// 放大圖片
case 'pic-item':
case 'item-only-img':
hidePanel();
// 獲取頁面
var height = $page.height() + 'px';
// 設(shè)置籠罩層的高度和顯示
$('.layer').css({
'height': height,
'display': 'block'
});
// 設(shè)置放大圖片的地址
$('.pic-enlarge').attr('src', $this.attr('src'));
break;
// 隱藏放大圖片區(qū)域
case 'layer':
case 'pic-enlarge':
hidePanel();
$('.layer').css('display', 'none');
break;
總結(jié):主要是并沒有設(shè)置背景層的高度,想著把高度設(shè)成與想個朋友圈頁面高度一致,但好像在實(shí)際手機(jī)中并不需要只要是手機(jī)屏幕的高度就可以了,但如果這樣子在網(wǎng)頁中就沒有罩住整個頁面,當(dāng)滾動的時候就會看到下面的消息,所以,在js中,用獲取page的高度,設(shè)置成一樣的。
另外,放大后的圖片設(shè)置最大高寬為500px,有嘗試設(shè)置成640px,那樣照片放大后有點(diǎn)模糊,所以,改成500px了,于是,就想著上下左右各留一點(diǎn)空隙
不知道這種想法是否正確,還請老師指點(diǎn)。
收獲與不足:
不足:自己對于jqery的一些方法和屬性還不太熟悉
比如children()和find(),一開始以為`children()'是找到所有的后代元素,花了好久測試以及搜索才知道原來只是找到直接子元素。
收獲:相對地,通過發(fā)現(xiàn)自己的不足,把不熟悉的屬性通過查資料更加熟悉了,更了解了。