In the past two days, I have studied the effects of Tencent’s Weibo posts and would like to share them. The effects are as follows:
Before sharing here, I would like to talk about my coding habits. Many people will ask me why I don’t write components in the form of Jquery since I use the jquery framework? My answer at the time was: Everyone has their own habits when writing code. But what I want to express more is: I personally feel that this kind of coding has a big advantage. I am not very dependent on the Jquery framework, because different companies have different frameworks. For example, the kissy framework used in Taobao and the Alipay framework used in Alipay Baidu uses the Baidu framework and Tencent has Tencent’s front-end js framework. If my code is too dependent on jquery What if other people want to use my code or I want to work on a Tencent project one day, but they require us to only use their JS framework and have such a function? So if I completely rely on jquery's form of encoding, do I have to re-encode it now? If you code according to the current coding method, you will only use the jquery selector. Then as long as you change the selector, other codes can be used directly. This kind of scalability is very good! I personally feel that as a professional front-end developer, you should not only know a little bit of jquery to make things, but should also consider writing high-quality code. Maybe writing simple code with jquery can also do something well, but is there any Considering that if a certain function is added to the demand one day, will you have to change the code again? Can we rewrite new functions based on the previous ones? No need to change the code!
What is high-quality code?
Personally, I think the following points must be met:
1. Scalability.
2. Maintainability.
3. Readability and ease of use.
4. JS performance.
The most important thing is to meet the above points.
Okay, no more nonsense! Changing the topic, the effect of posting on Weibo is just simple. Of course, Tencent has some complex functions for posting on Weibo, such as adding emoticons, etc., but it has not been made like that at present (the workload is relatively large).
The JS code I wrote below needs to pay attention to two points:
1. Everyone is saying that an item will be added to the list after each publication. Currently, there is no ajax request sent and there is no record in the background, so refreshing the page will clear it.
2. The time is based on the client time. If the client time is wrong, the time will also be affected.
In fact, the idea is very simple. You can understand it just by looking at the effect above, so I won’t go into details here! Or I will provide a compressed demo below. You can download it yourself and see the effect! A callback is provided as an extension after each publication! Of course, when the mouse moves to an item, a delete button will appear and an item can be deleted at will. There is nothing much to say if you post the code directly!
The HTML code is as follows:
Copy the code code as follows:
<div id="msgBox">
<form>
<h2>Come, tell me what you are doing and what you are thinking</h2>
<div>
<input id="userName" value="" />
<p id="face">
<img src="img/face1.gif" />
<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"></textarea>
</div>
<div>
<p>
<span>Can also enter</span><strong>140</strong><span> characters</span>
<input id="sendBtn" type="button" value="" />
</p>
</div>
</form>
<div>
<h3><span>Everyone is talking</span></h3>
<ul id="list-msg"></ul>
</div>
</div>
The CSS code is as follows:
Copy the code code as follows:
body,div,h2,h3,ul,li,p{margin:0;padding:0;}
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:400;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:0;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:1;filter:alpha(opacity=100);}
#sendBtn{border:0;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:400;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:1;}
#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:1;}
#msgBox .list .times span{float:left;}
#msgBox .list .times a{float:right;color:#889db6;}
.tr{overflow:hidden;zoom:1;}
.tr p{float:right;line-height:30px;}
.tr *{float:left;}
.hidden {display:none;}
The JS code is as follows:
Copy the code code as follows:
/**
*Imitate the effect of Tencent publishing on Weibo
* 1. Currently there is no ajax request sent and there is no record in the background, so refreshing the page will clear it.
* 2. The time is based on the client time. If the client time is wrong, the time will also be affected.
* At present, the specific idea of interacting like this is not too complicated. If this is used in the project, it can be changed according to specific needs.
* @constructor Microblog
* @date 2013-12-23
* @author tugenhua
* @email [email protected]
*/
function Microblog(options) {
this.config = {
maxNum : 140, // Maximum number of characters
targetElem: '.f-text', // The class name of the input box or text field
maxNumElem: '.maxNum', // How many more word containers can be entered
sendBtn : '#sendBtn', // Broadcast button
face : '#face', // emoticon container
activeCls: 'active', //Mouse click input box add class
currentCls: 'current', // The class name added when the mouse clicks on the face avatar
inputID : '#userName', //Input box ID
textareaId : '#conBox', // Text area ID
list : '#list-msg', // The container everyone is talking about
callback: null // callback function after dynamic broadcast
};
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;
// Click the input box input text area textarea border changes
$(_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);
});
});
// Click on the face avatar to add (add) class name
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);
});
});
//Broadcast button hover event
$(_config.sendBtn).hover(function(){
!$(this).hasClass('hover') && $(this).addClass('hover');
},function(){
$(this).hasClass('hover') && $(this).removeClass('hover');
})
//Bind event
self._bindEnv();
},
/*
* Calculate the length of characters including Chinese numbers, English, etc.
* @param str
* @return the length of the string
*/
_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;
},
/*
* All binding events
*/
_bindEnv: function() {
var self = this,
_config = self.config,
_cache = self.cache;
//Text field keyup event
self._keyUp();
// Click broadcast button event
self._clickBtn();
},
/*
* Text field keyup event
*/
_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);
});
},
/*
* Click broadcast button event
*/
_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('Please enter your name');
return;
}else if(reg.test(textVal)) {
alert("Just say something!");
return;
}
if(maxNum * 1 < 0) {
alert('The characters exceed the limit, please reduce the characters');
return;
}
// Originally, we were going to send an ajax request, but there is no background processing here, so currently we are just rendering the page on the client side.
self._renderHTML(inputVal,textVal);
});
},
/*
* Render the html structure
*/
_renderHTML: function(inputVal,textVal) {
var self = this,
_config = self.config,
_cache = self.cache;
var oLi = document.createElement("li"),
oDate = new Date();
oLi.innerHTML = '<div>' +
'<img src="'+self._getSrc()+'" />'+
'</div>' +
'<div>' +
'<div><a href="javascript:;">'+inputVal+'</a>:</div>' +
'<div>'+textVal+'</div>' +
'<div>'+
'<span>'+self._format(oDate.getMonth() + 1) + "/u6708" + self._format(oDate.getDate()) + "/u65e5 " + self._format(oDate.getHours()) + ":" + self._format(oDate.getMinutes())+'</span>'+
'<a href="javascript:;">Delete</a>'+
'</div>' +
'</div>';
//Insert element
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();
//Clear the value of the input box text field
self._clearVal();
//hover event
self._hover();
},
/*
* Format time, if it is a single digit, add 0
*/
_format: function(str){
return str.toString().replace(/^(/d)$/,"0$1");
},
/*
* Get 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;
}
}
},
/*
* Clear value
*/
_clearVal: function() {
var self = this,
_config = self.config,
_cache = self.cache;
$(_config.inputID) && $(_config.inputID).val('');
$(_config.textareaId) && $(_config.textareaId).val('');
},
/*
* hover event
*/
_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);
// delete event
$('.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);
}
};
// initialization code
$(function(){
new Microblog({});
});
Source code download: http://xiazai.VeVB.COm//201312/yuanma/wb(VeVB.COm).rar