html + jquery 原生开发ToDo网页

html + jquery 原生开发ToDo网页

相信做前端的大家都见过这个网页吧
TodoMVC
Vue的入门网页

今天我用原生html实现一下
demo
在这里插入图片描述

首先看一下html部分的代码:

<html>

<head>
    <meta charset="utf-8">
    <title>幸运记事</title>
    <link rel="stylesheet" href="./css/app.css">

</head>

<body>
    <section id="todoapp" class="todoapp">
        <header class="header">
            <h1 id="title" onmouseover="todo.method().hover()" >记</br>事</h1>

        </header>
        <section class="main">
            <section class="input"> 
                    <input type="checkbox" class="all-checker" onclick="allChecked(this)"> 
                    <img class= "input-img" src="./img/arrow_down.svg"> 
                    <input id="add-todo" class="new-todo" placeholder="诗和远方..." autofocus="autofocus" autocomplete="off" 
                                            onkeyup="todo.method().addItem(event)">
                    
            </input>
            </section>
            
            <ul id="list" class="todo-items">
            </ul>
            <section id="listFoot" class="foot">
                <span class="todo-count">
                        待办&nbsp;
                    <span id = "count">0</span>
                    
                </span>
                <ul class="filters">
                    <li id = "do-border" class="filter" onclick="todo.method().doFilter(this)">
                        <span >全部</span>
                    </li>
                    <li class="filter" onclick="todo.method().doFilter(this)">
                        <span >未完成</span>
                    </li>
                    <li class="filter"  onclick="todo.method().doFilter(this)">
                        <span >已完成</span>
                    </li>
                </ul>
                <span id = "removeCom" class="rmv-complete" onclick="rmvCompleted()">
                        移除已完成
                </span>
            </section>
        </section>
        <footer class="footer">

        </footer>
    </section>
</body>
<script src="./js/app.js"></script>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script>

</script>

</html>

比较简单哈!

再看下简单的css吧

ul{
    padding: 0;
    margin: 0;
}
body{
    display: flex;
    flex-direction: column;
    align-items: center;
}
.todoapp{
    display: flex;
    flex-direction: column;
    width: 60%;
}

.header{
   
    font-size: 3rem;
    color: red;
    opacity: 0.6;
    /* display: flex; */
    text-align: center;
    width: 100%;
}

.new-todo{   
   
    width: 100%;
    font-size: 1.5rem;
    font-style: italic;
    opacity: 0.8;
    padding: 1.5rem 1rem 1.5rem 4rem;
    border: none;
    box-shadow: 2px 2px 5px #333333;
}

.main{
    margin: 0 auto;
    width: 100%;
    display: flex;
    flex-direction: column;
    border:1px solid #F2F2F2;
    box-shadow: 2px 2px 7px #3333339a;
}

.todo-items{
    margin: 0;
    
    list-style: none;
    display: none;
    padding: 0;
}
#count{
    color:red;
}
.todo-item{
    display: flex;
    flex-direction: row;
    justify-items: center;
    margin: 0;
    font-size: 1.4rem;
    opacity: 0.8;
    padding: 1.3rem 1rem 1.3rem 0.8rem;
    font-style: normal;
    border-bottom: 1px solid #dddcdcb2;
    font-weight: 100;
}

.rmv-complete{
    color: #f84747ee;
    cursor: pointer;
    display: none;
    margin-left: 10%;
    margin-right: 4%;
    
}

.li_img{
    margin-left: auto;
    cursor: pointer;
}

.todo-item:hover{
    background-color: #F2F2F2;
    font-size: 1.7rem;
}

.foot{
    display: none;
    flex-direction: row;
    width: 100%;
    margin: 0;
    font-size: 1.2rem;
    color: #747171ee;
    opacity: 0.8;
    padding: 1rem 1rem 1rem 0;
    border-bottom: 1px solid #dddcdcb2;
}
.todo-count{
    margin-left: 7%;
    display: flex;
}
.filters{
    display: flex;
    list-style: none;
    margin-left: auto;
}

.filter{
    display: flex;
    padding: 0;
    display: block;
    padding:0 0.5rem;
    /* border: 1px solid #ff780ab2; */
    border-radius: 5px;
    text-align: center;
    margin-left: 10px;
    cursor: pointer;
    
}
.complete{
    margin-left: auto;
    margin-right: 5%;
}
.footer{
    width: 100%;
}

.input{
    display: flex;
    flex-direction: row;
}

.input-img{
    
    position: absolute;
    margin-top: 20 ;
    margin-left: 15;
}
.input-img:hover{
    opacity: 0.8;
}
.check{
    position: absolute;
    z-index: 2;
    width: 30;
    height:30;
    margin-left: 10;
    
}

.li-text{
    padding-left: 4rem;
}

.all-checker{
    z-index: 2;
    cursor: pointer;
    opacity: 0;
    width: 50;
    height:50;
    position: absolute;
    margin-left: 10;
    margin-top: 10;
}

最后再看看简单的js

哈哈,开个玩笑
先上代码吧,后面我们来分析一下

(function () {
    const todo = {
        mounted: function () {

            this.method().startBorder();
        },
        data: {
            context: document.getElementById("title"),

        },
        method: function () {
            return {

                startBorder: () => {
                    document.getElementById("do-border").style.border = "1px solid #ff780ab2";

                },
                /**
                 * 鼠标滑过标题
                 */
                hover: () => {
                    switch (this.data.context.innerText) {
                        case "记\n事":
                            this.data.context.innerText = "幸\n运";
                            break;
                        case "幸\n运":
                            this.data.context.innerText = "记\n事";
                            break;
                    }
                },

                /**
                 * 回车添加
                 */
                addItem: (event) => {

                    if (event.keyCode == "13") {
                        var text = document.getElementById("add-todo").value;
                        if (text.replace(/\s/g, "").length == 0) {    //空字符检测
                            return;
                        }
                        var list = document.getElementById("list");
                        var foot = document.getElementById("listFoot");
                        var count = list.getElementsByTagName("li").length;

                        document.getElementById("count").innerHTML = parseInt(count) + 1;
                        foot.style.display = "flex";
                        list.style.display = "block";
                        addLi(text);
                        document.getElementById("add-todo").value = "";
                    }
                },
                /**
                 * 筛选器
                 */
                doFilter: (obj) => {
                    var children = obj.parentNode.children;
                    var index = $(obj).index();
                    for (var i = 0; i != 3; i++) {
                        if (index == i) {

                            children[i].style.border = "1px solid #ff780ab2";
                        } else {
                            children[i].style.border = "";
                        }
                    }
                    this.method().filterResult(obj);
                },

                /**
                 * 筛选显示结果
                 */
                filterResult: (obj) => {
                    switch ($(obj).index()) {
                        case 0:
                            $("#list li").each(function () {
                                $(this).show();
                            })
                            break;
                        case 1:
                            $("#list li").each(function () {
                                $(this).show();
                                if ($(this)[0].children[0].checked)
                                    $(this).hide();
                            })
                            break;
                        case 2:
                            $("#list li").each(function () {
                                $(this).show();
                                if (!$(this)[0].children[0].checked)
                                    $(this).hide();
                            })
                            break;
                    }
                }


            }
        }
    }
    window.todo = todo
    window.todo.mounted()
})()



/**
 * 创建li元素
 * @param {string} text 
 */
function addLi(text) {
    var ele_li = document.createElement("li");
    ele_li.setAttribute("class", "todo-item");
    addEle(ele_li, text);
    list.appendChild(ele_li);

}

/**
 * 全选操作
 * @param {checkbox} obj 
 */
function allChecked(obj) {
    var li_list = document.getElementById("list").getElementsByTagName("li");
    if (li_list.length == 0)
        return;
    if (obj.checked) {
        for (var i = 0; i != li_list.length; i++) {
            deleteLine(li_list[i].getElementsByTagName("span")[0], 1);
            li_list[i].getElementsByTagName("input")[0].checked = true;
            document.getElementById("count").innerHTML = 0;
        }
    } else {
        for (var i = 0; i != li_list.length; i++) {
            deleteLine(li_list[i].getElementsByTagName("span")[0], -1);
            li_list[i].getElementsByTagName("input")[0].checked = false;
            document.getElementById("count").innerHTML = i + 1;
        }
    }
    rmvComp();
}
/**
 * 增加或删除   删除线
 * @param {*} text 
 */
function deleteLine(text, num) {
    if (num == 1) {
        text.style.textDecoration = "line-through";
    } else {
        text.style.textDecoration = "none";
    }

}


/**
 * 为li添加子元素
 * @param {*} li 
 * @param {*} text 
 */

function addEle(li, text) {
    //checkbox
    var ele_check = document.createElement("input");
    ele_check.setAttribute("class", "check");
    ele_check.setAttribute("type", "checkbox");
    ele_check.setAttribute("onclick", "isChecked(this)");
    //事项内容
    var ele_span = document.createElement("span");
    ele_span.setAttribute("class", "li-text");
    ele_span.setAttribute("ondblclick" ,"updateItem()")
    ele_span.setAttribute("id", "li-span")
    ele_span.innerHTML = text;
    //删除图标
    var ele_img = document.createElement("img");
    ele_img.setAttribute("class", "li_img");
    ele_img.setAttribute("src", "./img/delete.svg");
    ele_img.setAttribute("onclick", "deleteItem(this)");
    //加入子元素
    li.appendChild(ele_check);
    li.appendChild(ele_span);
    li.appendChild(ele_img);
}

function updateItem(){

}

//为删除按钮添加删除节点功能
function deleteItem(obj) {
    var li = obj.parentNode;
    var ul = li.parentNode;
    //alert($(li).index());
    if (!li.getElementsByTagName("input")[0].checked) {
        var count = document.getElementById("count").innerHTML;
        document.getElementById("count").innerHTML = parseInt(count) - 1;
    }

    ul.removeChild(li);
    rmvComp();
}


function isChecked(obj) {

    var count = document.getElementById("count").innerHTML;
    if (obj.checked) {
        deleteLine(obj.parentNode.getElementsByTagName("span")[0], 1);
        document.getElementById("count").innerHTML = parseInt(count) - 1;

    } else {
        deleteLine(obj.parentNode.getElementsByTagName("span")[0], -1);
        document.getElementById("count").innerHTML = parseInt(count) + 1;

    }
    rmvComp();
}

function rmvComp() {
    var needRmv = false;
    $("#list li").each(function () {
        if ($(this)[0].children[0].checked) {
            needRmv = true;
            return;
        }
    })
    if (needRmv) {
        $("#removeCom").show();
    } else {
        $("#removeCom").hide();
    }

}


function rmvCompleted() {
    $("#list li").each(function () {
        if ($(this)[0].children[0].checked) {
            $(this).remove();
        }
    })
}

大家可以看到,一开始就是一个function,然后里面是一些变量,方法之类的
看起来是不是很像vue啊
其实大概就是这样,利用js的闭包特性,共享包内属性,还能都储存在内存中

(function(){
...})()

这是立即执行函数的一种写法。
然后定义常量,里面再次定义变量,返回方法的方法

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值