JS 仿騰訊發表微博的效果

龍恩0707發表於2013-12-24

   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: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;}
View Code

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({});
 });
View Code

 Demo下載

 今天是平安夜 最後祝福大家平安夜快樂!

相關文章