JS copy tencent micro blog effect code

  • 2020-03-30 01:04:04
  • OfStack

In the past two days, I have studied the effect of tencent's microblog. Here I would like to share the effect as follows:

< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201312/20131225172351824.gif" >

 

Before I share this, I will talk about my coding habits. Many people will ask me why I do not write components in the form of jquery since I am using jquery framework. My answer was: everyone writes code in everyone's way. But I want to say is: more personal feel this encoding has a lot of advantages, I am not a very dependent on the Jquery framework, because different companies have different frameworks such as taobao kissy framework in paid treasure to use the alipay framework in baidu baidu framework, in the front of the tencent has tencent js framework if my code is too dependent on the Jquery that if others want to use my code or my own one day to do a tencent project but their side demand we can only use their js framework and have such a function? So if I'm completely dependent on jquery for formal coding do I have to recode now? If the most you can do is to use the jquery selector, then you can just change the selector and the rest of the code can be used directly. This expansion is very good! Personally, I think that as a professional front-end development, not only a little jquery to do things, but also should consider writing high-quality code, may use jquery to write simple code can also do something well, but have you considered that if one day the need to add such and such function you are not to change the code? Can you write new features based on the previous ones? Without changing the code!

What is high-quality code?

I feel that the following must be met:

    1. Scalability.

    2. Maintainability.

    3. Readability and ease of use.

    4. JS performance.

  The most important to meet the above points.

  All right, enough nonsense! To change the topic, at present, the effect of this post I made is simple. Of course, tencent post has some complicated functions, such as adding emoticons, etc., which are not done at present (the workload is relatively large).

  The following JS code I wrote needs to pay attention to two points:

  1. After each post, everyone said that one item would be added to the list. At present, no ajax request has been sent and no records have been recorded in the background, so the page will be cleared after refreshing.

  2. The time is client time. If the client time is wrong, the time will be affected.

In fact, the train of thought is very simple to see the above effect is clear so the train of thought in this side not much to say! Or I will provide compression demo below you can download down to see the effect of ok! Callbacks are provided after each publication as an extension. Of course, when the mouse moves over an item, the delete button will appear and you can delete any item. Direct paste code there is nothing to say!

The HTML code is as follows:


<div id="msgBox">
        <form>
            <h2> to  ,  What are you doing  ,  Want to what </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"> Can enter </span><strong class="maxNum">140</strong><span> A word </span>
                    <input id="sendBtn" type="button" value="" title=" shortcuts  Ctrl+Enter" />
                </p>
            </div>
        </form>
        <div class="list">
            <h3><span> You are talking </span></h3>
            <ul id="list-msg"></ul>
        </div>    
    </div>

The CSS code is 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 5b8b4f53;}
    #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 5fae8f6f96c59ed1;}
    #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;}

JS code is as follows:




 function Microblog(options) {

    this.config = {
        maxNum                        :   140,               //The maximum number of characters
        targetElem                    :   '.f-text',         //The class name of the input field or text field
        maxNumElem                    :   '.maxNum',         //How many more word containers can you enter
        sendBtn                       :   '#sendBtn',        //The radio button
        face                          :   '#face',           //Expression container
        activeCls                     :   'active',          //Click the input field add class
        currentCls                    :   'current',         //The class name added when the mouse clicks on the face avatar
        inputID                       :   '#userName',       //Input box ID
        textareaId                    :   '#conBox',         //Text field ID
        list                          :   '#list-msg',       //You're talking about containers
        callback                      :   null               //Dynamic broadcast after the callback function
    };
    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 on the input text field 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 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);
            });
        });
        //The radio buttonhover The event 
        $(_config.sendBtn).hover(function(){
            !$(this).hasClass('hover') && $(this).addClass('hover');
        },function(){
            $(this).hasClass('hover') && $(this).removeClass('hover');
        })

        //The binding event
        self._bindEnv();
    },
    
     _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;

        //The text field keyup event
        self._keyUp();

        //Click the broadcast button event
        self._clickBtn();
     },
     
     _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(' Please enter your name ');
                return;
            }else if(reg.test(textVal)) {
                alert(" Anything to say !");
                return;
            }
            if(maxNum * 1 < 0) {
                alert(' Character over limit   Please cut the word ');
                return;
            }
            //I was going to make an ajax request but there's no background processing so I'm just rendering the page on the client side
            self._renderHTML(inputVal,textVal);
        });
     },
     
     _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:;"> delete </a>'+
                            '</div>' + 
                        '</div>';
        //Insert elements
        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 field
        self._clearVal();
        //Hover event
        self._hover();
     },
     
    _format: function(str){
        return str.toString().replace(/^(d)$/,"0$1");
    },
    
    _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: 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 events
            $('.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');
        });

    },
    
     _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({});
 });

The source code download: (link: http://xiazai.jb51.net//201312/yuanma/wb (jb51.net). Rar)


Related articles: