JSON字符串转对象 -> JSON.parse()

html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>TodoList</title>
  8. <link href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  9. <link rel="stylesheet" href="./css/common.css">
  10. <link rel="stylesheet" href="./css/index.css">
  11. </head>
  12. <body>
  13. <div class="wrap">
  14. <div class="list-hd">
  15. <h2>TodoList</h2>
  16. <a href="javascript:;" class="j-plus-btn fa fa-plus"></a>
  17. </div>
  18. <div class="input-wrap">
  19. <div class="input-bd text-input">
  20. <input type="text" id="itemContent"/>
  21. </div>
  22. <div class="btn-bd add-btn">
  23. <button class="j-add-item">增加项目</button>
  24. </div>
  25. </div>
  26. <div class="list-wrap">
  27. <ul class="item-list"></ul>
  28. </div>
  29. </div>
  30. <script src="./js/untils.js"></script>
  31. <script src="./js/index.js"></script>
  32. </body>
  33. </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]));