我想要我点击更改的笔记标题,而不是列表的第一个笔记

I want the title of my note that I clicked on to change NOT the first note of the list

我正在尝试完成构建我的最小 note-taking 应用程序的编辑功能,但问题是在我编辑我的标题并单击 "save" 按钮后,列表的第一个注释发生了变化,但我希望我单击的注释的标题发生变化。

这是我的js代码:

// display list of notes on the side
    
      const noteContainer = document.querySelector(".column is-one-quarter")
      const noteList = document.querySelector(".menu-list")
    
      fetch('http://localhost:3000/api/v1/notes')
      .then(function(response) {
        return response.json();
      })
      .then(function(note) {
        note.forEach(function(note) {
          noteList.innerHTML += `<li><a id="note" data-id=${note.id} class="menu-item">${note.title}</a></li>`
        })
      })
    
      // display details of each note

      const noteDetail = document.querySelector(".note-detail")
    
      noteList.addEventListener('click', function(event) {
        if (event.target.className === "menu-item") {
          fetch(`http://localhost:3000/api/v1/notes/${event.target.dataset.id}`)
          .then(function(response) {
            return response.json()
          })
          .then(function(note) {
              noteDetail.innerHTML = `<h1 contenteditable="true" id="title" data-id=${note.id} class="subtitle is-2">${note.title}</h1><p contenteditable="true" id="body" data-id=${note.id} class="subtitle is-6">${note.body}</p><a id="save" class="button is-small">Save</a>`
    
    
         // i should be able to edit the title and body of a note when i click
         // on it and it should save when i click on the button.
    
         const noteId = event.target.dataset.id
         const editTitleInput = document.querySelector(`h1[data-id="${noteId}"]`)
         const editBodyInput = document.querySelector(`p[data-id="${noteId}"]`)
         const singleNote = document.querySelector("#note")
         const allNotes = document.querySelectorAll("li")
    
         noteDetail.addEventListener('click', function(event) {
           if (event.target.id === "save") {
             fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
               method: "PATCH",
               headers: {
                 'Content-Type': 'application/json',
                 'Accepts': 'application/json'
               },
               body: JSON.stringify({
                 title: editTitleInput.innerText,
                 body: editBodyInput.innerText
               })
             }).then(function(response) {
               return response.json()
             }).then(function(note) {
                    singleNote.innerText = editTitleInput.innerText
                })
              }
            })
          })
        }
      })

这是我的 HTML 代码:

<div class="columns">

  <div class="column is-one-quarter">
    <p class="menu-label" style="font-size:15px;">
      Notes <i id="create" class="fas fa-plus-circle has-text-grey-light hvr-grow" style="margin-left: 10px; width: 20px; height: 30px; font-size: 24px;"></i>
    </p>
      <ul class="menu-list">

      </ul>
 </div>

  <div class="column is-three-fifths">
    <div class="note-detail">

    </div>
  </div>

  <div class="column">

  </div>

</div>

我可以看到两个问题。

当您为此处的注释生成 HTML 时:

notes.forEach(function(note) {
   noteList.innerHTML += `<li><a id="note" data-id=${note.id} class="menu-item">${note.title}</a></li>`
})

您为每个音符赋予了相同的 id (id="note"),然后稍后,尝试将元素的 innerText 设置为 id="note" 但它总是会得到第一个 id 为笔记。您的代码如下:

const singleNote = document.querySelector('#note');
singleNote.innerText = editTitleInput.innerText;

因此,为了解决这个问题,我建议您在生成 HTML 时将 note-id 连接到元素的 id(以便它们每个都有一个唯一的 id),如下所示:

notes.forEach(function(note) {
     noteList.innerHTML += `<li><a id="note${note.id}" data-id=${note.id} class="menu-item">${note.title}</a></li>`
})

然后通过以下查询获取相应的元素。

let singleNote = document.querySelector(`#note${noteId}`);

我看到的问题的第二部分是您正在向 noteDetail 添加一个 eventListener, noteList的点击事件监听代码里面如下:

noteList.addEventListener('click', function(event) {
...
  noteDetail.addEventListener('click', function(event) {
    ....
  })
})

这意味着每次单击 noteList 时,您都会向 noteDetail 添加一个事件侦听器(您已经完成了)。 所以当点击 noteDetail 时,代码将执行多次而不是一次。

所以为了解决这个问题,我建议你把 noteDetail 点击事件监听器放在 noteList 点击事件监听器之外。

这是我的完整 JS 代码。我已经评论了我已经改变的部分。希望对您有所帮助:)

  const noteContainer = document.querySelector(".column is-one-quarter")
  const noteList = document.querySelector(".menu-list")

  fetch('http://localhost:3000/api/v1/notes')
  .then(function(response) {
    return response.json();
  })
  .then(function(notes) {
    //I changed the variable to "notes" instead of "note" as we're getting all notes here.
    notes.forEach(function(note) {
      //give a unique id to each note.
      noteList.innerHTML += `<li><a id="note${note.id}" data-id=${note.id} class="menu-item">${note.title}</a></li>`

    })
  })

  // display details of each note
  const noteDetail = document.querySelector(".note-detail");

  noteList.addEventListener('click', function(event) {
    if (event.target.className === "menu-item") {
      fetch(`http://localhost:3000/api/v1/notes/${event.target.dataset.id}`)
      .then(function(response) {
        return response.json()
      })
      .then(function(note) {
        noteDetail.innerHTML = `<h1 contenteditable="true" id="title" data-id=${note.id} class="subtitle is-2">${note.title}</h1><p contenteditable="true" id="body" data-id=${note.id} class="subtitle is-6">${note.body}</p><a id="save" class="button is-small">Save</a>`
      //I removed the noteDetail event listener from here
      })

    }
  })

  //Add the noteDetail event listener here (i.e outside of the noteList addEventListener code).
  noteDetail.addEventListener('click', function(event){ 

    if (event.target.id === "save") {
      //Now get the noteId of the current note being edited. 
      //We know this exists in both the data-id of the title and the body of noteDetail HTML 
      //so we retrieve it from one of these.
      //We could have also added a data-id to the save button of the noteDetail html. 
      //and then retrieved the noteId here with event.target.dataset.id
      let noteId = document.querySelector('#title').dataset.id;
      let editTitleInput = document.querySelector(`h1[data-id="${noteId}"]`);
      let editBodyInput = document.querySelector(`p[data-id="${noteId}"]`);
      //get the singleNote by it's unique id.
      let singleNote = document.querySelector(`#note${noteId}`);

      fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
        method: "PATCH",
        headers: {
          'Content-Type': 'application/json',
          'Accepts': 'application/json'
          },
          body: JSON.stringify({
            title: editTitleInput.innerText,
            body: editBodyInput.innerText
          })
      }).then(function(response) {
          return response.json()
      }).then(function(note) { 
          singleNote.innerText = editTitleInput.innerText;
      })
    }

  })