首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用纯javascript组件执行列表任务

使用纯javascript组件执行列表任务
EN

Stack Overflow用户
提问于 2018-03-06 08:55:27
回答 2查看 105关注 0票数 0

有一个要做的列表任务。有三个组成部分。类TodoAppComponent、类TodoFormComponent和类TodoListComponent。请检查一下我的doneTask()在TodoListComponent。当我添加一个任务时,当复选框状态更改为“选中”时,我需要跨越行,它似乎不能正常工作,但是控制台没有显示任何错误。

代码语言:javascript
复制
class TodoAppComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.todoFormMountPoint = this.mountPoint.querySelector(
      ".todo-app__form-point"
    );
    this.todoListMountPoint = this.mountPoint.querySelector(
      ".todo-app__list-point"
    );
  }

  mountChildren() {
    this.todoFormComponent = new TodoFormComponent(this.todoFormMountPoint, {
      onTodoAdd: this.handleTodoAdd.bind(this)
    });
    this.todoFormComponent.mount();
    this.todoListComponent = new TodoListComponent(this.todoListMountPoint);
    this.todoListComponent.mount();
  }

  handleTodoAdd(task) {
    this.todoListComponent.addTask(task);
    const numItems = this.todoListComponent.getNumTasks();
    this.todoFormComponent.setCounter(numItems + 1);
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.mountChildren();
  }

  render() {
    return `
      <div class="todo-app">
        <h2>Todo:</h2>
        <div class="todo-app__form-point"></div>
        <div class="todo-app__list-point"></div>
      </div>
    `;
  }
}

class TodoFormComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.field = this.mountPoint.querySelector(".todo-form__field");
    this.btn = this.mountPoint.querySelector(".todo-form__btn");
    this.counter = this.mountPoint.querySelector(".todo-form__counter");
  }

  addEventListeners() {
    this.btn.addEventListener("click", this.handeBtnClick.bind(this));
  }

  handeBtnClick() {
    this.props.onTodoAdd(this.field.value);
    this.field.value = "";
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.addEventListeners();
  }

  setCounter(val) {
    this.counter.innerHTML = val;
  }

  render() {
    return `
      <div class="todo-form">
        <input class="todo-form__field" type="text">
        <button class="todo-form__btn">
          Add #<span class="todo-form__counter">1</span>
        </button>
      </div>
    `;
  }
}

class TodoListComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.list = this.mountPoint.querySelector(".todo-list");
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.doneTask();
  }

  addTask(task) {
    this.list.innerHTML += `
    <tr><td><input class ="checkbox" type="checkbox"></td>
    <td>${task}</td>
    <td><button value="&#215" style="width:5px;height:15px;"></button></td></tr>
        `;
  }

  doneTask() {
    let checkboxElements = document.getElementsByClassName("checkbox");

    for (let i = 0; i < checkboxElements.length; i++) {
      checkboxElements[i].addEventListener("change", function() {
        if (this.checked) {
          this.closest("tr").style.textDecoration = "line-through";
        }
      });
    }
  }
  getNumTasks() {
    return this.list.children.length;
  }

  render() {
    return `
      <br>
      <table class="todo-list" style="width:50px"></table>
    `;
  }
}

const root = document.querySelector("#root");

const cmp = new TodoAppComponent(root);

cmp.mount();
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
  
</body>
</html>

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-06 09:20:18

代码语言:javascript
复制
class TodoAppComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.todoFormMountPoint = this.mountPoint.querySelector(
      ".todo-app__form-point"
    );
    this.todoListMountPoint = this.mountPoint.querySelector(
      ".todo-app__list-point"
    );
  }

  mountChildren() {
    this.todoFormComponent = new TodoFormComponent(this.todoFormMountPoint, {
      onTodoAdd: this.handleTodoAdd.bind(this)
    });
    this.todoFormComponent.mount();
    this.todoListComponent = new TodoListComponent(this.todoListMountPoint);
    this.todoListComponent.mount();
  }

  handleTodoAdd(task) {
    this.todoListComponent.addTask(task);
    const numItems = this.todoListComponent.getNumTasks();
    this.todoFormComponent.setCounter(numItems + 1);
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.mountChildren();
  }

  render() {
    return `
      <div class="todo-app">
        <h2>Todo:</h2>
        <div class="todo-app__form-point"></div>
        <div class="todo-app__list-point"></div>
      </div>
    `;
  }
}

class TodoFormComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.field = this.mountPoint.querySelector(".todo-form__field");
    this.btn = this.mountPoint.querySelector(".todo-form__btn");
    this.counter = this.mountPoint.querySelector(".todo-form__counter");
  }

  addEventListeners() {
    this.btn.addEventListener("click", this.handeBtnClick.bind(this));
  }

  handeBtnClick() {
    this.props.onTodoAdd(this.field.value);
    this.field.value = "";
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.addEventListeners();
  }

  setCounter(val) {
    this.counter.innerHTML = val;
  }

  render() {
    return `
      <div class="todo-form">
        <input class="todo-form__field" type="text">
        <button class="todo-form__btn">
          Add #<span class="todo-form__counter">1</span>
        </button>
      </div>
    `;
  }
}

class TodoListComponent {
  constructor(mountPoint, props = {}) {
    this.mountPoint = mountPoint;
    this.props = props;
  }

  querySelectors() {
    this.list = this.mountPoint.querySelector(".todo-list");
  }

  mount() {
    this.mountPoint.innerHTML = this.render();
    this.querySelectors();
    this.doneTask();
  }

  addTask(task) {
    this.list.innerHTML += `
    <tr><td><input class ="checkbox" type="checkbox"></td>
    <td>${task}</td>
    <td><button value="&#215" style="width:5px;height:15px;"></button></td></tr>
        `;
        
     this.doneTask();
  }

  doneTask() {
    let checkboxElements = document.getElementsByClassName("checkbox");

    for (let i = 0; i < checkboxElements.length; i++) {
      checkboxElements[i].addEventListener("change", function() {
        if (this.checked) {
          this.closest("tr").style.textDecoration = "line-through";
        }
      });
    }
  }
  getNumTasks() {
    return this.list.children.length;
  }

  render() {
    return `
      <br>
      <table class="todo-list" style="width:50px"></table>
    `;
  }
}

const root = document.querySelector("#root");

const cmp = new TodoAppComponent(root);

cmp.mount();
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
  
</body>
</html>

因为您的函数doneTask()没有被调用,所以样式没有更新。尝尝这个。我刚打电话给doneTask() in addTask()

希望这能帮上忙!

票数 1
EN

Stack Overflow用户

发布于 2018-03-06 09:15:11

doneTask()方法在页面初始化过程中只运行一次,以添加侦听器。此时实际上没有元素,因此没有添加侦听器。

相反,尝试在添加到DOM的每个元素中添加一个侦听器(因此doneTask()是多余的):

代码语言:javascript
复制
  addTask(task) {
    this.list.innerHTML += `
    <tr><td><input class ="checkbox" type="checkbox"></td>
    <td>${task}</td>
    <td><button value="&#215" style="width:5px;height:15px;"></button></td></tr>
        `;

    // Actually add the listener
    this.list.lastChild.firstChild.firstChild.firstChild.addEventListener("change", function() {
      if (this.checked) {
        this.closest("tr").style.textDecoration = "line-through";
      }
    });

  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49126812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档