使用jQuery开发Todos实录

来源:互联网 发布:js原型链继承面试题 编辑:程序博客网 时间:2024/05/20 21:46

本例是模仿vue.js中todoMVC的功能,使用jQuery进行开发,第一版的jQuery会显得有些混乱,后续将进行优化。 
这里写图片描述 
todoMVC具有添加、修改、删除、更改状态、分类等操作todos的功能。我的开发过程分为了以下几个步骤。

  1. 将整个应用进行功能拆分
  2. 分别实现每个子功能
  3. 合并功能
  4. 优化

具体实现

  • 添加todos
 var newtodoVul= $('#newtodo').val();  $("#newtodo").val('');  var tpl_html=$('.todo-li-template').clone(true);  tpl_html.find('.todo-name').text(newtodoVul);  tpl_html.removeClass('hidden');  tpl_html.removeClass('todo-li-template');  tpl_html.attr('data-id', String(id));  $('#list').prepend(tpl_html);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

生成一个tpl_html的模版,然后prepend()反向插入。

  • 删除todos
function todosDel(){  $(".destroy").on('click',function(event){    $(this).addClass("btn-click");    setTimeout(function() {      $(event.target).parents('.todo').remove();      delToDos(Number($(event.target).parents('.todo').data('id')));    }, 200);  });}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里删除按钮有一个旋转的动画,执行时间是0.2s,所以需要setTimeout()函数来延迟执行删除函数,同时在数组中也将这条todos进行删除。

function delToDos(id){  arr.forEach(function (item,index){    if(item.id == id){      arr.splice(index,1);    }  })  };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 更改todos状态 
    todos事件分为两种状态,一种是正在进行的’todo’,另一种为完成过后的’done’。创建一个数组保存todos的id、状态、和内容。input框回车事件会调用这个todosArrys(),然后传入id和text的值,存入数组当中。 
    i = i + 1; 
    text = $(event.target).val(); 
    todosArray(i, text); 
function todosArray(id,text){  arr.push({    id: id,    status: 'todo',    text:text  });}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

每次状态更改,会获取当前checkbox点击事件的对象,通过对数组进行遍历,获取相同id的状态进行更改。

function todosToDonw(id) {  arr.forEach(function (item) {    if(item.id==id){      item.status='done';    }  });  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • todos分状态查看

    1.ALL 查看全部列表 
    2.Active 查看正在进行的列表 
    3.Completed 查看已完成的列表

Active和Completed的实现方式是使用jQuery方法each()去遍历DOM,判断是否包含line这个Class再对DOM进行显示或隐藏。

function ActiveToDos() {   $("#list li").each(function(index,element){     if($(element).find(".todo-name").hasClass("line")){       $(element).hide();     }else{       $(element).show();     }   })}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 每个todos修改功能 
    想要实现修改功能就需要在每个label标签的上层覆盖一个input标签,当双击label标签时,显示input标签,将label标签的text值传入input的val(),然后回车事件绑定alterTod0()函数,为input再添加hidden样式,同时将修改过后的val()再写回label的text。
function editToDos() {  $("#list").dblclick(function (event) {    if ($(event.target).hasClass('todo-name')) {      var $newtodos =         $(event.target).parents('.todo').find(".newtodos");      var resettodos = $(event.target).text();      $newtodos.removeClass("hidden");      $newtodos.val(resettodos);      $(event.target).siblings(".todo-icon").addClass("hidden");    }  })}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
function alterTodo(event){    if (event.keyCode == "13") {      $(event.target).siblings(".view").find(".todo-icon").removeClass("hidden");      $(event.target).parents(".todo").find(".todo-name").text($(event.target).val());      $(event.target).addClass("hidden");    }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 细节优化

    1.为toggle-all(全部选定的那个checkbox按钮),添加旋转逻辑

当所有的子checkbox按钮全选or全不选的时候,toggle-all会自动调整自己的体位..咳咳

function toggleAll(){  $("#list li").each(function(){    if($("#list li").find(".toggle:checked").length==$("#list li").length){      $(".toggle-all").prop("checked",true);    }    if($("#list li").find(".toggle:checked").length===0){      $(".toggle-all").prop("checked",false);    }  })}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.无需二次点击Active或Completed按钮,遍历DOM,含有box样式的分类就调用该分类函数。

function isHasAct(){  $(".footbtn li").each(function(){    if($(".footbtn").find(".box").find("a").attr("id")=="act"){      ActiveToDos();    }  })}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. todos记数
function updateTodosCouts(){  var num=0;  arr.forEach(function(item){    if(item.status=='todo'){      num++;    }  })  $("#foot-num").text(num);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

有哪些坑

  • 点击了每个toggle子checkbox后,无法用toggle-all进行checked状态修改,后来发现jQuery1.6版本后无法使用attr进行checked状态修改,改用prop()。
  • 使用prepend()向DOM中插入内容的时候,会将模版显示在上面,所以将模版放在ul标签以外。
  • 执行删除DOM节点之前,如果还有删除动画,那么用setTimeout(function(){../你的执行函数},time)延时执行函数。

经验值

  • 学会Chrome设置断点进行调试,进行DOM操作的时候,需要明白函数event.target指代什么、this指代什么,因为JS每个函数又同时是对象,所以是可以像其它对象一样被传递,return可以返回一个函数的值。这样可以定义一个变量去接收函数的值。
  • 使用包括JS数组迭代forEach(),jQueryDOM遍历Each(),修改属性attr(),prop(),插入DOM等。

  • 下一步将对jQuery进行重构,结合Handlebars.js 模板引擎来开发第二版。

Github项目链接