DOM-13【面向对象开发Todolist】

一、JSON字符串配置

; (function () {
    var TodoList = function () {
        
    }

    TodoList.prototype = {
        
    }
    
    // window.todoList = TodoList
    // 不需要写
})
<div class="wrap" data-config='{
    "plusBtn": "j-plus-btn",
    "inputArea": "input-wrap",
    "addBtn": "j-add-item",
    "list": "item-list",
    "itemClass": "item"
}'></div>

注意: JSON数据必须是双引号

二、获取JSON数据

(1)JSON.parse()

可以把JSON字符串转换成对象

; (function (node) {
    var TodoList = function () {
        this.node = node;

        this.config = this.getConfig();
    }

    TodoList.prototype = {
        getConfig: function () {
            return config = JSON.parse(this.node.getAttribute('data-config'))
        }
    }

    new TodoList();
}(document.getElementsByClassName('wrap')[0]));

三、设置默认项

; (function (node) {
    var TodoList = function () {
        this.node = node;

        this.dConfig = {
            "plusBtn": "",
            "inputArea": "",
            "addBtn": "",
            "list": "",
            "itemClass": ""
        }

        this.config = this.getConfig();
		// 如果配置项未写完整就会抛出错误
        for (var key in this.dConfig) {
            if (!this.config.hasOwnProperty(key)) {
                console.log(errorInfo(key));
                return;
            }

        }
    }

    TodoList.prototype = {
        getConfig: function () {
            return config = JSON.parse(this.node.getAttribute('data-config'))
        }
    }

    function errorInfo(key) {
        return new Error(
            '您没有配置参数' + key + '\n\n' +
            '必须配置的参数列表如下:\n' +
            '打开输入框按钮元素类名:plusBtn\n' +
            '输入框区域元素类名:inputArea\n' +
            '增加项目元素类名:addBtn\n' +
            '列表承载元素类名:list\n' +
            '列表承载元素类名:itemClass'
        );
    }

    new TodoList();
}(document.getElementsByClassName('wrap')[0]));

四、获取元素

; (function (node) {
    var TodoList = function () {
        this.node = node;

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

    TodoList.prototype = {
        getConfig: function () {
            return config = 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 = document.getElementById('itemContent')
        }
    }

    function errorInfo(key) {
        return new Error(
            '您没有配置参数' + key + '\n\n' +
            '必须配置的参数列表如下:\n' +
            '打开输入框按钮元素类名:plusBtn\n' +
            '输入框区域元素类名:inputArea\n' +
            '增加项目元素类名:addBtn\n' +
            '列表承载元素类名:list\n' +
            '列表承载元素类名:itemClass'
        );
    }

    new TodoList();
}(document.getElementsByClassName('wrap')[0]));

五、绑定事件

; (function (node) {
    var TodoList = function () {
        var _self = this;

        this.node = node;
        this.inputShow = false;

        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); // 第一层修改this指向
        })
    }

    TodoList.prototype = {
        getConfig: function () {
            return config = 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 = document.getElementById('itemContent')
        },

        showInput: function () {
            var _self = this;
            if (this.inputShow) {
                setInputShow.call(_self, 'close') // 第二层修改this指向
            } else {
                setInputShow.call(_self, 'open')
            }
        }
    }

    function setInputShow(action) {
        if (action === 'open') {
            this.inputArea.style.display = 'block';
            this.inputShow = true;
        } else if (action = 'close') {
            this.inputArea.style.display = 'none';
            this.inputShow = false;
        }
    }

    function errorInfo(key) {
        return new Error(
            '您没有配置参数' + key + '\n\n' +
            '必须配置的参数列表如下:\n' +
            '打开输入框按钮元素类名:plusBtn\n' +
            '输入框区域元素类名:inputArea\n' +
            '增加项目元素类名:addBtn\n' +
            '列表承载元素类名:list\n' +
            '列表承载元素类名:itemClass'
        );
    }

    new TodoList();
}(document.getElementsByClassName('wrap')[0]));

难点:

  1. 事件处理函数里面装了一个方法,这个方法里面又嵌套了一个方法,需要每一层都改变this指向,才能找到TodoList的实例对象
  2. 随时用_self保存函数的this指向,因为指不定往后嵌套的函数会用到

六、总结

(1)call、apply的使用场景

当只有一个参数的时候用call,有多个参数的时候就用apply

(2)书写规范

  1. 构造函数在最上面
  2. prototype在中间
  3. 函数在最下面

(3)顺序

  1. 获取配置项
  2. 默认项设置
  3. 对比默认项与配置项,如果有一项没有配置就抛出错误
  4. 绑定事件(加号按钮,增加项目按钮,编辑/删除按钮)
  5. 原形上写方法(showInput、addBtnClick、 listClick)
  6. 抽象原形方法(setInputShow、setInputStatus、errorInfo、itemTpl)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值