我正在尝试完成我的最小笔记应用程序的编辑功能的构建,但是问题是我编辑标题并单击“保存”按钮后,列表中第一个注释的标题发生了变化但我想要单击的便笺标题进行更改。
这是我的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>
答案 0 :(得分:0)
我可以看到两个问题。
在此处为注释生成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"
),然后再尝试使用id="note"
设置element的innerText,但是它总是会得到第一个音符为note的音符。您的代码如下:
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的click事件侦听器代码中,如下所示:
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;
})
}
})