这是学javascript做的项目,用到了jQuery。
思路:
因为整体朋友圈的界面是由信息遍历渲染得到的,在每条信息的div内部创建子元素‘回复弹出界面’和‘评论输入和发送界面’,每条信息有自己的索引,在click事件绑定之后,根据索引对相应数据的内容进行改动,再重新渲染到界面上,从而达到点赞和评论的效果。
<1>整体效果,数据遍历渲染
效果如图:
描述:
分为四种消息类型-多图片、分享、单图片、纯文字。
先设置各种消息的html模板,再遍历数据渲染后生成整个朋友圈。
实现代码:
①各个消息的模板
/**
* 多张图片消息模版
* @param {Object} pics 多图片消息的图片列表
* @return {String} 返回html字符串
*/
function multiplePicTpl(pics) {
var htmlText = [];
htmlText.push('<ul class="item-pic">');
for (var i = 0, len = pics.length; i < len; i++) {
htmlText.push('<img class="pic-item" src="' + pics[i] + '">')
}
htmlText.push('</ul>');
return htmlText.join('');
}
/**
* 分享消息模版
* @param {Object} share 分享的图片和信息
* @return {String} 返回html字符串
*/
function shareTpl(share) {
var htmlText = [];
htmlText.push('<div class="item-share">');
htmlText.push('<img class="sharepic" src="' + share.pic + '">');
htmlText.push('<span class="sharetext">' + share.text + '</span>');
htmlText.push('</div>');
return htmlText.join('');
}
/**
* 单图片消息模版
* @param {Object} pics 单图片消息的图片
* @return {String} 返回html字符串
*/
function singlePicTpl(pics) {
var htmlText = [];
htmlText.push('<img class="singlepic" src="' + pics + '">');
return htmlText.join('');
}
②switch语句判断消息类型
switch(content.type) {
// 多图片消息
case 0:
contentHtml = multiplePicTpl(content.pics);
break;
case 1:
// TODO: 实现分享消息
contentHtml = shareTpl(content.share);
break;
case 2:
// TODO: 实现单张图片消息
contentHtml = singlePicTpl(content.pics);
break;
case 3:
// TODO: 实现无图片消息
contentHtml = '';
break;
}
③遍历渲染
/**
* 页面渲染函数:render
*/
function render() {
// 使用遍历,将data数组中的每个消息都渲染一次
var messageHtml = [];
for(var i = 0;i < data.length; i++){
messageHtml.push(messageTpl(data[i]));
}
messageHtml = messageHtml.join('');
$momentsList.html(messageHtml);
}
<2>点赞评论弹出窗口
效果如图:
描述:
点击朋友圈消息下的按钮,会弹出点赞评论窗口,该窗口同一时间时只能存在一个,点击朋友圈其他地方的时候会隐藏点赞评论窗口。
实现代码:
①点赞评论窗口的HTML结构
/**
* 弹出点赞和评论按钮
* @param {Boolean} hasLiked 是否已点赞
* @return {String} 返回html字符串
*/
function panelTpl(hasLiked){
var likeText = hasLiked ? '取消' : '点赞';
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('');
}
②在每条消息的HTML中间插入点赞评论窗口
// 点赞和评论界面
htmlText.push(panelTpl(messageData.reply.hasLiked));
③绑定click事件
var $replypanel = $('.reply-panel');
$replypanel.hide();
// 鼠标点击回复按钮弹出点赞和评论的窗口
$('.moments-item').on('click','.item-reply',function(){
// 显示当前消息的回复操作面板
event.stopPropagation();//阻止 click 事件冒泡到父元素
$commentArea.animate({height:"hide"},1);
$('.reply-panel').animate({width:"hide"},150);
$(this).siblings('.reply-panel').animate({width:"show"},150);
});
PS:做得略有瑕疵。
<3>点赞和取消点赞
效果如图:
描述:
点击点赞按钮的时候,在下面点赞列表里会出现自己的用户名,同时点赞评论窗口的点赞变成取消,隐藏点赞评论窗口。
点击取消按钮的时候,就会从点赞列表里删除自己的用户名,同时点赞评论窗口的取消变成点赞,隐藏点赞评论窗口。
实现代码:
①点赞函数
/**
* 点赞函数
* @param {object} 点赞目标
*/
function clickLike($target){
// 创建数据索引
var index = $target.attr('data-index');
// 创建点赞状态
var like = data[index].reply.hasLiked;
// 如果like为false,即未点赞,进行点赞操作
if(!like){
// 改变数据中的点赞状态为true
data[index].reply.hasLiked = !like;
// 在数据中的点赞用户列表中加入自己的用户名
data[index].reply.likes.push(userName);
}
// 如果like为true,即已点赞,进行取消点赞操作
else{
// 改变数据中的点赞状态为false
data[index].reply.hasLiked = !like;
// 在数据中的点赞用户列表中删除自己的用户名
var likeIndex = data[index].reply.likes.indexOf(userName);
data[index].reply.likes.splice(likeIndex,1);
}
// 刷新点赞用户列表
$target.find('.reply-like').remove();
$target.find('.reply-zone').prepend(likesHtmlTpl(data[index].reply.likes));
// 修改reply-panel中点赞按钮的文字
var text = data[index].reply.hasLiked ? '取消' : '点赞';
$target.find('.text-like').html(text);
}
②click事件绑定
// 鼠标点击点赞按钮进行点赞和取消点赞的操作
$('.moments-item').on('click','.like',function(){
event.stopPropagation();
clickLike($(this).parents('.moments-item'));
$replypanel.animate({width:"hide"},150);
});
<4>评论
效果如图:
描述:
点击评论按钮的时候,在视窗的最下方出现input窗口,输入想要评论的内容点击发送或者按键盘上的enter键后,该条消息下方的评论列表会以“自己的用户名:input的内容”
的样式出现刚才输入的评论。
实现代码:
①评论函数
/**
* 评论函数
* @param {object} 评论目标
*/
function sendComment($target){
// 创建数据索引
var index = $target.attr('data-index');
// 如果评论输入框内有文字,则将输入的文字添加至data中的comments中
if($target.find('.comment-text').val()){
data[index].reply.comments.push({
author: userName,
text: $target.find('.comment-text').val()
});
}
// 刷新评论用户列表
$target.find('.reply-comment').remove();
$target.find('.reply-zone').append(commentsHtmlTpl(data[index].reply.comments));
// 隐藏评论界面
$target.find('.comment-area').animate({height:"hide"},1);
}
②click事件绑定
// 鼠标点击评论按钮进行评论的操作
$('.moments-item').on('click','.comment',function(){
event.stopPropagation();
$replypanel.animate({width:"hide"},150);
$(this).parents('.moments-item').find('.comment-area').animate({height:"toggle"},1);
$(this).parents('.moments-item').find('.comment-text')[0].focus();
});
// 鼠标点击发送按钮发送评论
$('.moments-item').on('click','.comment-send',function(){
if($(this).siblings('.comment-text').val()){
sendComment($(this).parents('.moments-item'));
$(this).siblings('.comment-text').val('');
$(this).css('background', '#dfdfdf');
$(this).css('cursor','auto');
$(this).attr('disabled', true);
}
});
③键盘事件绑定
// 键盘输入
$('.comment-text').on('keydown', function(event) {
// 按enter键等同于点击发送按钮
if(event.keyCode === 13) {
if($(this).val()){
sendComment($(this).parents('.moments-item'));
$(this).val('');
$(this).siblings('.comment-send').css('background', '#dfdfdf');
$(this).siblings('.comment-send').css('cursor','auto');
$(this).siblings('.comment-send').attr('disabled', true);
}
}
});
<5>评论输入界面的设置
效果如图:
描述:
点击评论按钮后评论输入界面弹出,input框获得焦点,未输入文字前发送按钮是灰色的且不可用,输入文字之后发送按钮变成绿色且可用。鼠标点击除评论输入界面的其他地方会隐藏该界面,Input框的内容会缓存,下次出现时之前输入的内容还在input框内。
实现代码:
①评论输入界面的HTML结构
// 评论输入和发送界面
htmlText.push('<div class="comment-area">');
htmlText.push('<input type="text" class="comment-text" placeholder="评论内容">');
htmlText.push('<button class="comment-send">发送</button>');
htmlText.push('</div>');
②事件绑定
// 评论输入框绑定
$('.comment-text').on('input',function(){
if($(this).val()){
$(this).siblings('.comment-send').css('background', '#3CB035');
$(this).siblings('.comment-send').css('cursor','pointer');
$(this).siblings('.comment-send').attr('disabled', false);
}else{
$(this).siblings('.comment-send').css('background', '#dfdfdf');
$(this).siblings('.comment-send').css('cursor','auto');
$(this).siblings('.comment-send').attr('disabled', true);
}
});
③优化
/**
* 优化: 点击不是回复按钮的地方则隐藏replypanel块
*/
$('body').on('click', function(event) {
var target = event.target;
if(target.className !== 'reply-panel'){
$replypanel.animate({width:"hide"},150);
}
if(target.className !== 'comment-area' && target.className !== 'comment-text' && target.className !== 'comment-send'){
$commentArea.animate({height:"hide"},1);
}
});
<6>放大查看图片
效果如图:
描述:
鼠标点击图片的时候,图片以黑色为背景放大居中显示,在页面的最上层,覆盖其他所有的元素。
再次点击任意处即可返回之前的朋友圈界面。
实现代码:
①HTML结构
<!-- 创建容纳放大图片的DIV -->
<div class="background">
<img src="" class="bigger-pic">
</div>
②CSS样式
/*放大图片的CSS样式*/
.background{
position: absolute;
display: block;
margin: 0 auto;
top: 0;
width: 100%;
max-width: 640px;
height: 0;
background: #000;
z-index: 4;
}
.background .bigger-pic{
width: 100%;
max-width: 640px;
position: fixed;
top: 50vh;
left: 50%;
transform: translate(-50%, -50%);
}
③click事件绑定
// 图片放大显示
$('.moments-item').on('click','.pic-item',function(){
var height = $page.height() + 'px';
$('.background').css({
'height': height,
'display': 'block'
});
$('.bigger-pic').attr('src',$(this).attr('src'));
});
$('.moments-item').on('click','.singlepic',function(){
var height = $page.height() + 'px';
$('.background').css({
'height': height,
'display': 'block'
});
$('.bigger-pic').attr('src',$(this).attr('src'));
});
// 图片隐藏
$('.page-moments').on('click','.background',function(){
$(this).css('display','none');
});
总结:
总是把简单的事情想复杂化,之前想了很久怎做弹出的界面,钻了牛角尖,等做出一个来之后,后面的要求就慢慢都会了,要把基础打牢,求精不求快。