JS 仿腾讯发表微博的效果

最近2天研究了下 腾讯发表微博的效果 特此来分享下,效果如下:

在此分享前 来谈谈本人编写代码的习惯,很多人会问我既然用的是jquery框架 为什么写的组件不用Jquery那种形式?我当时回答的是:每个人编写代码有每个人的习惯。但是我更想表达的是:这种编码个人觉得 有一个很大的优点,我不是非常依赖于Jquery框架,因为不同的公司有不同的框架 比如在淘宝用的kissy框架 在支付宝用的是支付宝框架 在百度用的是百度框架 在腾讯有腾讯的前端js框架 假如我的编写代码太依赖于jquery 那假如其他人想要用我代码或者我自己某一天去做腾讯项目了 但是他们那边要求我们只能用他们的JS框架 且又有这样的功能?那如果我完全依赖jquery那种形式编码 那现在我是不是要重新编码呢?如果按照现在编码方式去编码 最多只是用了下jquery选择器而已 那么只要改下选择器 其他的代码都可以直接拿来用,这样的扩张性非常好!我个人觉得作为一个专业的前端开发,不仅仅只会一点点jquery做做东西,而更应该考虑编写高质量的代码,可能用jquery写写简单的代码同样能做好某个东西,但是有没有考虑到假如某一天需求增加了某某功能 你是不是又要改代码?能不能在以前的基础上重新写新的功能?而无需改代码!

何谓高质量的代码?

个人觉得必须满足以下几点:

1. 可扩展性。

2. 可维护性。

3. 可读性,易使用性。

4. JS性能。

最主要满足以上几点。

好了 废话不多说了!转主题,目前我做的这个发表微博效果 只是简单的 当然腾讯发表微博有一些复杂的功能 比如说下面有添加表情等等功能,目前没有做成那样的(工作量比较大)。

下面我写的这个JS代码需要注意2点:

1.每次发表下后 大家在说列表会添加一条,目前没有发ajax请求 后台没有记录 所以刷新页面 会清掉。

2. 时间是用的是客户端时间 假如客户端时间错误的话 那么时间也会受影响。

其实思路很简单 看上面的效果就明白 所以思路在这边不多说了!或者我下面会提供压缩demo 可以自己下载下来看看效果就ok了!每次发表一次后 都提供了回调 作为扩展吧!当然鼠标移到某一项时候 会出现删除按钮 同时可以任意删除某一项。直接贴代码吧 也没有什么好说的!

HTML代码如下:

<div id="msgBox">
<form>
<h2>来 , 说说你在做什么 , 想什么</h2>
<div>
<input id="userName" class="f-text" value="" />
<p id="face">
<img src="img/face1.gif" class="current" />
<img src="img/face2.gif" />
<img src="img/face3.gif" />
<img src="img/face4.gif" />
<img src="img/face5.gif" />
<img src="img/face6.gif" />
<img src="img/face7.gif" />
<img src="img/face8.gif" />
</p>
</div>
<div>
<textarea id="conBox" class="f-text"></textarea>
</div>
<div class="tr">
<p>
<span class="countTxt">还能输入</span><strong class="maxNum">140</strong><span>个字</span>
<input id="sendBtn" type="button" value="" title="快捷键 Ctrl+Enter" />
</p>
</div>
</form>
<div class="list">
<h3><span>大家在说</span></h3>
<ul id="list-msg"></ul>
</div>
</div>

CSS代码如下:

body,div,h2,h3,ul,li,p{margin:;padding:;}
a{text-decoration:none;}
a:hover{text-decoration:underline;}
ul{list-style-type:none;}
body{color:#333;background:#3c3a3b;font:12px/1.5 \5b8b\4f53;}
#msgBox{width:500px;background:#fff;border-radius:5px;margin:10px auto;padding-top:10px;}
#msgBox form h2{font-weight:;font:400 18px/1.5 \5fae\8f6f\96c5\9ed1;}
#msgBox form{background:url(img/boxBG.jpg) repeat-x 0 bottom;padding:0 20px 15px;}
#userName,#conBox{color:#777;border:1px solid #d0d0d0;border-radius:6px;background:#fff url(img/inputBG.png) repeat-x;padding:3px 5px;font:14px/1.5 arial;}
#userName.active,#conBox.active{border:1px solid #7abb2c;}
#userName{height:20px;}
#conBox{width:448px;resize:none;height:65px;overflow:auto;}
#msgBox form div{position:relative;color:#999;margin-top:10px;}
#msgBox img{border-radius:3px;}
#face{position:absolute;top:;left:172px;}
#face img{float:left;display:inline;width:30px;height:30px;cursor:pointer;margin-right:6px;opacity:0.5;filter:alpha(opacity=50);}
#face img.hover,#face img.current{width:28px;height:28px;border:1px solid #f60;opacity:;filter:alpha(opacity=100);}
#sendBtn{border:;width:112px;height:30px;cursor:pointer;margin-left:10px;background:url(img/btn.png) no-repeat;}
#sendBtn.hover{background-position:0 -30px;}
#msgBox form .maxNum{font:26px/30px Georgia, Tahoma, Arial;padding:0 5px;}
#msgBox .list{padding:10px;}
#msgBox .list h3{position:relative;height:33px;font-size:14px;font-weight:;background:#e3eaec;border:1px solid #dee4e7;}
#msgBox .list h3 span{position:absolute;left:6px;top:6px;background:#fff;line-height:28px;display:inline-block;padding:0 15px;}
#msgBox .list ul{overflow:hidden;zoom:;}
#msgBox .list ul li{float:left;clear:both;width:100%;border-bottom:1px dashed #d8d8d8;padding:10px 0;background:#fff;overflow:hidden;}
#msgBox .list ul li.hover{background:#f5f5f5;}
#msgBox .list .userPic{float:left;width:50px;height:50px;display:inline;margin-left:10px;border:1px solid #ccc;border-radius:3px;}
#msgBox .list .content{float:left;width:400px;font-size:14px;margin-left:10px;font-family:arial;word-wrap:break-word;}
#msgBox .list .userName{display:inline;padding-right:5px;}
#msgBox .list .userName a{color:#2b4a78;}
#msgBox .list .msgInfo{display:inline;word-wrap:break-word;}
#msgBox .list .times{color:#889db6;font:12px/18px arial;margin-top:5px;overflow:hidden;zoom:;}
#msgBox .list .times span{float:left;}
#msgBox .list .times a{float:right;color:#889db6;}
.tr{overflow:hidden;zoom:;}
.tr p{float:right;line-height:30px;}
.tr *{float:left;}
.hidden {display:none;}

JS代码如下:

/**
* 仿腾讯发表微博的效果
* 1.目前没有发ajax请求 后台没有记录 所以刷新页面 会清掉
* 2. 时间是用的是客户端时间 假如客户端时间错误的话 那么时间也会受影响。
* 目前就这样交互 具体的思路不太复杂 如果项目中用到这样的 可以根据具体的需求更改
* @constructor Microblog
* @date 2013-12-23
* @author tugenhua
* @email 879083421@qq.com
*/ function Microblog(options) { this.config = {
maxNum : 140, // 最大的字符数
targetElem : '.f-text', // 输入框 或者文本域的class名
maxNumElem : '.maxNum', // 还能输入多少字容器
sendBtn : '#sendBtn', // 广播按钮
face : '#face', // 表情容器
activeCls : 'active', // 鼠标点击输入框add类
currentCls : 'current', // 鼠标点击face头像时 增加的类名
inputID : '#userName', // 输入框ID
textareaId : '#conBox', // 文本域ID
list : '#list-msg', // 大家在说的容器
callback : null // 动态广播完后的回调函数
}; this.cache = {};
this.init(options);
} Microblog.prototype = { constructor: Microblog, init: function(options) {
this.config = $.extend(this.config,options || {});
var self = this,
_config = self.config,
_cache = self.cache; // 点击输入框input 文本域 textarea 边框的变化
$(_config.targetElem).each(function(index,item){ $(item).unbind('focus');
$(item).bind('focus',function(e){
!$(this).hasClass(_config.activeCls) && $(this).addClass(_config.activeCls);
});
$(item).unbind('blur');
$(item).bind('blur',function(e){
$(this).hasClass(_config.activeCls) && $(this).removeClass(_config.activeCls);
});
}); // 点击face头像 add(增加)类名
var faceImg = $('img',$(_config.face));
$(faceImg).each(function(index,item){
$(item).unbind('click');
$(item).bind('click',function(e){
$(this).addClass(_config.currentCls).siblings().removeClass(_config.currentCls);
});
}); // 广播按钮hover事件
$(_config.sendBtn).hover(function(){
!$(this).hasClass('hover') && $(this).addClass('hover');
},function(){
$(this).hasClass('hover') && $(this).removeClass('hover');
}) // 绑定事件
self._bindEnv();
},
/*
* 计算字符的长度 包括中文 数字 英文等等
* @param str
* @return 字符串的长度
*/
_countCharacters: function(str) {
var totalCount = 0;
for (var i=0; i<str.length; i++) {
var c = str.charCodeAt(i);
if ((c >= 0x0001 && c <= 0x007e) || (0xff60<=c && c<=0xff9f)) {
totalCount++;
}else {
totalCount+=2;
}
}
return totalCount;
},
/*
* 所有的绑定事件
*/
_bindEnv: function() {
var self = this,
_config = self.config,
_cache = self.cache; // 文本域keyup事件
self._keyUp(); // 点击广播按钮事件
self._clickBtn();
},
/*
* 文本域keyup事件
*/
_keyUp: function() {
var self = this,
_config = self.config,
_cache = self.cache;
$(_config.textareaId).unbind('keyup');
$(_config.textareaId).bind('keyup',function(){
var len = self._countCharacters($(this).val()),
html;
if(_config.maxNum * 1 >= len * 1) {
html = _config.maxNum * 1 - len * 1;
}else {
html = _config.maxNum * 1 - len * 1;
}
$(_config.maxNumElem).html(html);
$(_config.maxNumElem).attr('data-html',html);
});
},
/*
* 点击广播按钮事件
*/
_clickBtn: function() { var self = this,
_config = self.config,
_cache = self.cache;
var reg = /^\s*$/g;
$(_config.sendBtn).unbind('click');
$(_config.sendBtn).bind('click',function(){ var inputVal = $(_config.inputID).val(),
textVal = $(_config.textareaId).val(),
maxNum = $(_config.maxNumElem).attr('data-html');
if(reg.test(inputVal)) {
alert('请输入你的姓名');
return;
}else if(reg.test(textVal)) {
alert("随便说点什么吧!");
return;
}
if(maxNum * 1 < 0) {
alert('字符超过限制 请缩减字');
return;
}
// 本来是要发ajax请求的 但是这边没有后台处理 所以目前只是客户端渲染页面
self._renderHTML(inputVal,textVal);
});
},
/*
* 把html结构渲染出来
*/
_renderHTML: function(inputVal,textVal) {
var self = this,
_config = self.config,
_cache = self.cache;
var oLi = document.createElement("li"),
oDate = new Date();
oLi.innerHTML = '<div class="userPic">' +
'<img src="'+self._getSrc()+'" />'+
'</div>' +
'<div class="content">' +
'<div class="userName"><a href="javascript:;">'+inputVal+'</a>:</div>' +
'<div class="msgInfo">'+textVal+'</div>' +
'<div class="times">'+
'<span>'+self._format(oDate.getMonth() + 1) + "\u6708" + self._format(oDate.getDate()) + "\u65e5 " + self._format(oDate.getHours()) + ":" + self._format(oDate.getMinutes())+'</span>'+
'<a class="del hidden" href="javascript:;">删除</a>'+
'</div>' +
'</div>';
// 插入元素
if($(_config.list + " li").length > 0) { $(oLi).insertBefore($(_config.list + " li")[0]);
self._animate(oLi);
}else { $(_config.list).append(oLi);
self._animate(oLi); }
_config.callback && $.isFunction(_config.callback) && _config.callback(); // 清空输入框 文本域的值
self._clearVal(); // hover事件
self._hover();
},
/*
* 格式化时间, 如果为一位数时补0
*/
_format: function(str){
return str.toString().replace(/^(\d)$/,"0$1");
},
/*
* 获取ing src
* @return src
*/
_getSrc: function() {
var self = this,
_config = self.config,
_cache = self.cache;
var faceImg = $('img',$(_config.face)); for(var i = 0; i < faceImg.length; i++) {
if($(faceImg[i]).hasClass(_config.currentCls)) {
return $(faceImg[i]).attr('src');
break;
}
}
},
/*
* 清空值
*/
_clearVal: function() {
var self = this,
_config = self.config,
_cache = self.cache; $(_config.inputID) && $(_config.inputID).val('');
$(_config.textareaId) && $(_config.textareaId).val(''); },
/*
* hover事件
*/
_hover: function() {
var self = this,
_config = self.config,
_cache = self.cache;
$(_config.list + ' li').hover(function(){
!$(this).hasClass('hover') && $(this).addClass('hover').siblings().removeClass('hover');
$('.del',$(this)).hasClass('hidden') && $('.del',$(this)).removeClass('hidden');
var $that = $(this); // 删除事件
$('.del',$that).unbind('click');
$('.del',$that).bind('click',function(){ $($that).animate({
'opacity' : 0
},500,function(){
$that.remove();
});
});
},function(){
$(this).hasClass('hover') && $(this).removeClass('hover');
!$('.del',$(this)).hasClass('hidden') && $('.del',$(this)).addClass('hidden');
}); },
/*
* height
*/
_animate: function(oLi) {
var self = this;
var iHeight = $(oLi).height(),
alpah = 0,
timer,
count = 0;
$(oLi).css({"opacity" : "0", "height" : "0"}); timer && clearInterval(timer);
timer = setInterval(function (){
$(oLi).css({"display" : "block", "opacity" : "0", "height" : (count += 8) + "px"});
if (count > iHeight){
clearInterval(timer);
$(oLi).css({ "height" : iHeight + "px"});
timer = setInterval(function (){
$(oLi).css({"opacity" : alpah += 10}); alpah > 100 && (clearInterval(timer), $(oLi).css({"opacity":100})); },30);
}
},30);
}
}; // 初始化代码
$(function(){
new Microblog({});
});

Demo下载

今天是平安夜 最后祝福大家平安夜快乐!

JS 仿腾讯发表微博的效果的更多相关文章

  1. Js仿腾讯微博效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  2. JS实现仿腾讯微博无刷新删除微博效果代码

    这里演示JS仿腾讯微博无刷新删除效果,将显示在微博列表里的内容删除,运用AJAX技术,无刷新删除微博的内容,参考性强,希望对初学AJAX的朋友有所帮助. 在线演示地址如下: http://demo.j ...

  3. 完美拖拽 &&仿腾讯微博效果&& 自定义多级右键菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 仿腾讯微博的一个弹出框 v0.1 beta

    仿腾讯微博的一个弹出框 v0.1 beta   代码写的不太好,新手请大家海涵,只为博君一笑,勿放在心上. 写在这里留作纪念,也许以后用的到. 效果 CSS .prompt{ position: ab ...

  5. Jquery实现仿腾讯微薄的广播发表

    前言: 由于这几天在学习Jquery的一些知识,比以前的感觉就是Jquery太强大了,很多很简单的功能以前在JavaScript要写几十行的代码而在Jquery中只用几行代码就搞定了,所以我决定好好学 ...

  6. JS仿淘宝详情页菜单条智能定位效果

    类似于淘宝详情页菜单条智能定位 对于每个人来说并不陌生!如下截图所示:红色框的那部分! 基本原理: 是用JS侦听滚动事件,当页面的滚动距离(页面滚动的高度)大于或者等于 "对象"( ...

  7. 原生JS+tween.js模仿微博发布效果

    转载请注明出处:http://www.cnblogs.com/zhangmingze/p/4816865.html 1.先看效果吧,有效果才有动力: 2.html结构: <!DOCTYPE ht ...

  8. JS仿QQ空间鼠标停在长图片时候图片自动上下滚动效果

    JS仿QQ空间鼠标停在长图片时候图片自动上下滚动效果 今天是2014年第一篇博客是关于类似于我们的qq空间长图片展示效果,因为一张很长的图片不可能全部把他展示出来,所以外层用了一个容器给他一个高度,超 ...

  9. js控住DOM实现发布微博简单效果

    这段代码的效果具体是输入标题和内容,点击发布把消息发布出去,并使最新的消息始终在内容的最上面,代码为: <!DOCTYPE html> <html lang="en&quo ...

随机推荐

  1. Android - AssetManager

    http://blog.csdn.net/luoshengyang/article/details/8791064

  2. BZOJ3165: [Heoi2013]Segment(李超线段树)

    题意 题目链接 Sol 李超线段树板子题.具体原理就不讲了. 一开始自己yy着写差点写自闭都快把叉积搬出来了... 后来看了下litble的写法才发现原来可以写的这么清晰简洁Orz #include& ...

  3. .net4.0多进程间共享内存实现通信(VB.Net)

    .net4.0新增内存共享功能,从而很方便的实现了多进程间通信. 源码下载

  4. Android Studio 编译: Program type already present: XXX 解决方案

    3情况1:个例 build.gradle 中 dependencies { classpath 'com.android.tools.build:gradle:3.1.1' // } 改成 depen ...

  5. Vue -- webpack 项目自动打包压缩成zip文件

    这段时间用 Vue2.0 开发项目,每次打包都会用到 npm run build 命令,但是每次部署时给后端发包都要手动zip压缩,这样一两次还行,但遇到项目板块测试和临时加急功能测试的时候,一天可能 ...

  6. JUnit手动设计测试方法以及与Randoop的自动生成测试的比较

    手动设计测试 在已有的web project本地目录lib文件夹里导入两个jar文件(版本可不一样):junit-4.12.jar和hamcrest.jar 打开eclipse,导入项目,右击项目选择 ...

  7. tomcat catalina.out日志切割(logrotate)

    简单说明: 1,因为tomcat日志会一直往catalina.out里面输出,所以回到值catalina.out非常大,占用磁盘空间 2,日志非常大,查看日志就需要很长时间. 3,据说catalina ...

  8. linq not in 查询

    想要的sql: select A.* from BL_BCSS_Invoice A join BL_BCSS_OfflineInvoice B on A.ID!=B.InvoiceID; 不知道如何写 ...

  9. Oracle EBS AP取消核销

    --取消核销 created by jenrry 20170425 DECLARE l_result BOOLEAN; l_msg_count NUMBER; l_result_n varchar2( ...

  10. 无法将数据库从SINGLE_USER模式切换回MULTI_USER模式(Error 5064),及查找SQL Server数据库中用户spid(非SQL Server系统spid)的方法

    今天公司SQL Server数据库无意间变为SINGLE_USER模式了,而且使用如下语句切换回MULTI_USER失败: ALTER DATABASE [MyDB] SET MULTI_USER W ...