JS添加标签效果

JS添加标签效果

  在豆瓣网上添加自己的标签是一种常见的效果,今天也就做了一个简单的demo。由于时间的问题 我不多原理,大家可以试着操作几遍就能明白其中的原理了。

 JSFiddle的效果如下:

 点击我看看效果!

依赖于HTML结构如下:

<div class="j-container">

    <div class="mb-meta">

        <div class="btn mb-add-button">Add</div>

    </div>

    <ul class="mb-list"></ul>

</div>

所有的JS代码如下:

/**

 * JS文本标签

 * @time 2014-4-10

 * @author tugenhua

 */

    function AddTag(options) {



        this.config = {

            containerCls  :  '.j-container',           // 最外层容器

            buttonCls     :  '.mb-add-button',         // add按钮

            btnContainer  :  '.mb-meta',               // add按钮最近的父容器

            listItemCls   :  '.mb-list',               // 添加标签到当前的容器里

            isInput       :  true                      // add按钮前是否需要input输入框

        };



        this.cache = {

            arrs :  []

        }



        this.init(options);

    }

    AddTag.prototype = {



        constructor: AddTag,

        init: function(options){

            this.config = $.extend(this.config,options || {});

            var self = this,

                _config = self.config,

                _cache = self.cache;



            if(_config.isInput) {

                $(_config.btnContainer).each(function(){

                    $(this).prepend('<input placeholder="Enter tags here" class="mb-input">');

                });

            }

            self._bindEnv();

        },

        /*

         * 绑定事件

         * @method _bindEnv

         * keycode 13->enter键

         */

        _bindEnv: function(){

            var self = this,

                _config = self.config,

                _cache = self.cache;

            // input enter键 事件

            if($('.mb-input').length > 0) {

                $('.mb-input').each(function(){

                    $(this).unbind('keyup').bind('keyup',function(e){

                        var keyCode = e.keyCode,

                            curValue = $.trim($(this).val()),

                            tparent = $(this).closest(_config.containerCls);

                        if(keyCode == 13) {

                            self._renderHTML(curValue,tparent);

                        }

                    });

                });

            }



            // 点击add按钮 触发事件

            $(_config.buttonCls).each(function(){

                $(this).unbind('click').bind('click',function(){

                    var container = $(this).closest(_config.containerCls);

                    if($('.mb-input',container).length > 0) {

                        var inputVal = $.trim($('.mb-input',container).val());

                        self._renderHTML(inputVal,container);

                    }else {

                        var $thisParent = $(this).closest(_config.btnContainer),

                            $container = $(this).closest(_config.containerCls);

                        // 否则的话  直接把按钮变成input输入框

                        $($thisParent).prepend('<input placeholder="Enter tags here" class="mb-input">');

                        !$(this).hasClass('hidden') && $(this).addClass('hidden');

                        $('.mb-input',$container).focus();

                        // 失去焦点时候 触发事件

                        self._blurEnv($('.mb-input'),$(this),$container);

                    }

                });

            });

        },

        /*

         * 添加html标签

         * @method _renderHTML

         * @param {curValue,tparent} 当前值 当前最外层容器

         */

        _renderHTML: function(curValue,tparent){

            var self = this,

                _config = self.config,

                _cache = self.cache;



            var html = '<li class="mb-tag" data-tag="'+curValue+'">'+

                            '<div class="mb-tag-content">'+

                                '<span class="mb-tag-text">'+curValue+'</span>'+

                                '<a class="mb-tag-remove"></a>'+

                            '</div>'+

                        '</li>';

            if($('.mb-tag',_config.listItemCls).length > 0) {

                $('.mb-tag',_config.listItemCls).each(function(){

                    var dataTag = $(this).attr('data-tag');

                    _cache.arrs.push(dataTag);

                    _cache.arrs = self.unique(_cache.arrs);

                });

            }

            var curIndex = self._indexOf(curValue,_cache.arrs);

            if(curIndex < 0) {

                $(tparent).find(_config.listItemCls).append(html);

            }else {

                alert('重复项,请重新输入');

                return true;

            }

            

            //  关闭事件

            self._closedEnv();

        },

        /*

         * 失去焦点时候触发

         * @method _blurEnv

         * @param {target,$btn,$container}当前输入框目标元素 按钮 当前最外层容器

         */

        _blurEnv: function(target,$btn,$container){

            var self = this,

                _config = self.config,

                _cache = self.cache;

            

            $(target).unbind('blur').bind('blur',function(e){

                var tagVal = $.trim($(this).val());

                blur($(this),tagVal);

            });

            

            function blur($this,tagVal){

                if(tagVal == '') {

                    return;

                }else {

                    self._renderHTML(tagVal,$container);

                    var curIndex = self._indexOf(tagVal,_cache.arrs);

                    if(curIndex < 0) {

                        $(target).remove();

                        self._removeItem(tagVal,_cache.arrs);

                        _cache.arrs = self.unique(_cache.arrs);



                        $($btn).removeClass('hidden');

                    }

                    

                }

            }

            // ENTER键

            if($(target).length > 0) {

                $(target).each(function(){

                    $(this).unbind('keyup').bind('keyup',function(e){

                        e.preventDefault();

                        var keyCode = e.keyCode,

                            curValue = $.trim($(this).val()),

                            tparent = $(this).closest(_config.containerCls);

                        if(keyCode == 13) {

                            // 先清空值 调用 _renderHTML方法 目地使按enter键下时候 不触发blur事件

                            $(this).val('');

                            

                            var istrue = self._renderHTML(curValue,tparent);

                            if(istrue) {

                                $(this).val(curValue);

                                return;

                            }

                            $(this).remove();

                            $($btn).removeClass('hidden');

                        }

                    });

                });

            }

            

        },

        /*

         * 关闭事件

         */

        _closedEnv: function(){

            var self = this,

                _config = self.config,

                _cache = self.cache;



            // 关闭X按钮事件

            if($('.mb-tag-remove',_config.listItemCls).length > 0) {

                $('.mb-tag-remove',_config.listItemCls).each(function(){

                    $(this).unbind('click').bind('click',function(){

                        var liparent = $(this).closest('li'),

                            tagVal = $.trim($(liparent).attr('data-tag'));

                        self._removeItem(tagVal,_cache.arrs);

                        _cache.arrs = self.unique(_cache.arrs);



                        $(liparent).remove();

                    });

                });

            }

        },

        /*

         * 从数组里面删除一项

         * @method _removeItem

         * @param {item,arr} 当前的项 数组

         * @return 返回新数组

         */

        _removeItem: function(item,arr){

            var self = this,

                index = self._indexOf(item,arr);

            if(index > -1) {

                arr.splice(index, 1);

            }

        },

        /*

         * 索引 jquery1.8 indexof 会重新排序 所以没有用jquery indexof

         */

        _indexOf: function(item,arr) {

            if(Array.prototype.indexOf) {

                return arr.indexOf(item);

            }else {

                for(var i = 0, ilen = arr.length; i < ilen; i+=1) {

                    if(arr[i] == item) {

                        return i;

                    }else {

                        return -1;

                    }

                }

            }

        },

        /*

         * 去掉数组重复项

         * @method unique

         * @param array

         * @return newArray

         */

        unique: function(arr){

            arr = arr || [];

            var obj = {},

                ret = [];

            for(var i = 0, ilen = arr.length; i < ilen; i+=1) {

                var curItem = arr[i],

                    curItemType = typeof(curItem) + curItem;

                if(obj[curItemType] !== 1) {

                    ret.push(curItem);

                    obj[curItemType] = 1;

                }

            }

            return ret;

        }

};

 

DEMO下载

由于时间问题 先晚安 如果有问题的话,请留言!ok!

你可能感兴趣的:(js)