温习classList api
有道题是一个removeClass的功能,代码里是正则分隔了传入的name,根据name的个数,循环移除掉,让寻找bug。。看了了这几行代码,首先想到的是我会如何去优化。 如果看代码一两分钟就能找到公司js框架中的bug,那也太。。。
改为如何优化算是不错的面试题,
first,去掉正则表达式,使用split字符串内置方法分隔,
second,支持html5的浏览器使用classList api,
第三,类似jq,hasClass、remove、togglle都是用了字符串内置方法,indexOf、replace、字符串相加。
周末试着coding。代码如下
1 var className = (function() { 2 //设置的方法list 3 var fnName = 'add,remove,contains,toggle'.split(','); 4 var _trim = function(str) { 5 return str.trim ? str.trim() : str.replace(/(^\s*)|(\s*$)/g, ""); 6 }; 7 8 //不支持H5的classList,使用自定义方法实现 9 var cClassList = { 10 add: function(el, name) { 11 if (!this.contains(el, name)) { 12 el.className = _trim(el.className + ' ' + name + ' '); 13 } 14 }, 15 remove: function(el, name) { 16 if (this.contains(el, name)) { 17 var _class = (' ' + el.className + ' ').replace(' ' + name + ' ', ' '); 18 el.className = _class ? _trim(_class) : ''; 19 } 20 }, 21 contains: function(el, name) { 22 if (el && el.nodeType == 1 && (" " + el.className + " ").indexOf(" " + name + " ") >= 0) { 23 return true; 24 } 25 return false; 26 }, 27 toggle: function(el, name) { 28 if (this.contains(el, name)) { 29 this.remove(el, name); 30 } else { 31 this.add(el, name); 32 } 33 } 34 }; 35 36 var _classList = {}; 37 /* 38 * 如果name为多个(空格分隔),那么循环设置,反之调用classList设置 39 * @param {HtmlNode} type 40 * @param {String} name 41 * @returns {undefined} 42 */ 43 var _eachDo = function(type, name) { 44 if (typeof name === 'string' && name.length) { 45 name = _trim(name).split(' '); 46 var len = name.length; 47 if (len === 1) { 48 if (this.classList) {//使用h5的classList,非hasClass 则return undefined 49 return this.classList[type](name[0]); 50 } else { 51 return cClassList[type](this, name);//使用自定义设置 52 } 53 } else { 54 var Return = true; 55 for (var j = 0; j < len; j++) { 56 if (_eachDo.call(this, type, name[j]) == false) { 57 Return = false; 58 } 59 ; 60 } 61 return Return; 62 } 63 } 64 }; 65 //添加上 add、toggle、contains、remove方法 66 for (var i = 0; i < fnName.length; i++) { 67 (function(key) { 68 _classList[key] = function(el, name) { 69 //如果传入的className是个function,那么得到计算结果 70 if (typeof name === 'function') { 71 name = name.call(this); 72 } 73 return _eachDo.call(el, key, name); 74 }; 75 })(fnName[i]); 76 } 77 //hasClass 78 _classList['has'] = _classList.contains; 79 return _classList; 80 })(); 81 82 var div1 = document.getElementById('div1'); 83 className.add(div1, 'asd fv'); 84 alert(div1.className) 85 className.remove(div1, 'asd'); 86 alert(div1.className) 87 className.toggle(div1, 'asd sd'); 88 alert(div1.className) 89 className.add(div1, 'asd sd fv'); 90 alert(div1.className) 91 alert(className.has(div1, 'asd fv'))