亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

更改數組元素值的樣式

更改數組元素值的樣式

慕標5832272 2023-09-28 10:20:23
我正在構建一個待辦事項列表,但無法弄清楚如何保留具有直通裝飾的數組值。調用 render 方法時,數組就會從頭開始構建。意味著如果我刪除一個 li,則所有其他已由復選框標記為直通的 li,都會丟失裝飾。我該怎么做才能保持線路暢通?到目前為止,我嘗試在 markTask 方法中將原始值替換為帶有直通線的值,但它不起作用?;旧?,我試圖完成的是通過插入帶有直通式的值,以便能夠檢查該值是否具有直通式樣式,并且在渲染之后能夠將選中的復選框保持為選中狀態。到目前為止我的代碼:class Todo {  constructor() {    this.input = document.getElementById("input");    this.ul = document.getElementById("ul");    this.form = document.getElementById("form");    this.tasks = [];    this.registerEvent();  }  registerEvent() {    this.form.addEventListener("submit", (event) => {      event.preventDefault();      this.createTask(this.input.value);      this.form.reset();    });  }  createTask(task) {    if (task.trim().length === 0) {      return;    }    this.tasks.push(task);    this.render();  }  deleteTask(task) {    const myTask = task.target;    const parent = myTask.parentNode;    const taskToRemove = parent.childNodes[1].textContent;    const index = this.tasks.indexOf(taskToRemove);    this.tasks.splice(index, 1);    this.render();  }  markTask(task) {    const myTask = task.target;    const parent = myTask.parentNode;        if (myTask.checked) {      parent.style.textDecoration = "line-through";    } else {      parent.style.textDecoration = "none";    }  }  render() {    this.ul.innerHTML = "";    this.tasks.forEach((task) => {      const li = document.createElement("li");      const cb = document.createElement("input");      cb.type = "checkbox";      cb.addEventListener("click", (e) => {        this.markTask(e);      });      li.appendChild(cb);      li.append(document.createTextNode(task));      const btn = document.createElement("button");      li.appendChild(btn);      btn.textContent = "Delete";      btn.classList.add("remove");      btn.addEventListener("click", (e) => {        this.deleteTask(e);      });      this.ul.appendChild(li);    });  }}new Todo();<form id="form">  <input id="input" />  <button id="add">Add</button></form><ul id="ul">  </ul>
查看完整描述

3 回答

?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

這是因為你沒有跟蹤哪些任務已完成,而只是在推動字符串。對于您的createTask方法,您需要推送一個具有完成屬性的對象來指示哪些任務已完成,如下所示


 createTask(task) {

 if (task.trim().length === 0) {

  return;

 }

 this.tasks.push({title: task, done: false});

 this.render();

 }

更新渲染以考慮已完成的任務


render() {

this.ul.innerHTML = "";

this.tasks.forEach((task) => {

  const li = document.createElement("li");

  const cb = document.createElement("input");

  cb.type = "checkbox";

  cb.addEventListener("click", (e) => {

    this.markTask(e);

  });

  li.appendChild(cb);


  li.append(document.createTextNode(task.title));


  const btn = document.createElement("button");

  li.appendChild(btn);

  btn.textContent = "Delete";

  btn.classList.add("remove");

  btn.addEventListener("click", (e) => {

    this.deleteTask(e);

  });

  this.ul.appendChild(li);


   if (task.done) {

    cb.checked = true;

    li.style.textDecoration = "line-through";

   } else {

    cb.checked = false;

    li.style.textDecoration = "none";

   }

 });

}

在你的構造函數中更新你的任務變量以查看其效果


constructor() {

this.input = document.getElementById("input");

this.ul = document.getElementById("ul");

this.form = document.getElementById("form");

this.tasks = [{title: 'mill', done: true}, {title: 'jus', done: false}];

this.registerEvent();

}

希望您能了解總體思路。我不會完成整個實現,markTask因為這應該足以讓您了解解決方案應該是什么。祝你好運。


查看完整回答
反對 回復 2023-09-28
?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

如果可以的話,我對你的代碼做了一些修改。


您需要的技術是事件委托:對子元素的任何單擊也是對其父元素的單擊。我們在父元素上放置事件偵聽器,然后查看它發生在哪個子元素上。就您而言,這只會為您的所有“刪除”按鈕創建一個事件偵聽器。


另一個想法是不要忽略 DOM,它還保留任務列表,您不需要將它們保存在內存中的表中,這是多余的。


這是代碼:css也是有幫助的


class Todo 

  {

  constructor()

    {

    this.form  = document.getElementById('todo-form')

    this.liste = document.getElementById('todo-list')

    this.form.onsubmit = e => this.addTask(e)

    this.liste.onclick = e => this.delTask(e)

    }

  addTask(e)

    {

    e.preventDefault()

    if (this.form.task.value.trim() === '') return


    let li = document.createElement('li')

      , cb = document.createElement('input')

      , sp = document.createElement('span')

      , bt = document.createElement('button')

      ;

    cb.type        = 'checkbox'

    sp.textContent = this.form.task.value

    bt.textContent = 'Delete'

    bt.className   = 'remove'


    li.appendChild(cb)

    li.appendChild(sp)

    li.appendChild(bt)

    this.liste.appendChild(li)

    this.form.reset()

    }

  delTask(e)

    {

    if (!e.target.matches('button.remove')) return // reject others clicks

    e.target.closest('li').remove()

    }

  }


new Todo();

#todo-list li > span {

  display          : inline-block;

  background-color : whitesmoke;

  width            : 20em;

  }

#todo-list li input[type=checkbox]:checked + span {

  text-decoration : line-through;

  }

#todo-list li button.remove {

  font-size: .6em;

  }

<form id="todo-form">

  <input name="task">

  <button type="submit">Add</button>

</form>

<ul id="todo-list"></ul>

正如您所看到的,這段代碼更短。您還可以使用 IIFE 而不是類,如下所示:

(function() // IIFE

  {

  let form  = document.getElementById('todo-form')

    , liste = document.getElementById('todo-list')

    ;

  form.onsubmit = e =>  // addTask

    {

    e.preventDefault()

    if (form.task.value.trim() === '') return


    let li = document.createElement('li')

      , cb = document.createElement('input')

      , sp = document.createElement('span')

      , bt = document.createElement('button')

      ;

    cb.type        = 'checkbox'

    sp.textContent = form.task.value

    bt.textContent = 'Delete'

    bt.className   = 'remove'


    li.appendChild(cb)

    li.appendChild(sp)

    li.appendChild(bt)

    liste.appendChild(li)

    form.reset()

    }

  liste.onclick = e =>  // delTask

    {

    if (!e.target.matches('button.remove')) return // reject others clicks

    e.target.closest('li').remove()

    }

  }

)()



btTaskList.onclick = e =>

  {

  let tasks = [...document.querySelectorAll('#todo-list li')].map(li=> 

    {

    let val = li.querySelector('span').textContent

      , chk = li.querySelector('input[type=checkbox]').checked

      ;

    return {val,chk}

    })

  console.clear()

  console.log( tasks )

  }

#todo-list li > span {

  display          : inline-block;

  background-color : whitesmoke;

  width            : 20em;

  }

#todo-list li input[type=checkbox]:checked + span {

  text-decoration : line-through;

  }

#todo-list li button.remove {

  font-size: .6em;

  }

<form id="todo-form">

  <input name="task">

  <button type="submit">Add</button>

</form>

<ul id="todo-list"></ul>


  

<button id="btTaskList">get task list</button>

我還添加了一個get task list按鈕...



查看完整回答
反對 回復 2023-09-28
?
慕森王

TA貢獻1777條經驗 獲得超3個贊

標記元素后,您僅更改元素的 Stayle 和屬性。但是刪除后,您會使用render整個列表重新創建,并且render您不會渲染checked參數。


你的渲染應該是:


  render() {

    this.ul.innerHTML = "";

    this.tasks.forEach((task) => {

      const li = document.createElement("li");

      const cb = document.createElement("input");

      cb.type = "checkbox";

      cb.addEventListener("click", (e) => {

        this.markTask(e);

      });

      li.appendChild(cb);


      // missed rendering checked

      if (task.checked) {

        li.style.textDecoration = "line-through";

        cb.checked = 'checked';

      }


      li.append(document.createTextNode(task));


      const btn = document.createElement("button");

      li.appendChild(btn);

      btn.textContent = "Delete";

      btn.classList.add("remove");

      btn.addEventListener("click", (e) => {

        this.deleteTask(e);

      });


      this.ul.appendChild(li);

    });

  }


查看完整回答
反對 回復 2023-09-28
  • 3 回答
  • 0 關注
  • 171 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號