Javascript如何添加标签效果2014-09-19 cnblogs 涂根华在豆瓣网上添加自己的标签是一种常见的效果,今天也就做了一个简单的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;}};由于时间问题 先晚安 如果有问题的话,请留言!ok!