JS添加标签效果

JS添加标签效果

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

 JSFiddle的效果如下:

 点击我看看效果!

依赖于HTML结构如下:

<div class="j-container">
    <div class="mb-meta">
        <div class="btn mb-add-button">Adddiv>
    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('');
                });
            }
            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('');
                        !$(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 = '
  • '+ '
    '+ ''+curValue+''+ ''+ '
    '+ '
  • '; 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添加标签效果)