前端学习笔记:原生JS编程之实现todos(一)

(前言:看看就行,仅做记录,不断学习,以求最好)

2021年12月4日

image

结合之前所学,此次todos功能开发,在css部分引入了bootstrap,在js部分,使用了Ajax+Promise封装,ES6面向对象class类。

借鉴原官网(https://todomvc.com/examples/vue/#/all)的vuejs模板

首先是页面基础样式的实现:

1.大标题todos,放大字体,设置颜色。

2.小标题,文本输入框以及提示字。

3.显示列表,紧跟在输入框之后,由复选框+复选框自定义样式、文本框、span(删除)三个部分组成。并设置选中后的样式,由li标签上的是否有actived控制(bootstrap默认active有样式,所以重新编辑),当选中时表示已完成该事件,字体颜色变淡且贯穿线,自定义复选框显示选中状态。当鼠标移入li标签时(hover),显示删除按钮。

<--这是列表已完成和未完成的样式-->
              <li class="list-group-item " id="list_34">
                    <label class="state">
                        <input type="checkbox" name="state">
                        <div><div class="act"></div></div>
                    </label>
                    <span class="badge">x</span> 
                    <input type="text" id="contentInput" value="2" disabled="">
                </li>
             <li class="list-group-item actived" id="list_35">
                    <label class="state">
                        <input type="checkbox" name="state">
                        <div><div class="act"></div></div>
                    </label>
                    <span class="badge">x</span> 
                    <input type="text" id="contentInput" value="3" disabled="">
                </li>

4.底部操作栏,定义一个div紧跟在列表(ul)其后,内容居中,先设置三个按钮,分别表示显示全部、显示已完成和显示未完成,定义选中后的样式以及鼠标移入的样式。创建一个span标签表示总数量,定位在左侧,创建一个a标签,在有已完成任务时出现。

5.细节样式没有做修改,主要是完成功能。

其次思考页面功能:

准备工作:

static $$(tag) {
        // 快捷获取节点对象函数
        // 返回节点对象
        return document.querySelector(tag);
    }
    static $$All(tag) {
        // 返回节点对象群组
        return document.querySelectorAll(tag)
    }
// Ajax.request 参数
/*
    @param {method,url,data,dataType,success,error} object
    method   请求方式
    url      请求地址
    data     传输参数
    dataType 返回值类型
    以对象的方式传参,调用Ajax方法

    返回promise函数 
*/
// Todos 需要的参数
 /*
        @param {input,radio,ul,allBtn,activeBtn,completedBtn,clearAll,totalText,btnGroup,selectAll} object
        input 输入内容框
        ul 显示列表
        radio 完成按钮
        allBtn 显示全部任务按钮
        activeBtn 显示已完成按钮
        completedBtn 显示未完成按钮
        clearAll 清除所有已完成
        totalText 显示列表总数
        activeClassName 已完成class类名
        selectAll 全选按钮

        属性值:id或者class
*/

1.新增任务

经测试,输入框采用onkeyup事件,当键码为13(即Enter)时触发(按一次只触发一次)。

此时获取输入框里的value,先判断是否为空,再发送Ajax请求。

成功后清空文本框内容,获取列表标记index的值(保存的是state),再使用刷新列表的函数

Todos.$$(this.input).onkeyup = function(e)
// 用keyup只触发一次
// enter键的键码是13 时才触发请求
 if (e.keyCode === 13) 
// 获取输入框内容
// 判断内容为空则不触发
Ajax.request({
                    method: 'get',
                    url: './lib/index.php',
                    data: {
                        fn: 'add',
                        content  // 因为数据库设置,新增状态默认为未完成,也就是0,所以只需要传递内容就行
                    },
                    dataType: ''
})
// 成功后要对文本框内容清空
// 刷新当前显示页面
let state = Todos.$$(_this.ul).getAttribute('index');
Todos.show(state, _this.ul, _this.totalText);
// 判断有无内容显示底部操作界面
_this.examineSelectAll();

2.显示内容

获取列表内容并设置,定义三个参数,第一个是state状态,第二个是列表ul,第三个是存放显示总数文字的span。

首先判断参数state的内容,我定义的分别为“all”,1, 0,(all表示全部,1表示已完成,0表示未完成),state默认为all。

打开页面时获取全部内容,并输出,输出同时给ul设置自定义属性index存放state,给li设置选中或未选中的className


static show(state = 'all', ul, totalText)
// state 显示方式:全部('all')、已完成(1)、未完成(0)
// 判断条件是显示所有还是显示部分
if (state === 'all') 
// 发送Ajax请求
Ajax.request({
                method: 'get', //传输方式
                url: './lib/index.php', //地址,要以HTML文件为准的相对地址
                data: {
                    fn: 'getAll', // 调用对应函数
                }
})
//  成功后
// 设置总共显示数目
Todos.$$(totalText).innerHTML = `${data[0]} item left`;
// 调用页面创建方法
// 输出内容
odos.$$(ul).innerHTML = Todos.createAllListHtml(data[1]);
// 给显示列表添加id标记此时需要显示什么
Todos.$$(ul).setAttribute('index', `${state}`)
// 这里要注意一定要给当前页面一个标记,这样在添加数据,修改状态和删除等操作时可以直接针对显示的内容进行刷新
  Ajax.request({
                method: 'get',
                url: './lib/index.php',
                data: {
                    fn: 'getState',
                    state
                }
})
//注意,点击All、Active、Completed时,all是全查询,而后两个是条件查询,所以接受到的数值不一样
//成功后操作差不多,注意传参时只有一个data,当然也可以传一个数量
// php
// 获取数据的方法
function getAll(){
    $sql1 = 'select count(id) as listAll from jstodos';
    $listAll = select($sql1)[0]['listAll'];
    $sql = "select * from jstodos order by id asc";
    $res = select($sql);
    print_r(json_encode([$listAll,$res]));
}
// 获取单个数据的方法
function getState(){
    $state = $_GET['state'];
    $sql = 'select * from jstodos where state='.$state;
    $res = select($sql);
    print_r(json_encode($res));
}

这里推荐使用innerHTML,有种无缝的感觉,避免因为每次先清空innerHTML再插入节点对象时造成ul标签闪烁影响观感

3.点击all、avtive、completed切换显示内容

先实现三个显示界面,获取三个按钮分别绑定。

这里要利用排他思想,给当前选中界面的按钮设置被选中样式的class,所以不能单独获取该按钮而是获取按钮组。

这个比较简单,再调用一次 Todos.show()就行了

4.写一个事件委托,在LI标签上

给列表中的复选框绑定事件,使用事件委托机制,因为列表中三个内容分别有功能。

Todos.$$(this.ul).onclick
let target = e.target;
// 点击复选框修改当前状态
if (target.name == 'state') 
// 点击删除按钮直接删除
 if (target.className == 'badge')

5.复选框修改状态

截止到今天,首先完成了复选框事件,点击复选框,获取到父级的父级的class,也就是到LI标签为止。

用indexOf判断当前内容是已完成还是未完成,如果已完成则有一个actived的css类名,并设置相反的状态。

然后发送Ajax请求,并在成功后用classList删除或新增actived修改样式。

// 首先肯定要获取Li标签的class 用parentNode方法
// 其次获取该行id 、我在前面定义时,id的组成是 list_(id),所以这里要用split('_')先分割成数组,再取第二项
// 在之前我直接用slice(-1)截取最后一位,不行,如果是两位数三位数id,那难不成还要手动去修改吗?
let state;
        if (classStr.indexOf(`${this.activeClassName}`) === -1) {
            state = 1;
        } else {
            state = 0;
        }
// 我给已完成的li标签添加了一个叫做“actived”的类名,用index去匹配,没有返回-1,那该行就是未完成
Ajax.request({
            method: 'get',
            url: './lib/index.php',
            data: {
                fn: 'updateState',
                state,
                infoId //根据id修改state
            },
            dataType: ''
        })
//成功后,要调用一个函数判断有没有已完成,因为涉及到一个按钮功能。
//其次根据上面的state来添加或删除class
//这里使用classList.add() 和 classList.remove() 不会对其他已存在的clss造成影响
if (state == 1) {
                li.classList.add(`${this.activeClassName}`);
            } else {
                li.classList.remove(`${this.activeClassName}`);
            }
//接着刷新当前显示界面

当日总结:

首先显示总列数是不变的,所以只需要在进入页面初始化时设置一次。

其次要分别获取每个状态下的内容,并且要在其他操作时看到改变,所以要给节点对象设置标记

复选框只需要判断li标签的class里面是否有actived来设置状态

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容