;(function(){ var Test=function(opt){ // console.log(opt.a) } Test.prototype={ }; window.Test=Test;})();var test=new Test({a:'1',b:'2'});
JSON字符串转对象 -> JSON.parse()
html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>TodoList</title> <link href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <link rel="stylesheet" href="./css/common.css"> <link rel="stylesheet" href="./css/index.css"></head><body> <div class="wrap"> <div class="list-hd"> <h2>TodoList</h2> <a href="javascript:;" class="j-plus-btn fa fa-plus"></a> </div> <div class="input-wrap"> <div class="input-bd text-input"> <input type="text" id="itemContent"/> </div> <div class="btn-bd add-btn"> <button class="j-add-item">增加项目</button> </div> </div> <div class="list-wrap"> <ul class="item-list"></ul> </div> </div> <script src="./js/untils.js"></script> <script src="./js/index.js"></script></body></html>
common.css
body{ margin: 0;}a{ text-decoration: none;}ul{ padding: 0; margin: 0; list-style: none;}h1,h2,h3,h4,h5,h6,p{ margin: 0; font-weight: bold;}h1{ margin: 0; font-weight: bold;}div{ box-sizing: border-box;}input,button{ outline: none; box-sizing: border-box; border: none;}
index.css
.wrap{ position: relative; width: 500px; height: 500px; margin: 50px auto; box-shadow: 0 0 5px #999; border-radius: 10px; overflow: hidden;}.list-hd{ position: absolute; top: 0; left:0; height: 44px; width: 100%; background-color: #000; color: #fff; text-align: center; line-height: 44px;}.list-hd .fa-plus{ position: absolute; top: 15px; right: 15px; color: #fff;}.input-wrap{ display: none; position: relative; top: 44px; left: 0; width: 100%; height: 40px; border-bottom: 1px solid #ddd;}.input-wrap .text-input{ float: left; width: 410px; height: 100%; padding: 5px 5px 5px 10px;}.input-wrap .input-bd input{ width: 100%; height: 100%; border: 1px solid #ddd;}.input-wrap .btn-bd{ float: left; width: 90px; height: 100%; padding: 5px 5px 5px 10px;}.input-wrap .btn-bd button{ width: 100%; height: 100%; border: 1px solid #ddd; background-color: #fff;}.list-wrap{ height: 456px; margin-top: 44px; overflow: auto;}.list-wrap .item{ height: 50px; position: relative;}.list-wrap .item:nth-child(odd),.list-wrap .item:hover{ background-color: #eee;}.list-wrap .item.active{ background-color: #dff0d8;}.list-wrap .item .item-content{ position: absolute; left: 0; top: 0; width: 400px; height: 100%; line-height: 50px; text-indent: 15px;}.list-wrap .item .btn-group{ height: 100%; margin-left: 400px; line-height: 50px;}.list-wrap .item .btn-group a{ margin-left: 15px;}.list-wrap .item .btn-group .edit-btn{ color: green;}.list-wrap .item .btn-group .remove-btn{ color: red;}
untils.js
// 添加事件function addEvent(el,type,fn) { if(el.addEventListener){ el.addEventListener(type,fn,false); }else if(el.attachEvent){ el.attachEvent('on'+type,function () { fn.call(el); }) }else{ el['on'+type] = fn; }}// 获取滚动坐标function getScrollOffset(){ if(window.pageXOffset){ return{ left:window.pageXOffset, top:window.pageYOffset } }else{ return{ left:document.body.scrollLeft + document.documentElement.scrollLeft, top:document.body.scrollTop + document.documentElement.scrollTop } }}// 封装可视窗口尺寸function getViewportSize(){ if(window.innerWidth){ return{ width:window.innerWidth, height:window.innerHeight } }else{ if(document.compatMode==='BackCompat'){ return{ width:document.body.clientWidth, height:document.body.clientHeight } }else{ return { width:document.documentElement.clientWidth, height:document.documentElement.clientHeight } } }}//获取body大小function getScrollSize(){ if(document.body.scrollWidth){ return { width:document.body.scrollWidth, height:document.body.scrollHeight } }else{ return { width:document.documentElement.scrollWidth, height:document.documentElement.scrollHeight } }}// 获取子元素function elemChildren(node){ var temp = { 'length': 0, 'push': Array.prototype.push, 'splice': Array.prototype.splice }, len = node.childNodes.length; for(var i = 0;i<len;i++){ var childItem = node.childNodes[i]; if(childItem.nodeType === 1){ temp[temp['length']] = childItem; temp['length']++; // temp.push(childItem); push方法 } } return temp;}// 获取祖先元素function elemParent(node,n){ var type = typeof(n); if(type==='undefined'){ return node.parentNode; }else if(n<=0|| type !=='number'){ return undefined; } while(n){ node = node.parentNode; n--; } return node;}
index.js
;(function(node){ var TodoList = function(){ var _self = this; this.node = node; this.inputShow = false; this.isEdit = false; this.curIdx = null; this.dConfig = { "plusBtn":"", "inputArea":"", "addBtn":"", "list":"", "itemClass":"" } this.config = this.getConfig(); this.itemClass = this.config.itemClass; for(var key in this.dConfig){ if(!this.config.hasOwnProperty(key)){ console.log(errorInfo(key)); return; } } this.setConfig(); addEvent(this.plusBtn,'click',function(){ _self.showInput.call(_self); }); addEvent(this.addBtn,'click',function(){ _self.addBtnClick.call(_self); }); addEvent(this.oList,'click',function(e){ var e = e || window.event, tar = e.target || e.srcElement; _self.listClick.call(_self,tar); }); } TodoList.prototype = { getConfig:function(){ console.log(this.node.getAttribute('data-config')) return JSON.parse(this.node.getAttribute('data-config')) }, setConfig:function(){ var config = this.config, node = this.node; this.inputArea = node.getElementsByClassName(config.inputArea)[0]; this.addBtn = this.inputArea.getElementsByClassName(config.addBtn)[0]; this.plusBtn = node.getElementsByClassName(config.plusBtn)[0]; this.oList = node.getElementsByClassName(config.list)[0]; this.content = this.inputArea.getElementsByClassName('content')[0]; console.log(this); console.log(this.plusBtn); }, showInput:function(){ console.log('1'); var _self = this; if(this.inputShow){ setInputShow.call(_self,'close'); }else{ setInputShow.call(_self,'open'); } }, addBtnClick:function(){ var _self = this, content = this.content.value, contentLen = content.length, oItems = this.oList.getElementsByClassName('item'), itemLen = oItems.length, text; if(contentLen<=0){ return; } if(itemLen>0){ for(var i = 0;i<itemLen;i++){ text = elemChildren(oItems[i])[0].innerText; if(text===content){ alert('已存在该项'); return; } } } if(this.isEdit){ elemChildren(oItems[this.curIdx])[0].innerText = content; setInputStatus.call(_self,[oItems,null,'add']); }else{ var oLi = document.createElement('li'); oLi.className = this.itemClass; oLi.innerHTML = itemTpl(content); this.oList.appendChild(oLi); } setInputShow.call(_self,'close'); }, listClick:function(tar){ var _self = this, className = tar.className, oParent = elemParent(tar,2), oItems = this.oList.getElementsByClassName('item'), itemLen = oItems.length, item; if(className === 'edit-btn fa fa-edit'){ // console.log('edit'); for(var i = 0;i<itemLen;i++){ item = oItems[i]; item.className ='item'; } oParent.className += ' active'; setInputShow.call(_self,'open'); setInputStatus.apply(_self,[oItems,oParent,'edit']); }else if(className === 'remove-btn fa fa-times'){ // console.log('remove'); oParent.remove(); } } } function setInputShow(action) { // console.log('2'); var oItems = this.oList.getElementsByClassName('item'); if(action === 'open'){ this.inputArea.style.display = 'block'; this.inputShow = true; }else if(action === 'close'){ this.inputArea.style.display = 'none'; this.inputShow = false; this.content.value = ''; setInputStatus(oItems,null,status); } } function setInputStatus(oItems,target,status){ if(status === 'edit'){ var idx = Array.prototype.indexOf.call(oItems,target), text = elemChildren(target)[0].innerText; this.addBtn.innerText = '编辑第'+(idx+1)+'项'; this.isEdit = true; this.curIdx = idx; this.content.value = text; }else if(status === 'add'){ var itemLen = oItems.length, item; for(var i = 0;i<itemLen;i++){ item = oItems[i]; item.className = 'item'; this.addBtn.innerText ='增加项目'; this.isEdit = false; this.curIdx = null; } } } function errorInfo(key){ return new Error( '您没有配置参数' + key + '\n'+ '必须配置的参数列表如下: \n'+ '打开输入按钮元素类名:plusBtn\n' + '输入框区域元素类名:inputArea\n' + '增加项目按钮元素类名:addBtn\n' + '列表承载元素类名:list\n' + '列表项承载元素类名:itemClass' ); } function itemTpl(text) { return ( '<p class="item-content">' + text + '</p>' + '<div class="btn-group">' + '<a href="javascript:;" class="edit-btn fa fa-edit"></a>' + '<a href="javascript:;" class="remove-btn fa fa-times"></a>' + '</div>' ) } new TodoList();}(document.getElementsByClassName('todo-wrap')[0]));
index2
// ;(function(){// var Test=function(opt){// // console.log(opt.a)// }// Test.prototype={// };// window.Test=Test;// })();// var test=new Test({a:'1',b:'2'});(function (node) { var TodoList = function () { var _self = this; console.log(_self); //直接打印可以看到挂载到对象上的元素是否正确,而不用总是打印 this.node = node; this.inputShow = false; //打开关闭的状态 // console.log(this.getConfig()) this.dConfig = { plusBtn: "", inputArea: "", addBtn: "", list: "", itemClass: "", }; this.config = this.getConfig(); this.itemClass = this.config.itemClass; // this.config = this.getConfig(); for (var key in this.dConfig) { if (!this.config.hasOwnProperty(key)) { return; //结束函数 } } this.setConfig(); //这里this是plusBtn,应该把this变成TodoList addEvent(this.plusBtn, "click", function () { _self.showInput.call(_self); //改变showInput的this指向 得改变2次 // _self.showInput() }), addEvent(this.addBtn, "click", function () { // console.log('addBtn') _self.addBtnClick.call(_self); }); addEvent(this.oList, "click", function (e) { var e = e || window.event, tar = e.target || e.srcElement; _self.listClick.call(_self, tar); }); }; TodoList.prototype = { getConfig: function () { // var config= // console.log(this.node); // var config=JSON.parse(this.node.getAttribute('data-config')); // // var config=this.node.dataset.config; // // console.log(config) // return config; return JSON.parse(this.node.getAttribute("data-config")); }, setConfig: function () { var config = this.config, node = this.node; this.inputArea = node.getElementsByClassName(config.inputArea)[0]; this.addBtn = this.inputArea.getElementsByClassName(config.addBtn)[0]; //效率更高,比从node上获取 this.plusBtn = node.getElementsByClassName(config.plusBtn)[0]; this.oList = node.getElementsByClassName(config.list)[0]; this.content = this.inputArea.getElementsByClassName("content")[0]; // this.plusBtn=node.getElementsByClassName(config.plusBtn)[0]; // this.oList=node.getElementsByClassName(config.list)[0]; // console.log(this); // console.log(this.plusBtn); }, //点击+展示输入框 showInput: function () { // console.log(this) var _self = this; if (this.inputShow) { //封装显示输入框的方法 setInputShow.call(_self, "close"); } else { setInputShow.call(_self, "open"); } }, //输入数据 addBtnClick: function () { var _self = this, content = this.content.value, contentLen = content.length, oItems = this.oList.getElementsByClassName("item"), itemLen = oItems.length, text; if (contentLen <= 0) { return; } if (itemLen > 0) { for (var i = 0; i < itemLen; i++) { text = elemChildren(oItems[i])[0].innerText; if (text === content) { alert("已存在该项"); return; } } } if (this.isEdit) { elemChildren(oItems[this.curIdx])[0].innerText = content; setInputStatus.call(_self, [oItems, null, "add"]); } else { var oLi = document.createElement("li"); oLi.className = this.itemClass; oLi.innerHTML = itemTpl(content); this.oList.appendChild(oLi); } setInputShow.call(_self, "close"); }, listClick: function (tar) { var _self = this, className = tar.className, oParent = elemParent(tar, 2), oItems = this.oList.getElementsByClassName("item"), itemLen = oItems.length, item; if (className === "edit-btn fa fa-edit") { // console.log('edit'); for (var i = 0; i < itemLen; i++) { item = oItems[i]; item.className = "item"; } oParent.className += " active"; setInputShow.call(_self, "open"); setInputStatus.apply(_self, [oItems, oParent, "edit"]); } else if (className === "remove-btn fa fa-times") { // console.log('remove'); oParent.remove(); } }, }; function setInputShow(action) { // console.log(2,this) if (action === "open") { this.inputArea.style.display = "block"; this.inputShow = true; } else if (action === "close") { this.inputArea.style.display = "none"; this.inputShow = false; } } function setInputShow(action) { // console.log('2'); var oItems = this.oList.getElementsByClassName("item"); if (action === "open") { this.inputArea.style.display = "block"; this.inputShow = true; } else if (action === "close") { this.inputArea.style.display = "none"; this.inputShow = false; this.content.value = ""; setInputStatus(oItems, null, status); } } function setInputStatus(oItems, target, status) { if (status === "edit") { var idx = Array.prototype.indexOf.call(oItems, target), text = elemChildren(target)[0].innerText; this.addBtn.innerText = "编辑第" + (idx + 1) + "项"; this.isEdit = true; this.curIdx = idx; this.content.value = text; } else if (status === "add") { var itemLen = oItems.length, item; for (var i = 0; i < itemLen; i++) { item = oItems[i]; item.className = "item"; this.addBtn.innerText = "增加项目"; this.isEdit = false; this.curIdx = null; } } } function errorInfo(key) { return new Error( "您没有配置参数" + key + "\n" + "必须配置的参数列表如下: \n" + "打开输入按钮元素类名:plusBtn\n" + "输入框区域元素类名:inputArea\n" + "增加项目按钮元素类名:addBtn\n" + "列表承载元素类名:list\n" + "列表项承载元素类名:itemClass" ); } function itemTpl(text) { return ( '<p class="item-content">' + text + "</p>" + '<div class="btn-group">' + '<a href="javascript:;" class="edit-btn fa fa-edit"></a>' + '<a href="javascript:;" class="remove-btn fa fa-times"></a>' + "</div>" ); } new TodoList();})(document.getElementsByClassName("todo-wrap")[0]);