tugenhua0707

JS添加标签效果

2014-04-11 00:50  龙恩0707  阅读(3255)  评论(3编辑  收藏  举报

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!

分类:

技术点:

相关文章:

  • 2021-10-03
  • 2021-12-15
  • 2021-12-10
  • 2021-12-07
  • 2021-12-15
  • 2021-12-31
  • 2021-11-18
  • 2021-11-23
猜你喜欢
  • 2021-11-13
  • 2021-12-05
  • 2021-11-02
  • 2021-12-24
  • 2021-06-09
  • 2021-12-15
  • 2021-11-27
相关资源
相似解决方案