;(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]);